maintainers 0.2.0 → 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG +7 -1
- data/MAINTAINERS +1 -1
- data/MAINTAINERS-example +1 -1
- data/MAINTAINERS-unmaintained_example +1 -1
- data/README.md +7 -13
- data/lib/maintainers/cli.rb +26 -2
- data/lib/maintainers/runner.rb +84 -19
- data/lib/maintainers/version.rb +1 -1
- data/schema/{MAINTAINERS.json → MAINTAINERS-schema.json} +0 -0
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b180ab1f1bf4d3b38fbe24e230f23c5463880a73
|
4
|
+
data.tar.gz: 30df1da1ffe8477687ad3764f668885361126540
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 666a0d00c79c5e08358244b53f855b0a14c3dfcba0c8d21d3e5345a7167f026426682583fb4949a460e0a26a4345e2d340f59a891dbae70737b4002117fc57d3
|
7
|
+
data.tar.gz: 8756b96d1523bc1c8d4b61979d998f9c981fe42a8006737892d1beba393f1060993aed83d85478a61e06c982ade7e4a5abda349a92aa47ff8d42509a34227c15
|
data/CHANGELOG
CHANGED
@@ -6,6 +6,11 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
|
6
6
|
|
7
7
|
## [Unreleased]
|
8
8
|
|
9
|
+
## [0.2.1] - 2016-09-08
|
10
|
+
### Fixed
|
11
|
+
- Make 'report' subcommand more useful
|
12
|
+
- Make 'file_format' value more helpful and more future-proof
|
13
|
+
|
9
14
|
## [0.2.0] - 2016-09-05
|
10
15
|
### Added
|
11
16
|
- Add a 'validate' subcommand
|
@@ -27,7 +32,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
|
27
32
|
### Added
|
28
33
|
- Initial support for a json format for MAINTAINERS
|
29
34
|
|
30
|
-
[Unreleased]: https://github.com/puppetlabs/maintainers/compare/0.2.
|
35
|
+
[Unreleased]: https://github.com/puppetlabs/maintainers/compare/0.2.1...HEAD
|
36
|
+
[0.2.1]: https://github.com/puppetlabs/maintainers/compare/0.2.0...0.2.1
|
31
37
|
[0.2.0]: https://github.com/puppetlabs/maintainers/compare/0.1.2...0.2.0
|
32
38
|
[0.1.2]: https://github.com/puppetlabs/maintainers/compare/0.1.1...0.1.2
|
33
39
|
[0.1.1]: https://github.com/puppetlabs/maintainers/compare/0.1.0...0.1.1
|
data/MAINTAINERS
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"version": 1,
|
3
|
-
"file_format": "This MAINTAINERS file format is described at
|
3
|
+
"file_format": "This MAINTAINERS file format is described at http://pup.pt/maintainers",
|
4
4
|
"issues": "https://github.com/puppetlabs/maintainers/issues",
|
5
5
|
"people": [
|
6
6
|
{
|
data/MAINTAINERS-example
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"version": 1,
|
3
|
-
"file_format": "This MAINTAINERS file format is described at
|
3
|
+
"file_format": "This MAINTAINERS file format is described at http://pup.pt/maintainers",
|
4
4
|
"issues": "https://github.com/graceland/issues",
|
5
5
|
"people": [
|
6
6
|
{
|
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"version": 1,
|
3
|
-
"file_format": "This MAINTAINERS file format is described at
|
3
|
+
"file_format": "This MAINTAINERS file format is described at http://pup.pt/maintainers",
|
4
4
|
"maintained": false,
|
5
5
|
"issues": "This repo is not maintained",
|
6
6
|
"people": []
|
data/README.md
CHANGED
@@ -24,11 +24,11 @@ At this point you might drop some comments in the resultant MAINTAINERS file.
|
|
24
24
|
|
25
25
|
### Add or remove a maintainer from a MAINTAINERS file
|
26
26
|
|
27
|
-
Add users, optionally
|
27
|
+
Add users identified by github id, optionally specifying name, email address, and a comment.
|
28
28
|
|
29
29
|
```ruby
|
30
30
|
maintainers add --github gracehopper --email grace@usnavy.gov --name "Grace Hopper"
|
31
|
-
maintainers add --github gracehopper --email grace@usnavy.gov --name "Grace Hopper" --
|
31
|
+
maintainers add --github gracehopper --email grace@usnavy.gov --name "Grace Hopper" --comment "Maintains ENIAC"
|
32
32
|
```
|
33
33
|
|
34
34
|
Remove user by specifying the github id:
|
@@ -45,24 +45,18 @@ Emit a list of maintainers:
|
|
45
45
|
maintainers list
|
46
46
|
```
|
47
47
|
|
48
|
-
###
|
49
|
-
|
50
|
-
Emit a list of maintainers:
|
48
|
+
### Produce a summary report of maintainers within the puppetlabs org
|
51
49
|
|
52
50
|
```ruby
|
53
|
-
maintainers
|
51
|
+
maintainers report
|
54
52
|
```
|
55
53
|
|
56
|
-
###
|
57
|
-
|
58
|
-
```ruby
|
59
|
-
maintainers report https://github.com/gracehopper
|
60
|
-
```
|
54
|
+
### Validate the MAINTAINERS file
|
61
55
|
|
62
|
-
|
56
|
+
Run this from the root of your project.
|
63
57
|
|
64
58
|
```ruby
|
65
|
-
maintainers
|
59
|
+
maintainers validate
|
66
60
|
```
|
67
61
|
|
68
62
|
## Development
|
data/lib/maintainers/cli.rb
CHANGED
@@ -53,12 +53,25 @@ validate
|
|
53
53
|
be useful if you hand-edit the file but want to double-check
|
54
54
|
that it is still machine readable.
|
55
55
|
|
56
|
-
report
|
56
|
+
report [--verbose] [--details [repo|people]]
|
57
|
+
|
58
|
+
Report on maintainers throughout a github organization. By default,
|
59
|
+
the report just lists maintained repos, but see --details for more.
|
60
|
+
- The 'verbose' flag turns on some status. Note that the
|
61
|
+
report can take a while (a couple minutes) due to the number
|
62
|
+
of github API calls needed.
|
63
|
+
- The 'details' flag generates a report which is either
|
64
|
+
repo-centric, i.e. a sorted list of repos with the people
|
65
|
+
maintainer each, OR people-centric, i.e. a sorted list of
|
66
|
+
people with what repos they maintain.
|
57
67
|
|
58
|
-
Report on maintainers throughout a github organization.
|
59
68
|
Note: for the report to include private repos, generate a github
|
60
69
|
token with full control of private repositories, and then
|
61
70
|
set the environment variable GITHUB_TOKEN to that token.
|
71
|
+
Also note that this token may not really be optional:
|
72
|
+
specifically, if you do *not* specify a GITHUB_TOKEN and the
|
73
|
+
organization has a lot of repos (hi puppetlabs), you will likely
|
74
|
+
hit github rate limit exceptions.
|
62
75
|
USAGE
|
63
76
|
puts usage
|
64
77
|
exit 1
|
@@ -94,6 +107,12 @@ USAGE
|
|
94
107
|
'validate' => OptionParser.new do |opts|
|
95
108
|
end,
|
96
109
|
'report' => OptionParser.new do |opts|
|
110
|
+
opts.on("-v", "--verbose", "verbosity") do |v|
|
111
|
+
options[:verbose] = v
|
112
|
+
end
|
113
|
+
opts.on("-d", "--details [repos|people]", "detailed report") do |v|
|
114
|
+
options[:details] = v
|
115
|
+
end
|
97
116
|
end,
|
98
117
|
}
|
99
118
|
|
@@ -116,6 +135,11 @@ USAGE
|
|
116
135
|
usage
|
117
136
|
end
|
118
137
|
|
138
|
+
if subcommand == 'report' && !options[:details].nil? && !['repo', 'people'].include?(options[:details])
|
139
|
+
$stderr.puts "--details must specify either 'repo' or 'people'"
|
140
|
+
usage
|
141
|
+
end
|
142
|
+
|
119
143
|
if args.count > 0
|
120
144
|
$stderr.puts "Unexpected additional args #{args}"
|
121
145
|
usage
|
data/lib/maintainers/runner.rb
CHANGED
@@ -40,7 +40,7 @@ module Maintainers
|
|
40
40
|
def maintainers_schema
|
41
41
|
# I don't know what the idiomatic way is to access a non-ruby file packaged
|
42
42
|
# with the gem. This seems gross but it works.
|
43
|
-
schema_path = File.join(Gem.loaded_specs['maintainers'].gem_dir, 'schema/MAINTAINERS.json')
|
43
|
+
schema_path = File.join(Gem.loaded_specs['maintainers'].gem_dir, 'schema/MAINTAINERS-schema.json')
|
44
44
|
|
45
45
|
JSON.parse(File.read(schema_path))
|
46
46
|
end
|
@@ -75,7 +75,7 @@ module Maintainers
|
|
75
75
|
# minimum content for a maintainers file
|
76
76
|
maintainers = {}
|
77
77
|
maintainers["version"] = 1
|
78
|
-
maintainers["file_format"] = "This MAINTAINERS file format is described at
|
78
|
+
maintainers["file_format"] = "This MAINTAINERS file format is described at http://pup.pt/maintainers"
|
79
79
|
maintainers["issues"] = options[:issues]
|
80
80
|
maintainers["people"] = []
|
81
81
|
|
@@ -154,13 +154,60 @@ module Maintainers
|
|
154
154
|
end
|
155
155
|
end
|
156
156
|
|
157
|
+
def report_basic(maintainers_files)
|
158
|
+
maintainers_files.keys.sort.each { |repo|
|
159
|
+
maintainers = JSON.load( maintainers_files[repo] )
|
160
|
+
if !maintainers['maintained'].nil? && !maintainers['maintained']
|
161
|
+
puts "#{repo} (unmaintained)"
|
162
|
+
else
|
163
|
+
puts "#{repo}"
|
164
|
+
end
|
165
|
+
}
|
166
|
+
end
|
167
|
+
|
168
|
+
def report_repo_details(maintainers_files)
|
169
|
+
maintainers_files.keys.sort.each { |repo|
|
170
|
+
puts "\t#{repo}"
|
171
|
+
maintainers = JSON.load( maintainers_files[repo] )
|
172
|
+
puts "\t\tunmaintained" if !maintainers['maintained'].nil? && !maintainers['maintained']
|
173
|
+
maintainers['people'].each { |person|
|
174
|
+
puts "\t\t#{person['name'] ? person['name'] : person['github']}"
|
175
|
+
}
|
176
|
+
}
|
177
|
+
end
|
178
|
+
|
179
|
+
def report_people_details(maintainers_files)
|
180
|
+
people = {}
|
181
|
+
|
182
|
+
# populate the people hash, building up a 'repos' array per person
|
183
|
+
maintainers_files.keys.sort.each { |repo|
|
184
|
+
maintainers = JSON.load( maintainers_files[repo] )
|
185
|
+
maintainers['people'].each { |person|
|
186
|
+
github_id = person['github']
|
187
|
+
if people[github_id].nil?
|
188
|
+
people[github_id] = person
|
189
|
+
people[github_id]['repos'] = [ repo ]
|
190
|
+
else
|
191
|
+
people[github_id]['repos'] << repo
|
192
|
+
end
|
193
|
+
}
|
194
|
+
}
|
195
|
+
|
196
|
+
# report out on the people hash
|
197
|
+
people.keys.sort.each { |github_id|
|
198
|
+
person = people[github_id]
|
199
|
+
puts "#{person['name'] ? person['name'] : person['github']} is maintaining:"
|
200
|
+
person['repos'].each { |repo| puts "\t#{repo}" }
|
201
|
+
}
|
202
|
+
end
|
203
|
+
|
157
204
|
def report(options)
|
158
|
-
puts "Ok, hang tight, this may take a while as I query github ..."
|
205
|
+
puts "Ok, hang tight, this may take a while as I query github ..." if options[:verbose]
|
159
206
|
client = Octokit::Client.new(:access_token => ENV['GITHUB_TOKEN'], :auto_paginate => true)
|
160
207
|
|
161
208
|
repos = client.org_repos(options[:org])
|
162
209
|
|
163
|
-
puts "Found a total of #{repos.count} #{options[:org]} repos"
|
210
|
+
puts "Found a total of #{repos.count} #{options[:org]} repos" if options[:verbose]
|
164
211
|
|
165
212
|
# For now hardwire some arbitrary filters to help narrow down the
|
166
213
|
# number of repos reported on (and thus github API calls):
|
@@ -168,7 +215,7 @@ module Maintainers
|
|
168
215
|
# - ignore repos on a blocklist
|
169
216
|
# There are pretty arbitrary lines, so could be parameterized (or dropped).
|
170
217
|
|
171
|
-
|
218
|
+
lightly_forked, repos = repos.partition { |repo| repo.forks < 5 }
|
172
219
|
|
173
220
|
blocklist = [
|
174
221
|
'puppetlabs-modules',
|
@@ -185,31 +232,49 @@ module Maintainers
|
|
185
232
|
'courseware-lvm',
|
186
233
|
]
|
187
234
|
|
188
|
-
|
235
|
+
blocklisted, repos = repos.partition { |repo| blocklist.include? repo.name }
|
189
236
|
|
190
|
-
|
237
|
+
# hash of repo name to maintainers json blob
|
238
|
+
maintainers_files = { }
|
239
|
+
|
240
|
+
no_maintainers_file, repos = repos.partition { |repo|
|
191
241
|
begin
|
192
242
|
contents = client.contents("#{options[:org]}/#{repo.name}", :path => 'MAINTAINERS')
|
243
|
+
|
244
|
+
# the file content is base64 encoded with some '\n's sprinkled in.
|
245
|
+
# the split.join maneuver below strips out those '\n' sprinkles.
|
246
|
+
maintainers = Base64.decode64(contents[:content].split.join)
|
247
|
+
maintainers_files[repo.name] = maintainers
|
193
248
|
rescue Octokit::NotFound
|
194
249
|
end
|
195
250
|
|
196
251
|
contents.nil?
|
197
252
|
}
|
198
253
|
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
!validate_json(maintainers, true)
|
254
|
+
# ok, kinda awkward and not sure if this is worth reporting on?
|
255
|
+
# but some repos may contain a file called MAINTAINERS but in a
|
256
|
+
# different format
|
257
|
+
unrecognized_maintainers_file, repos = repos.partition { |repo|
|
258
|
+
!validate_json(maintainers_files[repo.name], true)
|
206
259
|
}
|
260
|
+
unrecognized_maintainers_file.each { |repo| maintainers_files.delete(repo.name) }
|
261
|
+
|
262
|
+
if options[:verbose]
|
263
|
+
puts "Skipped #{lightly_forked.count} repos with fewer than 5 forks" if lightly_forked && lightly_forked.count > 0
|
264
|
+
puts "Skipped #{blocklisted.count} repos on a blocklist" if blocklisted && blocklisted.count > 0
|
265
|
+
puts "Skipped #{no_maintainers_file.count} without a MAINTAINERS file" if no_maintainers_file && no_maintainers_file.count > 0
|
266
|
+
puts "Skipped #{unrecognized_maintainers_file.count} with a MAINTAINERS file in a different format" if unrecognized_maintainers_file && unrecognized_maintainers_file.count > 0
|
267
|
+
puts "Found #{repos.count} repos with MAINTAINERS files"
|
268
|
+
end
|
207
269
|
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
270
|
+
case options[:details]
|
271
|
+
when 'repo'
|
272
|
+
report_repo_details(maintainers_files)
|
273
|
+
when 'people'
|
274
|
+
report_people_details(maintainers_files)
|
275
|
+
else
|
276
|
+
report_basic(maintainers_files)
|
277
|
+
end
|
213
278
|
|
214
279
|
end
|
215
280
|
|
data/lib/maintainers/version.rb
CHANGED
File without changes
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: maintainers
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Puppet, Inc
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-09-
|
11
|
+
date: 2016-09-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -121,7 +121,7 @@ files:
|
|
121
121
|
- lib/maintainers/runner.rb
|
122
122
|
- lib/maintainers/version.rb
|
123
123
|
- maintainers.gemspec
|
124
|
-
- schema/MAINTAINERS.json
|
124
|
+
- schema/MAINTAINERS-schema.json
|
125
125
|
- schema/json-meta-schema.json
|
126
126
|
homepage: https://github.com/puppetlabs/maintainers
|
127
127
|
licenses: []
|