team_api 0.0.5 → 0.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CONTRIBUTING.md +33 -3
- data/lib/team_api/api.rb +5 -160
- data/lib/team_api/api_impl.rb +70 -0
- data/lib/team_api/api_impl_error_helpers.rb +34 -0
- data/lib/team_api/api_impl_snippet_helpers.rb +59 -0
- data/lib/team_api/endpoint.rb +22 -0
- data/lib/team_api/index_page.rb +23 -0
- data/lib/team_api/joiner.rb +74 -51
- data/lib/team_api/version.rb +1 -1
- metadata +7 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 95ed3978aeeee3c3d06b646286221dc312863242
|
4
|
+
data.tar.gz: f3c70c2f94311e235e4376fabcf50bf888c43e8a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 01bcaf3b059028430dad48e6b8703da39d3694d8c0c6856addb6931671fbd14c75e2e3088ded448c3f14c537fb47107de47d05ee3d950088397b9f031e37cd9c
|
7
|
+
data.tar.gz: 5240cfd63440904c7a79817c5b385a2414730843f7254c6626a5ba0aed40cb309080ac23bb3092dcd0c6c5acdf4d3dc939c4d8311927c619f6f7521186e9dd29
|
data/CONTRIBUTING.md
CHANGED
@@ -1,10 +1,40 @@
|
|
1
1
|
## Welcome!
|
2
2
|
|
3
|
-
|
3
|
+
### Code of conduct
|
4
4
|
|
5
|
-
|
5
|
+
We aspire to create a welcoming environment for collaboration on this project.
|
6
|
+
To that end, we follow the [18F Code of
|
7
|
+
Conduct](https://github.com/18F/code-of-conduct/blob/master/code-of-conduct.md)
|
8
|
+
and ask that all contributors do the same.
|
6
9
|
|
7
|
-
|
10
|
+
### Getting started
|
11
|
+
|
12
|
+
We're so glad you're thinking about contributing to an 18F open source project!
|
13
|
+
If you're unsure or afraid of anything, just ask or submit the issue or pull
|
14
|
+
request anyways. The worst that can happen is that you'll be politely asked to
|
15
|
+
change something. We appreciate any sort of contribution, and don't want a wall
|
16
|
+
of rules to get in the way of that.
|
17
|
+
|
18
|
+
Before contributing, we encourage you to read our CONTRIBUTING policy (you are
|
19
|
+
here), our [LICENSE](LICENSE.md), and our [README](REAMDE.md). If you have any
|
20
|
+
questions, or want to read more about our underlying policies, you can consult
|
21
|
+
the [18F Open Source Policy GitHub
|
22
|
+
repository](https://github.com/18f/open-source-policy), or just shoot us an
|
23
|
+
email/official government letterhead note to [18f@gsa.gov](mailto:18f@gsa.gov).
|
24
|
+
|
25
|
+
### Submitting a pull request
|
26
|
+
|
27
|
+
1. Fork the repository or create a branch if you are part of the 18F Team on
|
28
|
+
GitHub
|
29
|
+
2. Implement your feature or bug fix (and add test coverage if applicable)
|
30
|
+
3. Run the tests (`$ ./go test`) to make sure nothing is broken
|
31
|
+
4. Add, commit, and push your changes
|
32
|
+
5. [Submit a pull
|
33
|
+
request](https://help.github.com/articles/using-pull-requests/)
|
34
|
+
6. Another contributor will merge your pull request into master when it is deemed
|
35
|
+
ready
|
36
|
+
|
37
|
+
### Public domain
|
8
38
|
|
9
39
|
This project is in the public domain within the United States, and
|
10
40
|
copyright and related rights in the work worldwide are waived through
|
data/lib/team_api/api.rb
CHANGED
@@ -1,53 +1,12 @@
|
|
1
|
-
# @author Mike Bland (michael.bland@gsa.gov)
|
2
|
-
|
3
1
|
require_relative 'canonicalizer'
|
2
|
+
require_relative 'api_impl'
|
4
3
|
require_relative 'config'
|
4
|
+
require_relative 'index_page'
|
5
5
|
require 'jekyll'
|
6
6
|
require 'json'
|
7
7
|
require 'safe_yaml'
|
8
8
|
|
9
9
|
module TeamApi
|
10
|
-
class IndexPage < ::Jekyll::Page
|
11
|
-
private_class_method :new
|
12
|
-
|
13
|
-
def initialize(site)
|
14
|
-
@site = site
|
15
|
-
@base = site.source
|
16
|
-
@dir = Api::BASEURL
|
17
|
-
@name = 'index.html'
|
18
|
-
@data = {}
|
19
|
-
end
|
20
|
-
|
21
|
-
def self.create(site, index_endpoints)
|
22
|
-
index_page = new site
|
23
|
-
index_page.process index_page.name
|
24
|
-
layout = site.config['api_index_layout']
|
25
|
-
fail '`api_index_layout:` not defined in _config.yml' unless layout
|
26
|
-
index_page.read_yaml File.join(site.source, '_layouts'), layout
|
27
|
-
index_page.data['endpoints'] = index_endpoints
|
28
|
-
site.pages << index_page
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
class Endpoint < ::Jekyll::Page
|
33
|
-
private_class_method :new
|
34
|
-
|
35
|
-
def initialize(site, endpoint_path)
|
36
|
-
@site = site
|
37
|
-
@base = site.source
|
38
|
-
@dir = endpoint_path
|
39
|
-
@name = 'api.json'
|
40
|
-
@data = {}
|
41
|
-
end
|
42
|
-
|
43
|
-
def self.create(site, endpoint_path, data)
|
44
|
-
endpoint = new site, endpoint_path
|
45
|
-
endpoint.process endpoint.name
|
46
|
-
endpoint.content = data.to_json
|
47
|
-
site.pages << endpoint
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
10
|
# Functions for generating JSON objects as part of an API
|
52
11
|
class Api
|
53
12
|
BASEURL = 'api'
|
@@ -59,6 +18,7 @@ module TeamApi
|
|
59
18
|
generate_collection_endpoints impl
|
60
19
|
generate_tag_category_endpoints impl
|
61
20
|
impl.generate_snippets_endpoints
|
21
|
+
impl.generate_error_endpoint
|
62
22
|
IndexPage.create site, impl.index_endpoints
|
63
23
|
end
|
64
24
|
|
@@ -87,6 +47,7 @@ module TeamApi
|
|
87
47
|
impl.generate_item_endpoints endpoint_info['collection']
|
88
48
|
end
|
89
49
|
end
|
50
|
+
|
90
51
|
private_class_method :generate_collection_endpoints
|
91
52
|
|
92
53
|
def self.generate_tag_category_endpoints(impl)
|
@@ -95,123 +56,7 @@ module TeamApi
|
|
95
56
|
impl.generate_item_endpoints Canonicalizer.canonicalize(tag_category)
|
96
57
|
end
|
97
58
|
end
|
98
|
-
private_class_method :generate_tag_category_endpoints
|
99
|
-
end
|
100
|
-
|
101
|
-
module ApiImplSnippetHelpers
|
102
|
-
private
|
103
|
-
|
104
|
-
def snippet_dates
|
105
|
-
@snippet_dates ||= (data['snippets'] || {}).keys.sort.reverse
|
106
|
-
end
|
107
|
-
|
108
|
-
def snippets
|
109
|
-
@snippets ||= snippet_dates.map { |t| [t, data['snippets'][t]] }.to_h
|
110
|
-
end
|
111
|
-
|
112
|
-
def snippets_by_user
|
113
|
-
@snippets_by_user ||= snippets
|
114
|
-
.flat_map { |date, batch| batch.map { |snippet| [date, snippet] } }
|
115
|
-
.group_by { |_date, snippet| snippet['name'] }
|
116
|
-
.map { |name, mapping| [name, mapping.to_h] }
|
117
|
-
.to_h
|
118
|
-
end
|
119
|
-
|
120
|
-
def snippets_summary
|
121
|
-
@snippet_summary ||= {
|
122
|
-
'latest' => snippet_dates.first,
|
123
|
-
'all' => snippet_dates,
|
124
|
-
'users' => Canonicalizer.team_xrefs(
|
125
|
-
data['team'], snippets_by_user.keys),
|
126
|
-
}
|
127
|
-
end
|
128
|
-
|
129
|
-
def generate_latest_snippet_endpoint
|
130
|
-
return if snippets.empty?
|
131
|
-
latest = snippets.first
|
132
|
-
endpoint = 'snippets/latest'
|
133
|
-
Endpoint.create(site, "#{baseurl}/#{endpoint}",
|
134
|
-
{ 'datestamp' => latest[0] }.merge(envelop(endpoint, latest[1])))
|
135
|
-
end
|
136
|
-
|
137
|
-
def generate_snippets_by_date_endpoints
|
138
|
-
snippets.each do |timestamp, batch|
|
139
|
-
endpoint = "snippets/#{timestamp}"
|
140
|
-
Endpoint.create site, "#{baseurl}/#{endpoint}", envelop(endpoint, batch)
|
141
|
-
end
|
142
|
-
end
|
143
|
-
|
144
|
-
def generate_snippets_by_user_endpoints
|
145
|
-
snippets_by_user.each do |name, batch|
|
146
|
-
Endpoint.create site, "#{baseurl}/snippets/#{name}", batch
|
147
|
-
Endpoint.create(
|
148
|
-
site, "#{baseurl}/snippets/#{name}/latest", [batch.first].to_h)
|
149
|
-
end
|
150
|
-
end
|
151
|
-
|
152
|
-
def generate_snippets_index_summary_endpoint
|
153
|
-
generate_index_endpoint(
|
154
|
-
'snippets', 'Snippets', 'Summary of all available snippets',
|
155
|
-
snippets_summary) unless snippets.empty?
|
156
|
-
end
|
157
|
-
end
|
158
|
-
|
159
|
-
class ApiImpl
|
160
|
-
attr_accessor :site, :data, :index_endpoints, :baseurl
|
161
|
-
include ApiImplSnippetHelpers
|
162
|
-
|
163
|
-
def initialize(site, baseurl)
|
164
|
-
@site = site
|
165
|
-
@data = site.data
|
166
|
-
@index_endpoints = []
|
167
|
-
@baseurl = baseurl
|
168
|
-
end
|
169
|
-
|
170
|
-
def self_link(endpoint)
|
171
|
-
File.join site.config['url'], baseurl, endpoint
|
172
|
-
end
|
173
59
|
|
174
|
-
|
175
|
-
return if items.nil? || items.empty?
|
176
|
-
{ 'self' => self_link(endpoint), 'results' => items }
|
177
|
-
end
|
178
|
-
|
179
|
-
def generate_index_endpoint(endpoint, title, description, items)
|
180
|
-
return if items.nil? || items.empty?
|
181
|
-
Endpoint.create site, "#{baseurl}/#{endpoint}", items
|
182
|
-
index_endpoints << {
|
183
|
-
'endpoint' => endpoint, 'title' => title, 'description' => description
|
184
|
-
}
|
185
|
-
end
|
186
|
-
|
187
|
-
def generate_tag_category_endpoint(category)
|
188
|
-
canonicalized = Canonicalizer.canonicalize(category)
|
189
|
-
generate_index_endpoint(canonicalized, category,
|
190
|
-
"Index of team members by #{category.downcase}",
|
191
|
-
envelop(canonicalized, (data[canonicalized] || {}).values))
|
192
|
-
end
|
193
|
-
|
194
|
-
def generate_index_endpoint_for_collection(endpoint_info)
|
195
|
-
collection = endpoint_info['collection']
|
196
|
-
generate_index_endpoint(
|
197
|
-
endpoint_info['collection'], endpoint_info['title'],
|
198
|
-
endpoint_info['description'],
|
199
|
-
envelop(collection, (data[collection] || {}).values))
|
200
|
-
end
|
201
|
-
|
202
|
-
def generate_item_endpoints(collection_name)
|
203
|
-
(data[collection_name] || {}).each do |identifier, value|
|
204
|
-
identifier = Canonicalizer.canonicalize(identifier)
|
205
|
-
url = "#{baseurl}/#{collection_name}/#{identifier}"
|
206
|
-
Endpoint.create site, url, value
|
207
|
-
end
|
208
|
-
end
|
209
|
-
|
210
|
-
def generate_snippets_endpoints
|
211
|
-
generate_latest_snippet_endpoint
|
212
|
-
generate_snippets_by_date_endpoints
|
213
|
-
generate_snippets_by_user_endpoints
|
214
|
-
generate_snippets_index_summary_endpoint
|
215
|
-
end
|
60
|
+
private_class_method :generate_tag_category_endpoints
|
216
61
|
end
|
217
62
|
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require_relative 'endpoint'
|
2
|
+
require_relative 'api_impl_snippet_helpers'
|
3
|
+
require_relative 'api_impl_error_helpers'
|
4
|
+
|
5
|
+
module TeamApi
|
6
|
+
class ApiImpl
|
7
|
+
attr_accessor :site, :data, :index_endpoints, :baseurl
|
8
|
+
include ApiImplSnippetHelpers
|
9
|
+
include ApiImplErrorHelpers
|
10
|
+
|
11
|
+
def initialize(site, baseurl)
|
12
|
+
@site = site
|
13
|
+
@data = site.data
|
14
|
+
@index_endpoints = []
|
15
|
+
@baseurl = baseurl
|
16
|
+
end
|
17
|
+
|
18
|
+
def self_link(endpoint)
|
19
|
+
File.join site.config['url'], baseurl, endpoint
|
20
|
+
end
|
21
|
+
|
22
|
+
def envelop(endpoint, items)
|
23
|
+
return if items.nil? || items.empty?
|
24
|
+
{ 'self' => self_link(endpoint), 'results' => items }
|
25
|
+
end
|
26
|
+
|
27
|
+
def generate_index_endpoint(endpoint, title, description, items)
|
28
|
+
return if items.nil? || items.empty?
|
29
|
+
Endpoint.create site, "#{baseurl}/#{endpoint}", items
|
30
|
+
index_endpoints << {
|
31
|
+
'endpoint' => endpoint, 'title' => title, 'description' => description
|
32
|
+
}
|
33
|
+
end
|
34
|
+
|
35
|
+
def generate_tag_category_endpoint(category)
|
36
|
+
canonicalized = Canonicalizer.canonicalize(category)
|
37
|
+
generate_index_endpoint(canonicalized, category,
|
38
|
+
"Index of team members by #{category.downcase}",
|
39
|
+
envelop(canonicalized, (data[canonicalized] || {}).values))
|
40
|
+
end
|
41
|
+
|
42
|
+
def generate_index_endpoint_for_collection(endpoint_info)
|
43
|
+
collection = endpoint_info['collection']
|
44
|
+
generate_index_endpoint(
|
45
|
+
endpoint_info['collection'], endpoint_info['title'],
|
46
|
+
endpoint_info['description'],
|
47
|
+
envelop(collection, (data[collection] || {}).values))
|
48
|
+
end
|
49
|
+
|
50
|
+
def generate_item_endpoints(collection_name)
|
51
|
+
(data[collection_name] || {}).each do |identifier, value|
|
52
|
+
identifier = Canonicalizer.canonicalize(identifier)
|
53
|
+
url = "#{baseurl}/#{collection_name}/#{identifier}"
|
54
|
+
Endpoint.create site, url, value
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def generate_snippets_endpoints
|
59
|
+
generate_latest_snippet_endpoint
|
60
|
+
generate_snippets_by_date_endpoints
|
61
|
+
generate_snippets_by_user_endpoints
|
62
|
+
generate_snippets_index_summary_endpoint
|
63
|
+
end
|
64
|
+
|
65
|
+
def generate_error_endpoint
|
66
|
+
generate_errors_endpoint
|
67
|
+
generate_errors_index_summary_endpoint
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module TeamApi
|
2
|
+
module ApiImplErrorHelpers
|
3
|
+
private
|
4
|
+
|
5
|
+
def errors
|
6
|
+
@errors ||= (data['errors'] || {})
|
7
|
+
end
|
8
|
+
|
9
|
+
def missing
|
10
|
+
@missing ||= (data['missing'] || {})
|
11
|
+
end
|
12
|
+
|
13
|
+
def error_summary
|
14
|
+
@error_summary ||= {
|
15
|
+
'errors' => errors,
|
16
|
+
'missing' => missing,
|
17
|
+
}
|
18
|
+
end
|
19
|
+
|
20
|
+
def generate_errors_endpoint
|
21
|
+
return if errors.empty? && missing.empty?
|
22
|
+
endpoint = 'errors'
|
23
|
+
Endpoint.create(site, "#{baseurl}/#{endpoint}", error_summary)
|
24
|
+
end
|
25
|
+
|
26
|
+
def generate_errors_index_summary_endpoint
|
27
|
+
return if errors.empty? && missing.empty?
|
28
|
+
generate_index_endpoint(
|
29
|
+
'errors', 'Errors', '.about.yml parsing errors and ' \
|
30
|
+
'repos missing a .about.yml file.',
|
31
|
+
error_summary)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module TeamApi
|
2
|
+
module ApiImplSnippetHelpers
|
3
|
+
private
|
4
|
+
|
5
|
+
def snippet_dates
|
6
|
+
@snippet_dates ||= (data['snippets'] || {}).keys.sort.reverse
|
7
|
+
end
|
8
|
+
|
9
|
+
def snippets
|
10
|
+
@snippets ||= snippet_dates.map { |t| [t, data['snippets'][t]] }.to_h
|
11
|
+
end
|
12
|
+
|
13
|
+
def snippets_by_user
|
14
|
+
@snippets_by_user ||= snippets
|
15
|
+
.flat_map { |date, batch| batch.map { |snippet| [date, snippet] } }
|
16
|
+
.group_by { |_date, snippet| snippet['name'] }
|
17
|
+
.map { |name, mapping| [name, mapping.to_h] }
|
18
|
+
.to_h
|
19
|
+
end
|
20
|
+
|
21
|
+
def snippets_summary
|
22
|
+
@snippet_summary ||= {
|
23
|
+
'latest' => snippet_dates.first,
|
24
|
+
'all' => snippet_dates,
|
25
|
+
'users' => Canonicalizer.team_xrefs(
|
26
|
+
data['team'], snippets_by_user.keys),
|
27
|
+
}
|
28
|
+
end
|
29
|
+
|
30
|
+
def generate_latest_snippet_endpoint
|
31
|
+
return if snippets.empty?
|
32
|
+
latest = snippets.first
|
33
|
+
endpoint = 'snippets/latest'
|
34
|
+
Endpoint.create(site, "#{baseurl}/#{endpoint}",
|
35
|
+
{ 'datestamp' => latest[0] }.merge(envelop(endpoint, latest[1])))
|
36
|
+
end
|
37
|
+
|
38
|
+
def generate_snippets_by_date_endpoints
|
39
|
+
snippets.each do |timestamp, batch|
|
40
|
+
endpoint = "snippets/#{timestamp}"
|
41
|
+
Endpoint.create site, "#{baseurl}/#{endpoint}", envelop(endpoint, batch)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def generate_snippets_by_user_endpoints
|
46
|
+
snippets_by_user.each do |name, batch|
|
47
|
+
Endpoint.create site, "#{baseurl}/snippets/#{name}", batch
|
48
|
+
Endpoint.create(
|
49
|
+
site, "#{baseurl}/snippets/#{name}/latest", [batch.first].to_h)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def generate_snippets_index_summary_endpoint
|
54
|
+
generate_index_endpoint(
|
55
|
+
'snippets', 'Snippets', 'Summary of all available snippets',
|
56
|
+
snippets_summary) unless snippets.empty?
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'jekyll'
|
2
|
+
|
3
|
+
module TeamApi
|
4
|
+
class Endpoint < ::Jekyll::Page
|
5
|
+
private_class_method :new
|
6
|
+
|
7
|
+
def initialize(site, endpoint_path)
|
8
|
+
@site = site
|
9
|
+
@base = site.source
|
10
|
+
@dir = endpoint_path
|
11
|
+
@name = 'api.json'
|
12
|
+
@data = {}
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.create(site, endpoint_path, data)
|
16
|
+
endpoint = new site, endpoint_path
|
17
|
+
endpoint.process endpoint.name
|
18
|
+
endpoint.content = data.to_json
|
19
|
+
site.pages << endpoint
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module TeamApi
|
2
|
+
class IndexPage < ::Jekyll::Page
|
3
|
+
private_class_method :new
|
4
|
+
|
5
|
+
def initialize(site)
|
6
|
+
@site = site
|
7
|
+
@base = site.source
|
8
|
+
@dir = Api::BASEURL
|
9
|
+
@name = 'index.html'
|
10
|
+
@data = {}
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.create(site, index_endpoints)
|
14
|
+
index_page = new site
|
15
|
+
index_page.process index_page.name
|
16
|
+
layout = site.config['api_index_layout']
|
17
|
+
fail '`api_index_layout:` not defined in _config.yml' unless layout
|
18
|
+
index_page.read_yaml File.join(site.source, '_layouts'), layout
|
19
|
+
index_page.data['endpoints'] = index_endpoints
|
20
|
+
site.pages << index_page
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/lib/team_api/joiner.rb
CHANGED
@@ -4,9 +4,6 @@ require_relative 'api'
|
|
4
4
|
require 'hash-joiner'
|
5
5
|
|
6
6
|
module TeamApi
|
7
|
-
class UnknownTeamMemberReferenceError < StandardError
|
8
|
-
end
|
9
|
-
|
10
7
|
class UnknownSnippetUsernameError < StandardError
|
11
8
|
end
|
12
9
|
|
@@ -20,17 +17,68 @@ module TeamApi
|
|
20
17
|
def self.join_data(site)
|
21
18
|
impl = JoinerImpl.new site
|
22
19
|
site.data.merge! impl.collection_data
|
23
|
-
impl.create_indexes
|
24
20
|
impl.promote_or_remove_data
|
21
|
+
impl.init_team_data site.data['team']
|
25
22
|
impl.join_project_data
|
26
23
|
Api.add_self_links site
|
27
24
|
impl.join_snippet_data
|
28
25
|
end
|
29
26
|
end
|
30
27
|
|
28
|
+
class TeamIndexer
|
29
|
+
def initialize(data)
|
30
|
+
@team = data
|
31
|
+
end
|
32
|
+
|
33
|
+
def team
|
34
|
+
@team || {}
|
35
|
+
end
|
36
|
+
|
37
|
+
def create_indexes
|
38
|
+
team_by_email
|
39
|
+
team_by_github
|
40
|
+
end
|
41
|
+
|
42
|
+
# Returns an index of team member usernames keyed by email address.
|
43
|
+
def team_by_email
|
44
|
+
@team_by_email ||= team_index_by_field 'email'
|
45
|
+
end
|
46
|
+
|
47
|
+
# Returns an index of team member usernames keyed by email address.
|
48
|
+
def team_by_github
|
49
|
+
@team_by_github ||= team_index_by_field 'github'
|
50
|
+
end
|
51
|
+
|
52
|
+
# Returns an index of team member usernames keyed by a particular field.
|
53
|
+
def team_index_by_field(field)
|
54
|
+
team_members.map do |member|
|
55
|
+
value = member[field]
|
56
|
+
value = member['private'][field] if value.nil? && member['private']
|
57
|
+
[value, member['name']] unless value.nil?
|
58
|
+
end.compact.to_h
|
59
|
+
end
|
60
|
+
|
61
|
+
# Returns the list of team members, with site.data['team']['private']
|
62
|
+
# members included.
|
63
|
+
def team_members
|
64
|
+
@team_members ||= team.map { |key, value| value unless key == 'private' }
|
65
|
+
.compact
|
66
|
+
.concat((team['private'] || {}).values)
|
67
|
+
end
|
68
|
+
|
69
|
+
def team_member_key(ref)
|
70
|
+
(ref.is_a? String) ? ref : (ref['id'] || ref['email'] || ref['github'])
|
71
|
+
end
|
72
|
+
|
73
|
+
def team_member_from_reference(reference)
|
74
|
+
key = team_member_key reference
|
75
|
+
team[key] || team[team_by_email[key] || team_by_github[key]]
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
31
79
|
# Implements Joiner operations.
|
32
80
|
class JoinerImpl
|
33
|
-
attr_reader :site, :data, :public_mode
|
81
|
+
attr_reader :site, :data, :public_mode, :team_indexer
|
34
82
|
|
35
83
|
# +site+:: Jekyll site data object
|
36
84
|
def initialize(site)
|
@@ -39,6 +87,11 @@ module TeamApi
|
|
39
87
|
@public_mode = site.config['public']
|
40
88
|
end
|
41
89
|
|
90
|
+
def init_team_data(data)
|
91
|
+
@team_indexer = TeamIndexer.new data
|
92
|
+
team_indexer.create_indexes
|
93
|
+
end
|
94
|
+
|
42
95
|
def collection_data
|
43
96
|
@collection_data ||= site.collections.map do |data_class, collection|
|
44
97
|
groups = groups collection
|
@@ -75,43 +128,17 @@ module TeamApi
|
|
75
128
|
# convention takes hold, hopefully.
|
76
129
|
projects = (data['projects'] ||= {})
|
77
130
|
projects.delete_if { |_, p| p['status'] == 'Hold' } if @public_mode
|
78
|
-
projects.values.each
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
end
|
84
|
-
|
85
|
-
def create_indexes
|
86
|
-
team_by_email
|
87
|
-
team_by_github
|
88
|
-
end
|
89
|
-
|
90
|
-
# Returns an index of team member usernames keyed by email address.
|
91
|
-
def team_by_email
|
92
|
-
@team_by_email ||= team_index_by_field 'email'
|
93
|
-
end
|
94
|
-
|
95
|
-
# Returns an index of team member usernames keyed by email address.
|
96
|
-
def team_by_github
|
97
|
-
@team_by_github ||= team_index_by_field 'github'
|
131
|
+
projects.values.each do |p|
|
132
|
+
errors = p['errors'] || []
|
133
|
+
join_team_list p['team'], errors
|
134
|
+
store_project_errors p, errors unless errors.empty?
|
135
|
+
end
|
98
136
|
end
|
99
137
|
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
value = member['private'][field] if value.nil? && member['private']
|
105
|
-
[value, member['name']] unless value.nil?
|
106
|
-
end.compact.to_h
|
107
|
-
end
|
108
|
-
|
109
|
-
# Returns the list of team members, with site.data['team']['private']
|
110
|
-
# members included.
|
111
|
-
def team_members
|
112
|
-
@team_members ||= team.map { |key, value| value unless key == 'private' }
|
113
|
-
.compact
|
114
|
-
.concat((team['private'] || {}).values)
|
138
|
+
def store_project_errors(project, errors)
|
139
|
+
project['errors'] = errors
|
140
|
+
name = project['github'][0] || project['name']
|
141
|
+
data['errors'][name] |= errors unless data['errors'].nil?
|
115
142
|
end
|
116
143
|
|
117
144
|
# Replaces each member of team_list with a key into the team hash.
|
@@ -121,21 +148,17 @@ module TeamApi
|
|
121
148
|
# - Strings that are GitHub usernames
|
122
149
|
# - Hashes that contain an 'email' property
|
123
150
|
# - Hashes that contain a 'github' property
|
124
|
-
def join_team_list(team_list)
|
151
|
+
def join_team_list(team_list, errors)
|
125
152
|
(team_list || []).map! do |reference|
|
126
|
-
member = team_member_from_reference reference
|
153
|
+
member = team_indexer.team_member_from_reference reference
|
127
154
|
if member.nil?
|
128
|
-
|
155
|
+
errors << 'Unknown Team Member: ' +
|
156
|
+
team_indexer.team_member_key(reference)
|
157
|
+
nil
|
129
158
|
else
|
130
159
|
member['name']
|
131
160
|
end
|
132
|
-
end.compact
|
133
|
-
end
|
134
|
-
|
135
|
-
def team_member_from_reference(reference)
|
136
|
-
key = (reference.instance_of? String) ? reference : (
|
137
|
-
reference['id'] || reference['email'] || reference['github'])
|
138
|
-
team[key] || team[team_by_email[key] || team_by_github[key]]
|
161
|
+
end.compact! || []
|
139
162
|
end
|
140
163
|
|
141
164
|
SNIPPET_JOIN_FIELDS = %w(name full_name first_name last_name self)
|
@@ -155,7 +178,7 @@ module TeamApi
|
|
155
178
|
|
156
179
|
def join_snippet(snippet)
|
157
180
|
username = snippet['username']
|
158
|
-
member =
|
181
|
+
member = team_indexer.team_member_from_reference username
|
159
182
|
|
160
183
|
if member.nil?
|
161
184
|
fail UnknownSnippetUsernameError, username unless public_mode
|
data/lib/team_api/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: team_api
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mike Bland
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-10-
|
11
|
+
date: 2015-10-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -206,14 +206,19 @@ files:
|
|
206
206
|
- lib/team_api.rb
|
207
207
|
- lib/team_api/README.md
|
208
208
|
- lib/team_api/api.rb
|
209
|
+
- lib/team_api/api_impl.rb
|
210
|
+
- lib/team_api/api_impl_error_helpers.rb
|
211
|
+
- lib/team_api/api_impl_snippet_helpers.rb
|
209
212
|
- lib/team_api/canonicalizer.rb
|
210
213
|
- lib/team_api/collection_canonicalizer.rb
|
211
214
|
- lib/team_api/config.rb
|
212
215
|
- lib/team_api/cross_reference_data.rb
|
213
216
|
- lib/team_api/cross_referencer.rb
|
217
|
+
- lib/team_api/endpoint.rb
|
214
218
|
- lib/team_api/endpoints.yml
|
215
219
|
- lib/team_api/front_matter.rb
|
216
220
|
- lib/team_api/generator.rb
|
221
|
+
- lib/team_api/index_page.rb
|
217
222
|
- lib/team_api/joiner.rb
|
218
223
|
- lib/team_api/name_canonicalizer.rb
|
219
224
|
- lib/team_api/snippets.rb
|