how_is 24.0.0 → 25.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (62) hide show
  1. checksums.yaml +4 -4
  2. data/.github_changelog_generator +0 -1
  3. data/.rubocop.yml +37 -12
  4. data/.travis.yml +6 -3
  5. data/CHANGELOG.md +56 -0
  6. data/CONTRIBUTING.md +34 -0
  7. data/Gemfile +8 -4
  8. data/ISSUES.md +30 -54
  9. data/README.md +16 -91
  10. data/Rakefile +3 -31
  11. data/bin/prerelease-generate-changelog +1 -1
  12. data/bin/setup +0 -0
  13. data/build-debug.rb +20 -0
  14. data/exe/how_is +25 -22
  15. data/fixtures/vcr_cassettes/how-is-example-empty-repository.yml +334 -1
  16. data/fixtures/vcr_cassettes/how-is-example-repository.yml +350 -1
  17. data/fixtures/vcr_cassettes/how-is-from-config-frontmatter.yml +15234 -1
  18. data/fixtures/vcr_cassettes/how-is-how-is-travis-api-repos-builds.yml +2694 -1
  19. data/fixtures/vcr_cassettes/how-is-with-config-file.yml +15234 -1
  20. data/fixtures/vcr_cassettes/how_is_contributions_additions_count.yml +70 -1
  21. data/fixtures/vcr_cassettes/how_is_contributions_all_contributors.yml +70 -1
  22. data/fixtures/vcr_cassettes/how_is_contributions_changed_files.yml +70 -1
  23. data/fixtures/vcr_cassettes/how_is_contributions_changes.yml +70 -1
  24. data/fixtures/vcr_cassettes/how_is_contributions_commits.yml +70 -1
  25. data/fixtures/vcr_cassettes/how_is_contributions_compare_url.yml +70 -1
  26. data/fixtures/vcr_cassettes/how_is_contributions_default_branch.yml +70 -1
  27. data/fixtures/vcr_cassettes/how_is_contributions_deletions_count.yml +70 -1
  28. data/fixtures/vcr_cassettes/how_is_contributions_new_contributors.yml +70 -1
  29. data/fixtures/vcr_cassettes/how_is_contributions_summary.yml +70 -1
  30. data/fixtures/vcr_cassettes/how_is_contributions_summary_2.yml +70 -1
  31. data/how_is.gemspec +12 -6
  32. data/lib/how_is/cacheable.rb +71 -0
  33. data/lib/how_is/cli.rb +121 -124
  34. data/lib/how_is/config.rb +123 -0
  35. data/lib/how_is/constants.rb +9 -0
  36. data/lib/how_is/date_time_helpers.rb +48 -0
  37. data/lib/how_is/frontmatter.rb +14 -9
  38. data/lib/how_is/report.rb +86 -58
  39. data/lib/how_is/report_collection.rb +113 -0
  40. data/lib/how_is/sources/ci/appveyor.rb +88 -0
  41. data/lib/how_is/sources/ci/travis.rb +159 -0
  42. data/lib/how_is/sources/github/contributions.rb +169 -128
  43. data/lib/how_is/sources/github/issue_fetcher.rb +148 -0
  44. data/lib/how_is/sources/github/issues.rb +86 -235
  45. data/lib/how_is/sources/github/pulls.rb +19 -18
  46. data/lib/how_is/sources/github.rb +40 -18
  47. data/lib/how_is/sources/github_helpers.rb +8 -91
  48. data/lib/how_is/sources.rb +2 -0
  49. data/lib/how_is/template.rb +9 -0
  50. data/lib/how_is/templates/contributions_partial.html +1 -0
  51. data/lib/how_is/templates/{issues_or_pulls_partial.html_template → issues_or_pulls_partial.html} +0 -0
  52. data/lib/how_is/templates/new_contributors_partial.html +5 -0
  53. data/lib/how_is/templates/{report.html_template → report.html} +0 -8
  54. data/lib/how_is/templates/{report_partial.html_template → report_partial.html} +3 -3
  55. data/lib/how_is/text.rb +26 -0
  56. data/lib/how_is/version.rb +2 -1
  57. data/lib/how_is.rb +33 -60
  58. metadata +28 -47
  59. data/.hound.yml +0 -2
  60. data/.rubocop_todo.yml +0 -21
  61. data/lib/how_is/sources/travis.rb +0 -37
  62. data/roadmap.markdown +0 -82
@@ -2,11 +2,11 @@
2
2
  <h1>%{title}</h1>
3
3
  <p>%{contributions_summary}</p>
4
4
 
5
+ <h2>New Contributors</h2>
6
+ %{new_contributors}
7
+
5
8
  <h2>Pull Requests</h2>
6
9
  %{pulls_summary}
7
10
 
8
11
  <h2>Issues</h2>
9
12
  %{issues_summary}
10
-
11
- <h2>Issues Per Label</h2>
12
- %{issues_per_label}
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module HowIs
4
+ ##
5
+ # Helper class for printing text, but hiding it when e.g. running in CI.
6
+ class Text
7
+ def self.show_default_output
8
+ @show_default_output = true unless
9
+ instance_variable_defined?(:"@show_default_output")
10
+
11
+ @show_default_output
12
+ end
13
+
14
+ def self.show_default_output=(val)
15
+ @show_default_output = val
16
+ end
17
+
18
+ def self.print(*args)
19
+ Kernel.print(*args) if HowIs::Text.show_default_output
20
+ end
21
+
22
+ def self.puts(*args)
23
+ Kernel.puts(*args) if HowIs::Text.show_default_output
24
+ end
25
+ end
26
+ end
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module HowIs
4
- VERSION = "24.0.0"
4
+ VERSION = "25.0.0"
5
+ VERSION_STRING = "how_is #{HowIs::VERSION}"
5
6
  end
data/lib/how_is.rb CHANGED
@@ -1,39 +1,47 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "how_is/version"
4
+ require "how_is/config"
4
5
  require "how_is/report"
6
+ require "how_is/report_collection"
5
7
 
8
+ ##
9
+ # Top-level module for creating a report.
6
10
  module HowIs
7
- DEFAULT_REPORT_FILE = "report.html"
11
+ def self.default_config(repository)
12
+ {
13
+ "repository" => repository,
14
+ "reports" => {
15
+ "html" => {
16
+ "directory" => ".",
17
+ "frontmatter" => {},
18
+ "filename" => "report.html",
19
+ },
20
+ },
21
+ }
22
+ end
8
23
 
9
- def self.new(repository, date)
10
- Report.new(repository, date)
24
+ def self.new(repository, date, cache_mechanism = nil)
25
+ config =
26
+ Config.new
27
+ .load_defaults
28
+ .load(default_config(repository))
29
+ config["cache"] = {"type" => "self", "cache_mechanism" => cache_mechanism} if cache_mechanism
30
+ Report.new(config, date)
11
31
  end
12
32
 
13
33
  ##
14
34
  # Generates a series of report files based on a config Hash.
15
35
  #
16
- # @param config [Hash] A Hash specifying the formats, locations, etc
17
- # of the reports to generate.
36
+ # @param config [ReportCollection] All the information needed to generate
37
+ # the reports.
18
38
  # @param date [String] A string containing the date (YYYY-MM-DD) that the
19
39
  # report ends on. E.g., for Jan 1-Feb 1 2017, you'd pass 2017-02-01.
20
40
  def self.from_config(config, date)
21
- report = Report.new(config["repository"], date)
22
- report_data = prepare_report_metadata(config["repository"], date)
23
-
24
- generated_reports =
25
- config["reports"].map { |format, report_config|
26
- # Sometimes report_data has unused keys, which generates a warning, but
27
- # we're okay with it, so we wrap it with silence_warnings {}.
28
- filename = silence_warnings { report_config["filename"] % report_data }
29
- file = File.join(report_config["directory"], filename)
30
-
31
- report_export = report.send("to_#{format}", report_config["frontmatter"])
41
+ raise "Expected config to be Hash, got #{config.class}" unless \
42
+ config.is_a?(Hash)
32
43
 
33
- [file, report_export]
34
- }
35
-
36
- generated_reports.to_h
44
+ ReportCollection.new(config, date)
37
45
  end
38
46
 
39
47
  ##
@@ -44,47 +52,12 @@ module HowIs
44
52
  ["html", "json"]
45
53
  end
46
54
 
47
- def self.template(filename)
48
- dir = File.expand_path("./how_is/templates/", __dir__)
49
- path = File.join(dir, filename)
50
-
51
- open(path).read
52
- end
53
-
54
55
  ##
55
- # Returns whether or not the specified +file+ can be exported to.
56
+ # Returns whether or not the specified +format+ is supported.
56
57
  #
57
- # @param file [String] A filename.
58
- # @return [Boolean] +true+ if HowIs can export to the file, +false+
59
- # if it can't.
60
- def self.can_export_to?(file)
61
- # TODO: Check if the file is writable?
62
- supported_formats.include?(file.split(".").last)
63
- end
64
-
65
- def self.silence_warnings(&block)
66
- with_warnings(nil, &block)
67
- end
68
- private_class_method :silence_warnings
69
-
70
- def self.with_warnings(flag, &_block)
71
- old_verbose = $VERBOSE
72
- $VERBOSE = flag
73
- yield
74
- ensure
75
- $VERBOSE = old_verbose
76
- end
77
- private_class_method :with_warnings
78
-
79
- def self.prepare_report_metadata(repository, date)
80
- end_date = DateTime.strptime(date, "%Y-%m-%d")
81
- friendly_end_date = end_date.strftime("%B %d, %y")
82
-
83
- {
84
- repository: repository,
85
- date: end_date,
86
- friendly_date: friendly_end_date,
87
- }
58
+ # @param format_name [String] The format in question.
59
+ # @return [Boolean] +true+ if HowIs supports the format, +false+ otherwise.
60
+ def self.supported_format?(format_name)
61
+ supported_formats.include?(format_name)
88
62
  end
89
- private_class_method :prepare_report_metadata
90
63
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: how_is
3
3
  version: !ruby/object:Gem::Version
4
- version: 24.0.0
4
+ version: 25.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ellen Marie Dash
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-03-17 00:00:00.000000000 Z
11
+ date: 2019-04-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: github_api
@@ -24,34 +24,20 @@ dependencies:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: 0.18.1
27
- - !ruby/object:Gem::Dependency
28
- name: contracts
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - "~>"
32
- - !ruby/object:Gem::Version
33
- version: 0.16.0
34
- type: :runtime
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - "~>"
39
- - !ruby/object:Gem::Version
40
- version: 0.16.0
41
27
  - !ruby/object:Gem::Dependency
42
28
  name: okay
43
29
  requirement: !ruby/object:Gem::Requirement
44
30
  requirements:
45
31
  - - "~>"
46
32
  - !ruby/object:Gem::Version
47
- version: 7.0.0
33
+ version: '11.0'
48
34
  type: :runtime
49
35
  prerelease: false
50
36
  version_requirements: !ruby/object:Gem::Requirement
51
37
  requirements:
52
38
  - - "~>"
53
39
  - !ruby/object:Gem::Version
54
- version: 7.0.0
40
+ version: '11.0'
55
41
  - !ruby/object:Gem::Dependency
56
42
  name: json
57
43
  requirement: !ruby/object:Gem::Requirement
@@ -72,14 +58,14 @@ dependencies:
72
58
  requirements:
73
59
  - - "~>"
74
60
  - !ruby/object:Gem::Version
75
- version: '1.16'
61
+ version: '2.0'
76
62
  type: :development
77
63
  prerelease: false
78
64
  version_requirements: !ruby/object:Gem::Requirement
79
65
  requirements:
80
66
  - - "~>"
81
67
  - !ruby/object:Gem::Version
82
- version: '1.16'
68
+ version: '2.0'
83
69
  - !ruby/object:Gem::Dependency
84
70
  name: rake
85
71
  requirement: !ruby/object:Gem::Requirement
@@ -100,14 +86,14 @@ dependencies:
100
86
  requirements:
101
87
  - - "~>"
102
88
  - !ruby/object:Gem::Version
103
- version: '3.7'
89
+ version: '3.8'
104
90
  type: :development
105
91
  prerelease: false
106
92
  version_requirements: !ruby/object:Gem::Requirement
107
93
  requirements:
108
94
  - - "~>"
109
95
  - !ruby/object:Gem::Version
110
- version: '3.7'
96
+ version: '3.8'
111
97
  - !ruby/object:Gem::Dependency
112
98
  name: timecop
113
99
  requirement: !ruby/object:Gem::Requirement
@@ -178,20 +164,6 @@ dependencies:
178
164
  - - ">="
179
165
  - !ruby/object:Gem::Version
180
166
  version: '0'
181
- - !ruby/object:Gem::Dependency
182
- name: pry
183
- requirement: !ruby/object:Gem::Requirement
184
- requirements:
185
- - - ">="
186
- - !ruby/object:Gem::Version
187
- version: '0'
188
- type: :development
189
- prerelease: false
190
- version_requirements: !ruby/object:Gem::Requirement
191
- requirements:
192
- - - ">="
193
- - !ruby/object:Gem::Version
194
- version: '0'
195
167
  description:
196
168
  email:
197
169
  - me@duckie.co
@@ -203,13 +175,12 @@ files:
203
175
  - ".codeclimate.yml"
204
176
  - ".github_changelog_generator"
205
177
  - ".gitignore"
206
- - ".hound.yml"
207
178
  - ".rspec"
208
179
  - ".rubocop.yml"
209
- - ".rubocop_todo.yml"
210
180
  - ".travis.yml"
211
181
  - CHANGELOG.md
212
182
  - CODE_OF_CONDUCT.md
183
+ - CONTRIBUTING.md
213
184
  - Gemfile
214
185
  - ISSUES.md
215
186
  - LICENSE.txt
@@ -219,6 +190,7 @@ files:
219
190
  - bin/prerelease-generate-changelog
220
191
  - bin/setup
221
192
  - bors.toml
193
+ - build-debug.rb
222
194
  - design/01-functionality.md
223
195
  - design/02-implementation.md
224
196
  - exe/how_is
@@ -240,21 +212,31 @@ files:
240
212
  - fixtures/vcr_cassettes/how_is_contributions_summary_2.yml
241
213
  - how_is.gemspec
242
214
  - lib/how_is.rb
215
+ - lib/how_is/cacheable.rb
243
216
  - lib/how_is/cli.rb
217
+ - lib/how_is/config.rb
218
+ - lib/how_is/constants.rb
219
+ - lib/how_is/date_time_helpers.rb
244
220
  - lib/how_is/frontmatter.rb
245
221
  - lib/how_is/report.rb
222
+ - lib/how_is/report_collection.rb
246
223
  - lib/how_is/sources.rb
224
+ - lib/how_is/sources/ci/appveyor.rb
225
+ - lib/how_is/sources/ci/travis.rb
247
226
  - lib/how_is/sources/github.rb
248
227
  - lib/how_is/sources/github/contributions.rb
228
+ - lib/how_is/sources/github/issue_fetcher.rb
249
229
  - lib/how_is/sources/github/issues.rb
250
230
  - lib/how_is/sources/github/pulls.rb
251
231
  - lib/how_is/sources/github_helpers.rb
252
- - lib/how_is/sources/travis.rb
253
- - lib/how_is/templates/issues_or_pulls_partial.html_template
254
- - lib/how_is/templates/report.html_template
255
- - lib/how_is/templates/report_partial.html_template
232
+ - lib/how_is/template.rb
233
+ - lib/how_is/templates/contributions_partial.html
234
+ - lib/how_is/templates/issues_or_pulls_partial.html
235
+ - lib/how_is/templates/new_contributors_partial.html
236
+ - lib/how_is/templates/report.html
237
+ - lib/how_is/templates/report_partial.html
238
+ - lib/how_is/text.rb
256
239
  - lib/how_is/version.rb
257
- - roadmap.markdown
258
240
  homepage: https://github.com/how-is/how_is
259
241
  licenses:
260
242
  - MIT
@@ -265,17 +247,16 @@ require_paths:
265
247
  - lib
266
248
  required_ruby_version: !ruby/object:Gem::Requirement
267
249
  requirements:
268
- - - ">="
250
+ - - "~>"
269
251
  - !ruby/object:Gem::Version
270
- version: '0'
252
+ version: '2.4'
271
253
  required_rubygems_version: !ruby/object:Gem::Requirement
272
254
  requirements:
273
255
  - - ">="
274
256
  - !ruby/object:Gem::Version
275
257
  version: '0'
276
258
  requirements: []
277
- rubyforge_project:
278
- rubygems_version: 2.7.6
259
+ rubygems_version: 3.0.3
279
260
  signing_key:
280
261
  specification_version: 4
281
262
  summary: Quantify the health of a GitHub repository.
data/.hound.yml DELETED
@@ -1,2 +0,0 @@
1
- ruby:
2
- config_file: .rubocop.yml
data/.rubocop_todo.yml DELETED
@@ -1,21 +0,0 @@
1
- # This configuration was generated by
2
- # `rubocop --auto-gen-config`
3
- # on 2017-07-16 19:09:46 +0200 using RuboCop version 0.49.1.
4
- # The point is for the user to remove these configuration records
5
- # one by one as the offenses are removed from the code base.
6
- # Note that changes in the inspected code, or installation of new
7
- # versions of RuboCop, may require this file to be generated again.
8
-
9
- # Offense count: 8
10
- Metrics/AbcSize:
11
- Max: 31
12
-
13
- # Offense count: 2
14
- # Configuration parameters: CountComments.
15
- Metrics/ClassLength:
16
- Max: 117
17
-
18
- # Offense count: 3
19
- # Configuration parameters: CountComments.
20
- Metrics/MethodLength:
21
- Max: 31
@@ -1,37 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "okay/http"
4
- require "how_is/sources/github"
5
-
6
- module HowIs::Sources
7
- # Fetches metadata about CI builds from travis-ci.org.
8
- class Travis
9
- # @param repository [String] GitHub repository name, of the format user/repo.
10
- # @param start_date [String] Start date for the report being generated.
11
- # @param end_date [String] End date for the report being generated.
12
- def initialize(repository, start_date, end_date)
13
- @repository = repository
14
- @start_date = start_date
15
- @end_date = end_date
16
- # TODO: Use start/end date.
17
- # TODO: Figure out Default Branch of the repo
18
- end
19
-
20
- def builds
21
- JSON.parse(fetch_builds)
22
- end
23
-
24
- private
25
-
26
- # Returns API result of /repos/:user/:repo/builds for Push type Travis
27
- # events.
28
- #
29
- # @return [String] JSON result
30
- def fetch_builds
31
- Okay::HTTP.get(
32
- "http://api.travis-ci.org/repos/#{@repository}/builds?event_type=push",
33
- headers: {"Accept" => "application/vnd.travis-ci.2+json"}
34
- ).body
35
- end
36
- end
37
- end
data/roadmap.markdown DELETED
@@ -1,82 +0,0 @@
1
- # How_is Roadmap
2
-
3
- 2016-09-01
4
-
5
- A brief overview of how_is' goals and current status.
6
-
7
- ## Current Progress
8
-
9
- So far, HTML and JSON reports work extremely well. PDF support has lagged
10
- due to difficulties finding a library that can do everything needed.
11
- There is [an integration test that fails for an unknown reason](https://github.com/how-is/how_is/issues/36).
12
-
13
- Reports can be generated using a config file, typically named
14
- how_is.yml. This has been successfully used for
15
- [how-is.github.io/how-is-rubygems](https://how-is.github.io/how-is-rubygems/)
16
- ([how_is.yml source](https://github.com/how-is/how-is-rubygems/blob/gh-pages/how_is.yml)).
17
-
18
- how_is can be used as either an executable or a library, however
19
- [library usage is currently undocumented](https://github.com/how-is/how_is/issues/45).
20
-
21
- Metrics that have been implemented include:
22
-
23
- * number of open Issues,
24
- * number of open Pull Requests,
25
- * number of issues associated with each label, as well as the number associated with no label,
26
- * average Issue age,
27
- * average Pull Request age,
28
- * date oldest Issue was opened,
29
- * date oldest Pull Request was opened.
30
-
31
- HTML reports contain a graph showing the issues assigned each label (or no
32
- label). PDF reports contain a less-nice variant of
33
- that graph.
34
-
35
- ## Goals
36
-
37
- The next major steps are complex metrics and creating a web
38
- dashboard for multiple projects.
39
-
40
- Complex metrics require things like cloning the repository or making multiple API requests.
41
-
42
- ### Complex Metrics
43
-
44
- Complex metrics will include:
45
-
46
- * code churn (code change over time),
47
- * average response time by a team member in the past week,
48
- * graph of average response time by a team member per week.
49
-
50
- These metrics serve to either quantify the state of the repository, quantify the state of the codebase itself, or both. By quantifying the state of the issue tracker and codebase, it will hopefully be easier to decide what needs to be done.
51
-
52
- ### Dashboard
53
-
54
- The end goal for the dashboard is to have a website where you can view
55
- information about multiple projects, and identify trends.
56
-
57
- Currently, there is a way to generate reports based on a configuration
58
- file, which has been successfully used to generate [reports for RubyGems](https://how-is.github.io/how-is-rubygems/).
59
- However, these have to be manually generated each month.
60
-
61
- Idealy, these could be generated automatically, and would be stored in a
62
- database. Once that is done, the information can be more easily retrieved
63
- in groups and used to generate graphs or more complex summaries.
64
-
65
- ## Milestones
66
-
67
- Before beginning work on the dashboard, the how_is APIs need to be
68
- documented and possibly cleaned up.
69
-
70
- Once that's done, the plan for beginning work on the dashboard is
71
- roughly:
72
-
73
- 1. decide what the dashboard will eventually contain,
74
- 2. create a design for the finished dashboard (so we know what's being
75
- worked towards),
76
- 3. figure out the software architecture required to support this,
77
- 4. determine what parts of the dashboard are currently implementable,
78
- 5. create an intermediate design for what how_is can actually support
79
- (this should be a subset of the original design).
80
-
81
- Once these have been done, it should be possible to have people work on
82
- the dashboard in parallel.