github_bus_factor 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 1cba5f9e910be4bd2032951b9fd6a7f4775b8ec2
4
+ data.tar.gz: d236b469ad20187f07a9d93017e2fe8a9af3e48a
5
+ SHA512:
6
+ metadata.gz: cb0fc42b4ce7a95d6245463a4ef251968a11bed8ea72008faa50352fff6dd234a5cae1b3b9ec00c1ba733c0eee21493b8a55f9a8a663a3fed4a38b10207e36f7
7
+ data.tar.gz: 12b58ce1d3d42be1f9818ddc1963edf7793ad31dd90bce637f02fc4541c4ceca3def922a2a464c6be5a242036f4f49824b07b98c9c5d1a4dcb90a856ec8d1ddd
data/.gitignore ADDED
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
data/.travis.yml ADDED
@@ -0,0 +1,4 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.2.1
4
+ before_install: gem install bundler -v 1.10.6
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in github_bus_factor.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2016 Sash Zats
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,46 @@
1
+ # GitHub Bus Factor
2
+
3
+ > More meaningful statistics for GitHub projects than just stars.
4
+
5
+ ![](https://raw.githubusercontent.com/zats/github_bus_factor/master/README/screenshot.png)
6
+
7
+ $ gem install github_bus_factor
8
+
9
+
10
+ # Report
11
+
12
+ | 🙂 | Description |
13
+ | :--: | :-- |
14
+ | 🍴 | **Forks**. Might mean people planning are fixing bugs or adding features. |
15
+ | 🔭 | **Watchers**. Shows number of people interested in project changes. |
16
+ | 🌟 | **Stars**. Might mean it is a good project or that it was featured in a mailing list. Some people use 🌟 as a "Like". |
17
+ | 🗓 | **Age**. Mature projects might mean battle tested project. Recent pushes might mean project is actively maintained. |
18
+ | 🍻 | **Pull Requests**. Community contributions to the project. Many closed PRs usually is a good sign, while no PRs usual is bad. |
19
+ | 🛠 | **Refactoring**. Balance between added and deleted code. Crude value not including semantic understanding of the code. |
20
+ | 📦 | **Releases**. Might mean disciplined maintainer. Certain dependency managers rely on releases to be present. |
21
+ | 🚌 | **Bus factor**. Chances of the project to become abandoned once current collaborators stop updating it. The higher - the worse. |
22
+
23
+
24
+ # Usage
25
+
26
+ You will need to create a GitHub access token. Head over to https://github.com/settings/tokens and create a new one, call the app `GitHub Score` and copy the token.
27
+
28
+ To fetch a report for a particular repository
29
+
30
+ $ github_bus_factor fetch octokit/octokit.rb
31
+
32
+ First time you call it, it will prompt you to provide the token you just created.
33
+
34
+ To remove the token
35
+
36
+ $ github_bus_factor logout
37
+
38
+ If you ever forget what each line of the report means, run
39
+
40
+ $ github_bus_factor about
41
+
42
+
43
+ ## License
44
+
45
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
46
+
Binary file
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "github_bus_factor"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start
data/bin/setup ADDED
@@ -0,0 +1,7 @@
1
+ #!/bin/bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+
5
+ bundle install
6
+
7
+ # Do any other automated setup that you need to do here
data/exe/github_score ADDED
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+ $LOAD_PATH.push File.expand_path("../../lib", __FILE__)
3
+
4
+ require "github_bus_factor"
@@ -0,0 +1,38 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'github_bus_factor/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "github_bus_factor"
8
+ spec.version = GitHubBusFactor::VERSION
9
+ spec.authors = ["Sash Zats"]
10
+ spec.email = ["sash@zats.io"]
11
+
12
+ spec.summary = "Is it a good idea to use this GitHub project?"
13
+ spec.description = "Provides few more parameters to estimate quality of the GitHub project besides stars."
14
+ spec.homepage = "https://github.com/zats/github_bus_factor"
15
+ spec.license = "MIT"
16
+
17
+ # Prevent pushing this gem to RubyGems.org by setting 'allowed_push_host', or
18
+ # delete this section to allow pushing this gem to any host.
19
+ if spec.respond_to?(:metadata)
20
+ spec.metadata['allowed_push_host'] = 'https://rubygems.org'
21
+ else
22
+ raise "RubyGems 2.0 or newer is required to protect against public gem pushes."
23
+ end
24
+
25
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
26
+ spec.bindir = "exe"
27
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
28
+ spec.require_paths = ["lib"]
29
+
30
+ spec.add_development_dependency "bundler", "~> 1.10"
31
+ spec.add_development_dependency "rake", "~> 10.0"
32
+ spec.add_development_dependency "octokit", "~> 0.4"
33
+ spec.add_development_dependency 'commander', '~> 4.3', '>= 4.3.3'
34
+ spec.add_development_dependency "security", "~> 0.1.3"
35
+ spec.add_development_dependency 'terminal-table', '~> 1.5', '>= 1.5.2'
36
+ spec.add_development_dependency 'faraday-http-cache', '~> 1.2', '>= 1.2.2'
37
+ spec.add_development_dependency 'activesupport', '~> 4.2', '>= 4.2.5'
38
+ end
@@ -0,0 +1,232 @@
1
+ require "github_bus_factor/version"
2
+ #!/usr/bin/env ruby
3
+
4
+ require 'rubygems'
5
+ require 'commander/import'
6
+ require 'octokit'
7
+ require 'security'
8
+ require 'terminal-table'
9
+ require 'faraday-http-cache'
10
+ require 'action_view'
11
+ require 'active_support/core_ext/numeric/time'
12
+ include ActionView::Helpers::DateHelper
13
+
14
+
15
+
16
+ module GitHubBusFactor
17
+ KEYCHAIN_SERVICE = 'github_bus_factor'
18
+ API_CALL_RETRY_COUNT = 3
19
+
20
+
21
+ program :version, '0.0.1'
22
+ program :description, 'More than just stars'
23
+ default_command :about
24
+
25
+ # There must be a better way to deal with GitHub caching…
26
+ def GitHubBusFactor.helper(count, block)
27
+ return unless count > 0
28
+ return if !block.call(count).nil?
29
+ puts "Waiting for GitHub cache. Will retry in 3 seconds…"
30
+ sleep(3)
31
+ helper(count - 1, block)
32
+ end
33
+
34
+
35
+ command :about do |c|
36
+ c.syntax = 'github_bus_factor about'
37
+ c.summary = 'Explains every line of the report.'
38
+ c.action do |args, options|
39
+ table = Terminal::Table.new do |t|
40
+ t.style = {:padding_left => 1, :padding_right => 2}
41
+ t.title = 'GitHub Score'
42
+ t.headings = ['', 'Description']
43
+ t << ['🍴', 'Forks. Might mean people planning are fixing bugs or adding features.']
44
+ t << ['🔭', 'Watchers. Shows number of people interested in project changes.']
45
+ t << ['🌟', 'Stars. Might mean it is a good project or that it was featured in a mailing list. Some people use 🌟 as a "Like".']
46
+ t << ['🗓', 'Age. Mature projects might mean battle tested project. Recent pushes might mean project is actively maintained.']
47
+ t << ['🍻', 'Pull Requests. Community contributions to the project. Many closed PRs usually is a good sign, while no PRs usual is bad.']
48
+ t << ['🛠', 'Refactoring. Balance between added and deleted code. Crude value not including semantic understanding of the code.']
49
+ t << ['📦', 'Releases. Might mean disciplined maintainer. Certain dependency managers rely on releases to be present.']
50
+ t << ['🚌', 'Bus factor. Chances of the project to become abandoned once current collaborators stop updating it. The higher - the worse.']
51
+ end
52
+ puts table
53
+ end
54
+ end
55
+
56
+ command :logout do |c|
57
+ c.syntax = 'github_bus_factor logout'
58
+ c.summary = 'Remove GitHub token from your keychain.'
59
+ c.action do |args, options|
60
+ Security::GenericPassword.delete(service: KEYCHAIN_SERVICE)
61
+ end
62
+ end
63
+
64
+ command :fetch do |c|
65
+ c.syntax = 'github_bus_factor fetch [options]'
66
+ c.summary = 'Fetches GitHub score for a given owner/repository'
67
+ c.option '--verbose', 'Add extra logging'
68
+ c.action do |args, options|
69
+ # owner / repo
70
+ throw "Expect owner/repo as an argument" unless args.count == 1
71
+ matches = args.first.match(/^(.+)\/(.+)$/)
72
+ throw "Expect owner/repo as an argument" unless !matches.nil?
73
+ ownerName, repoName = matches.captures
74
+ throw "Expect owner/repo as an argument" if ownerName.nil? || ownerName.empty? || repoName.nil? || repoName.empty?
75
+
76
+ # Token
77
+ tokenPassword = Security::GenericPassword.find(service: KEYCHAIN_SERVICE)
78
+ token = nil
79
+ unless tokenPassword
80
+ puts "Please create a GitHub access token at https://github.com/settings/tokens"
81
+ while token.nil? || token.empty? do
82
+ token = ask("Token: ")
83
+ Security::GenericPassword.add(KEYCHAIN_SERVICE, '', token) unless token.nil? || token.empty?
84
+ end
85
+ else
86
+ token = tokenPassword.password
87
+ end
88
+
89
+ # GitHub client
90
+ client = Octokit::Client.new(:access_token => token)
91
+ client.auto_paginate = true
92
+ repository = Octokit::Repository.new(:owner => ownerName, :repo => repoName)
93
+
94
+ # Cache
95
+ stack = Faraday::RackBuilder.new do |builder|
96
+ builder.use Faraday::HttpCache
97
+ builder.use Octokit::Response::RaiseError
98
+ builder.adapter Faraday.default_adapter
99
+ end
100
+ client.middleware = stack
101
+
102
+ # Output
103
+ output = []
104
+
105
+ # Info
106
+ puts("1/6 Fetching repository info…")
107
+ repository_info = client.repository(repository)
108
+ puts(repository_info.inspect) if options.verbose
109
+
110
+ # Forks
111
+ FORKS_THRESHOLD = 5
112
+ if repository_info.forks_count > FORKS_THRESHOLD
113
+ forks_value = "#{repository_info.forks_count} forks."
114
+ else
115
+ forks_value = "Few forks (#{repository_info.forks_count})."
116
+ end
117
+ output << ['🍴', forks_value]
118
+
119
+ # Watchers
120
+ WATCHERS_THRESHOLD = 5
121
+ if repository_info.subscribers_count > WATCHERS_THRESHOLD
122
+ watchers_value = "#{repository_info.subscribers_count} watchers."
123
+ else
124
+ watchers_value = "Few watchers (#{repository_info.subscribers_count})."
125
+ end
126
+ output << ['🔭', watchers_value]
127
+
128
+ # Stars
129
+ STARS_THRESHOLD = 10
130
+ if repository_info.stargazers_count > STARS_THRESHOLD
131
+ stars_value = "#{repository_info.stargazers_count} stars."
132
+ else
133
+ stars_value = "Few stars (#{repository_info.stargazers_count})."
134
+ end
135
+ output << ['🌟', stars_value]
136
+
137
+ # Age
138
+ created_at = repository_info.created_at
139
+ last_push = repository_info.pushed_at
140
+ output << ['🗓', "Created #{time_ago_in_words(created_at)} ago; last push #{time_ago_in_words(last_push)} ago."]
141
+
142
+ # PRs
143
+ puts("2/6 Fetching open PRs…")
144
+ open_PRs = client.pull_requests(repository, {:per_page => 100})
145
+ puts(open_PRs.inspect) if options.verbose
146
+
147
+ puts("3/6 Fetching closed PRs…")
148
+ closed_PRs = client.pull_requests(repository, {:state => 'closed'})
149
+ puts(closed_PRs.inspect) if options.verbose
150
+
151
+ total_PRs_count = open_PRs.count + closed_PRs.count
152
+ if total_PRs_count > 0
153
+ ratio = (Float(closed_PRs.count) / total_PRs_count * 100).round(2)
154
+ prs_value = "#{total_PRs_count} PRs: #{closed_PRs.count} closed; #{open_PRs.count} opened; #{ratio}% PRs are closed."
155
+ else
156
+ prs_value = 'No PRs opened yet for this repository.'
157
+ end
158
+ output << ['🍻', prs_value]
159
+
160
+ # Refactoring
161
+ code_frequency = nil
162
+ GitHubBusFactor.helper(API_CALL_RETRY_COUNT, lambda { |c|
163
+ puts("4/6 Fetching code frequency…")
164
+ code_frequency = client.code_frequency_stats(repository)
165
+ })
166
+ puts(code_frequency.inspect) if options.verbose
167
+
168
+ deletions = 0
169
+ additions = 0
170
+ refactoring = code_frequency.each { |frequency|
171
+ additions += frequency[1]
172
+ deletions += frequency[2]
173
+ }
174
+ refactoring = (Float(deletions.abs) / Float(additions) * 100).round(2)
175
+ REFACTORING_THRESHOLD = 5
176
+ if refactoring > REFACTORING_THRESHOLD
177
+ refactoring_value = "Deletions to additions ratio: #{refactoring}% (#{deletions}/#{additions})."
178
+ else
179
+ refactoring_value = "Mostly additions, few deletions (#{deletions}/#{additions})."
180
+ end
181
+ output << ['🛠', refactoring_value]
182
+
183
+ # Releases
184
+ puts("5/6 Fetching releases…")
185
+ releases = client.releases(repository)
186
+ puts(releases.inspect) if options.verbose
187
+ if !releases.empty?
188
+ latest_release = releases.first
189
+ release_name = latest_release.name.nil? || latest_release.name.empty? ? latest_release.tag_name : latest_release.name
190
+ releases_value = "#{releases.count} releases; latest release \"#{release_name}\": #{time_ago_in_words(latest_release.published_at)}."
191
+ else
192
+ releases_value = 'No releases.'
193
+ end
194
+ output << ['📦', releases_value]
195
+
196
+ # Bus factor
197
+ contributions = nil
198
+ GitHubBusFactor.helper(API_CALL_RETRY_COUNT, lambda { |c|
199
+ puts("6/6 Fetching contribution statistics…")
200
+ contributions = client.contributors_stats(repository)
201
+ })
202
+ puts(contributions.inspect) if options.verbose
203
+ contributions = contributions.map { |c| c.total }
204
+ min, max = contributions.minmax
205
+ delta = max - min
206
+ CONTRIBUTION_THRESHOLD = 0.7
207
+ meaningful = contributions.select { |c| (max - c) < delta * CONTRIBUTION_THRESHOLD }
208
+ total_contributions = contributions.reduce(0) { |t, c| t + c }
209
+ if meaningful.empty?
210
+ bus_factor = 100
211
+ else
212
+ average = contributions.reduce(0) { |a, c| a + Float(c) / total_contributions }
213
+ bus_factor = (average / meaningful.count * 100.0).round(2)
214
+ end
215
+ if bus_factor > 90
216
+ bus_factor_value = "Bus factor: #{bus_factor}%. Most likely one core contributor."
217
+ else
218
+ bus_factor_value = "Bus factor: #{bus_factor}% (#{meaningful.count} impactful contributors out of #{contributions.count})."
219
+ end
220
+ output << ['🚌', bus_factor_value]
221
+
222
+ # Output
223
+ puts("Thank you for you patience 💕\n\n")
224
+ table = Terminal::Table.new do |t|
225
+ t.title = "#{ownerName}/#{repoName}"
226
+ t.style = {:padding_left => 1, :padding_right => 2}
227
+ t.rows = output.each_with_index
228
+ end
229
+ puts table
230
+ end
231
+ end
232
+ end
@@ -0,0 +1,3 @@
1
+ module GitHubBusFactor
2
+ VERSION = "0.1.0"
3
+ end
metadata ADDED
@@ -0,0 +1,197 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: github_bus_factor
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Sash Zats
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2016-01-18 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.10'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.10'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: octokit
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '0.4'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '0.4'
55
+ - !ruby/object:Gem::Dependency
56
+ name: commander
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '4.3'
62
+ - - ">="
63
+ - !ruby/object:Gem::Version
64
+ version: 4.3.3
65
+ type: :development
66
+ prerelease: false
67
+ version_requirements: !ruby/object:Gem::Requirement
68
+ requirements:
69
+ - - "~>"
70
+ - !ruby/object:Gem::Version
71
+ version: '4.3'
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ version: 4.3.3
75
+ - !ruby/object:Gem::Dependency
76
+ name: security
77
+ requirement: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - "~>"
80
+ - !ruby/object:Gem::Version
81
+ version: 0.1.3
82
+ type: :development
83
+ prerelease: false
84
+ version_requirements: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - "~>"
87
+ - !ruby/object:Gem::Version
88
+ version: 0.1.3
89
+ - !ruby/object:Gem::Dependency
90
+ name: terminal-table
91
+ requirement: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - "~>"
94
+ - !ruby/object:Gem::Version
95
+ version: '1.5'
96
+ - - ">="
97
+ - !ruby/object:Gem::Version
98
+ version: 1.5.2
99
+ type: :development
100
+ prerelease: false
101
+ version_requirements: !ruby/object:Gem::Requirement
102
+ requirements:
103
+ - - "~>"
104
+ - !ruby/object:Gem::Version
105
+ version: '1.5'
106
+ - - ">="
107
+ - !ruby/object:Gem::Version
108
+ version: 1.5.2
109
+ - !ruby/object:Gem::Dependency
110
+ name: faraday-http-cache
111
+ requirement: !ruby/object:Gem::Requirement
112
+ requirements:
113
+ - - "~>"
114
+ - !ruby/object:Gem::Version
115
+ version: '1.2'
116
+ - - ">="
117
+ - !ruby/object:Gem::Version
118
+ version: 1.2.2
119
+ type: :development
120
+ prerelease: false
121
+ version_requirements: !ruby/object:Gem::Requirement
122
+ requirements:
123
+ - - "~>"
124
+ - !ruby/object:Gem::Version
125
+ version: '1.2'
126
+ - - ">="
127
+ - !ruby/object:Gem::Version
128
+ version: 1.2.2
129
+ - !ruby/object:Gem::Dependency
130
+ name: activesupport
131
+ requirement: !ruby/object:Gem::Requirement
132
+ requirements:
133
+ - - "~>"
134
+ - !ruby/object:Gem::Version
135
+ version: '4.2'
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: 4.2.5
139
+ type: :development
140
+ prerelease: false
141
+ version_requirements: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - "~>"
144
+ - !ruby/object:Gem::Version
145
+ version: '4.2'
146
+ - - ">="
147
+ - !ruby/object:Gem::Version
148
+ version: 4.2.5
149
+ description: Provides few more parameters to estimate quality of the GitHub project
150
+ besides stars.
151
+ email:
152
+ - sash@zats.io
153
+ executables:
154
+ - github_score
155
+ extensions: []
156
+ extra_rdoc_files: []
157
+ files:
158
+ - ".gitignore"
159
+ - ".travis.yml"
160
+ - Gemfile
161
+ - LICENSE.txt
162
+ - README.md
163
+ - README/screenshot.png
164
+ - Rakefile
165
+ - bin/console
166
+ - bin/setup
167
+ - exe/github_score
168
+ - github_bus_factor.gemspec
169
+ - lib/github_bus_factor.rb
170
+ - lib/github_bus_factor/version.rb
171
+ homepage: https://github.com/zats/github_bus_factor
172
+ licenses:
173
+ - MIT
174
+ metadata:
175
+ allowed_push_host: https://rubygems.org
176
+ post_install_message:
177
+ rdoc_options: []
178
+ require_paths:
179
+ - lib
180
+ required_ruby_version: !ruby/object:Gem::Requirement
181
+ requirements:
182
+ - - ">="
183
+ - !ruby/object:Gem::Version
184
+ version: '0'
185
+ required_rubygems_version: !ruby/object:Gem::Requirement
186
+ requirements:
187
+ - - ">="
188
+ - !ruby/object:Gem::Version
189
+ version: '0'
190
+ requirements: []
191
+ rubyforge_project:
192
+ rubygems_version: 2.4.6
193
+ signing_key:
194
+ specification_version: 4
195
+ summary: Is it a good idea to use this GitHub project?
196
+ test_files: []
197
+ has_rdoc: