how_is 10.0.0 → 11.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/how_is.gemspec CHANGED
@@ -35,4 +35,6 @@ Gem::Specification.new do |spec|
35
35
  spec.add_development_dependency "rake", "~> 11.2"
36
36
  spec.add_development_dependency "rspec", "~> 3.5"
37
37
  spec.add_development_dependency "timecop", "~> 0.8.1"
38
+ spec.add_development_dependency "vcr", "~> 3.0"
39
+ spec.add_development_dependency "webmock"
38
40
  end
@@ -12,12 +12,16 @@ module HowIs
12
12
  class Analyzer
13
13
  include Contracts::Core
14
14
 
15
+ ##
16
+ # Raised when attempting to export to an unsupported format.
15
17
  class UnsupportedImportFormat < StandardError
16
18
  def initialize(format)
17
19
  super("Unsupported import format: #{format}")
18
20
  end
19
21
  end
20
22
 
23
+ ##
24
+ # Generates and returns an analysis.
21
25
  Contract Fetcher::Results, C::KeywordArgs[analysis_class: C::Optional[Class]] => Analysis
22
26
  def call(data, analysis_class: Analysis)
23
27
  issues = data.issues
@@ -43,6 +47,8 @@ module HowIs
43
47
  )
44
48
  end
45
49
 
50
+ ##
51
+ # Generates an analysis from a JSON report.
46
52
  def from_file(file)
47
53
  extension = file.split('.').last
48
54
  raise UnsupportedImportFormat, extension unless extension == 'json'
@@ -82,10 +88,13 @@ module HowIs
82
88
  hash
83
89
  end
84
90
 
91
+ # Returns the number of issues with no label.
85
92
  def num_with_no_label(issues)
86
93
  issues.select { |x| x['labels'].empty? }.length
87
94
  end
88
95
 
96
+ # Given an Array of dates, average the timestamps and return the date that
97
+ # represents.
89
98
  def average_date_for(issues_or_pulls)
90
99
  timestamps = issues_or_pulls.map { |iop| Date.parse(iop['created_at']).strftime('%s').to_i }
91
100
  average_timestamp = timestamps.reduce(:+) / issues_or_pulls.length
@@ -94,7 +103,10 @@ module HowIs
94
103
  end
95
104
 
96
105
  # Given an Array of issues or pulls, return the average age of them.
106
+ # Returns nil if no issues or pulls are provided.
97
107
  def average_age_for(issues_or_pulls)
108
+ return nil if issues_or_pulls.empty?
109
+
98
110
  ages = issues_or_pulls.map {|iop| time_ago_in_seconds(iop['created_at'])}
99
111
  raw_average = ages.reduce(:+) / ages.length
100
112
 
@@ -136,15 +148,21 @@ module HowIs
136
148
  end
137
149
 
138
150
  # Given an Array of issues or pulls, return the creation date of the oldest.
151
+ # Returns nil if no issues or pulls are provided.
139
152
  def oldest_for(issues_or_pulls)
153
+ return nil if issues_or_pulls.empty?
154
+
140
155
  issues_or_pulls.sort_by {|x| DateTime.parse(x['created_at']) }.first
141
156
  end
142
157
 
158
+ # Given an issue or PR, returns the date it was created.
143
159
  def date_for(issue_or_pull)
144
160
  DateTime.parse(issue_or_pull['created_at'])
145
161
  end
146
162
 
147
163
  private
164
+ # Takes an Array of labels, and returns amodified list that includes links
165
+ # to each label.
148
166
  def with_label_links(labels, repository)
149
167
  labels.map do |label, num_issues|
150
168
  label_link = "https://github.com/#{repository}/issues?q=" + CGI.escape("is:open is:issue label:\"#{label}\"")
@@ -153,11 +171,14 @@ module HowIs
153
171
  end.to_h
154
172
  end
155
173
 
174
+ # Returns how many seconds ago a date (as a String) was.
156
175
  def time_ago_in_seconds(x)
157
176
  DateTime.now.strftime("%s").to_i - DateTime.parse(x).strftime("%s").to_i
158
177
  end
159
178
 
160
179
  def issue_or_pull_to_hash(iop)
180
+ return nil if iop.nil?
181
+
161
182
  ret = {}
162
183
 
163
184
  ret['html_url'] = iop['html_url']
@@ -22,14 +22,16 @@ class HowIs::CLI
22
22
  class Parser
23
23
  attr_reader :opts
24
24
 
25
+ # Parses +argv+ to generate an options Hash to control the behavior of
26
+ # the library.
25
27
  def call(argv)
26
28
  opts = Slop::Options.new
27
29
  opts.banner =
28
30
  <<-EOF.gsub(/ *\| ?/, '')
29
- | Usage: how_is REPOSITORY [--report REPORT_FILE]
31
+ | Usage: how_is REPOSITORY [--report REPORT_FILE] [--from JSON_FILE]
30
32
  | how_is --config CONFIG_FILE
31
33
  |
32
- | Where REPOSITORY is of the format <GitHub username or org>/<repository name>.
34
+ | Where REPOSITORY is <GitHub username or org>/<repository name>.
33
35
  | CONFIG_FILE defaults to how_is.yml.
34
36
  |
35
37
  | E.g., if you wanted to check https://github.com/how-is/how_is,
@@ -53,28 +55,33 @@ class HowIs::CLI
53
55
 
54
56
  options[:report] ||= DEFAULT_REPORT_FILE
55
57
 
56
- # The following are only useful if true.
58
+ # The following are only useful if they're not nil or false.
57
59
  # Removing them here simplifies contracts and keyword args for other APIs.
58
60
  options.delete(:config) unless options[:config]
59
61
  options.delete(:help) unless options[:help]
60
62
  options.delete(:version) unless options[:version]
61
63
 
64
+ # Raise an exception if the file can't be exported.
62
65
  unless HowIs.can_export_to?(options[:report])
63
66
  raise InvalidOutputFileError, "Invalid file: #{options[:report_file]}. Supported formats: #{HowIs.supported_formats.join(', ')}"
64
67
  end
65
68
 
66
- if options[:config]
67
- # Nothing to do.
68
- elsif options[:from]
69
- # Opening this file here seems a bit messy, but it works.
70
- raise InvalidInputFileError, "No such file: #{options[:from]}" unless File.file?(options[:from])
71
-
72
- options[:repository] = JSON.parse(open(options[:from_file]).read)['repository']
73
- raise InvalidInputFileError, "Invalid JSON report file." unless options[:repository]
74
- elsif argv.length >= 1
75
- options[:repository] = argv.delete_at(0)
76
- else
77
- raise NoRepositoryError, "No repository specified."
69
+ unless options[:config]
70
+ # If we pass --config, other options (excluding --help and --version)
71
+ # are ignored. As such, everything in this `unless` block is irrelevant.
72
+
73
+ if options[:from]
74
+ raise InvalidInputFileError, "No such file: #{options[:from]}" unless File.file?(options[:from])
75
+
76
+ # Opening the file here is a bit gross, but I couldn't find a better
77
+ # way to do it. -@duckinator
78
+ options[:repository] = JSON.parse(open(options[:from_file]).read)['repository']
79
+ raise InvalidInputFileError, "Invalid JSON report file." unless options[:repository]
80
+ elsif argv.length >= 1
81
+ options[:repository] = argv.delete_at(0)
82
+ else
83
+ raise NoRepositoryError, "No repository specified."
84
+ end
78
85
  end
79
86
 
80
87
  {
data/lib/how_is/cli.rb CHANGED
@@ -28,12 +28,16 @@ class HowIs::CLI
28
28
  YAML.dump(frontmatter)
29
29
  end
30
30
 
31
+ ##
32
+ # Generates a series of report files based on a YAML config file.
31
33
  def from_config_file(config_file = nil, **kwargs)
32
34
  config_file ||= DEFAULT_CONFIG_FILE
33
35
 
34
36
  from_config(YAML.load_file(config_file), **kwargs)
35
37
  end
36
38
 
39
+ ##
40
+ # Generates a series of report files based on a config Hash.
37
41
  def from_config(config,
38
42
  github: nil,
39
43
  report_class: nil)
@@ -67,6 +71,8 @@ class HowIs::CLI
67
71
  end
68
72
  end
69
73
 
74
+ # Combine the frontmatter, report data, and raw report into a report with
75
+ # frontmatter.
70
76
  def build_report(frontmatter, report_data, report)
71
77
  str = StringIO.new
72
78
 
@@ -24,6 +24,8 @@ class HowIs::Fetcher
24
24
  end
25
25
 
26
26
 
27
+ ##
28
+ # Fetches repository information from GitHub and returns a Results object.
27
29
  Contract String, C::Or[C::RespondTo[:issues, :pulls], nil] => Results
28
30
  def call(repository,
29
31
  github = nil)
@@ -39,7 +41,8 @@ class HowIs::Fetcher
39
41
  )
40
42
  end
41
43
 
42
- private def obj_to_array_of_hashes(object)
44
+ private
45
+ def obj_to_array_of_hashes(object)
43
46
  object.to_a.map(&:to_h)
44
47
  end
45
48
  end
data/lib/how_is/pulse.rb CHANGED
@@ -14,8 +14,16 @@ module HowIs
14
14
  end
15
15
 
16
16
  def html_summary
17
- @pulse_page_response.body
18
- .split('<div class="section diffstat-summary">').last
17
+ parts =
18
+ @pulse_page_response.body
19
+ .split('<div class="section diffstat-summary">')
20
+
21
+ if parts.length == 1
22
+ return "There hasn't been any activity on #{@repository} in the last month."
23
+ end
24
+
25
+ parts
26
+ .last
19
27
  .split('</div>').first
20
28
  .gsub('<a href="/', '<a href="https://github.com/')
21
29
  .strip
@@ -38,7 +38,7 @@ module HowIs
38
38
  if row[2]
39
39
  label_text = link(row[0], row[2])
40
40
  else
41
- label_text = row[1]
41
+ label_text = row[0]
42
42
  end
43
43
 
44
44
  @r += <<-EOF
@@ -60,7 +60,7 @@ module HowIs
60
60
  instance_exec(&block)
61
61
  end
62
62
 
63
- def export!(file, &block)
63
+ def export_file(file, &block)
64
64
  report = export(&block)
65
65
 
66
66
  File.open(file, 'w') do |f|
@@ -8,7 +8,7 @@ module HowIs
8
8
  to_json
9
9
  end
10
10
 
11
- def export!(file, &block)
11
+ def export_file(file, &block)
12
12
  File.open(file, 'w') do |f|
13
13
  f.write export
14
14
  end
data/lib/how_is/report.rb CHANGED
@@ -1,3 +1,6 @@
1
+ require 'date'
2
+ require 'how_is/pulse'
3
+
1
4
  module HowIs
2
5
  class UnsupportedExportFormat < StandardError
3
6
  def initialize(format)
@@ -27,6 +30,14 @@ module HowIs
27
30
  end
28
31
 
29
32
  private
33
+ def pluralize(text, number)
34
+ number == 1 ? text : "#{text}s"
35
+ end
36
+
37
+ def are_is(number)
38
+ number == 1 ? "is" : "are"
39
+ end
40
+
30
41
  def issue_or_pr_summary(type, type_label)
31
42
  oldest_date_format = "%b %e, %Y"
32
43
  a = analysis
@@ -36,20 +47,39 @@ module HowIs
36
47
  type_link = a.send("#{type}s_url")
37
48
  oldest = a.send("oldest_#{type}")
38
49
 
39
- "There are #{link("#{number_of_type} #{type_label}s open", type_link)}. " +
40
- "The average #{type_label} age is #{a.send("average_#{type}_age")}, and the " +
41
- "#{link("oldest", oldest['html_url'])} was opened on #{oldest['date'].strftime(oldest_date_format)}."
50
+ if number_of_type == 0
51
+ "There are #{link("no #{type_label}s open", type_link)}."
52
+ else
53
+ "There #{are_is(number_of_type)} #{link("#{number_of_type} #{pluralize(type_label, number_of_type)} open", type_link)}. " +
54
+ "The average #{type_label} age is #{a.send("average_#{type}_age")}, and the " +
55
+ "#{link("oldest", oldest['html_url'])} was opened on #{oldest['date'].strftime(oldest_date_format)}."
56
+ end
42
57
  end
43
58
  end
44
59
 
45
60
  class Report
46
- require 'how_is/report/pdf'
47
61
  require 'how_is/report/json'
48
62
  require 'how_is/report/html'
49
63
 
64
+ # The way this entire class works is there is a REPORT_BLOCK proc which
65
+ # calls various methods to create the report, and REPORT_BLOCK is eventually
66
+ # instance_exec'd by the various *Report (HtmlReport, previously PdfReport)
67
+ # classes, which define the methods required.
68
+ #
69
+ # The *Report class inherit from BaseReport, which implements the common
70
+ # methods for them.
71
+
50
72
  REPORT_BLOCK = proc do
51
73
  title "How is #{analysis.repository}?"
52
74
 
75
+ # DateTime#new_offset(0) sets the timezone to UTC. I think it does this
76
+ # without changing anything besides the timezone, but who knows, 'cause
77
+ # new_offset is entirely undocumented! (Even though it's used in the
78
+ # DateTime documentation!)
79
+ #
80
+ # TODO: Stop pretending everyone who runs how_is is in UTC.
81
+ text "Monthly report, ending on #{DateTime.now.new_offset(0).strftime('%B %e, %Y')}."
82
+
53
83
  text github_pulse_summary
54
84
 
55
85
  header "Pull Requests"
@@ -67,13 +97,17 @@ module HowIs
67
97
  horizontal_bar_graph issues_per_label
68
98
  end
69
99
 
70
- def self.export!(analysis, file)
100
+ ##
101
+ # Export a report to a file.
102
+ def self.export_file(analysis, file)
71
103
  format = file.split('.').last
72
104
  report = get_report_class(format).new(analysis)
73
105
 
74
- report.export!(file, &REPORT_BLOCK)
106
+ report.export_file(file, &REPORT_BLOCK)
75
107
  end
76
108
 
109
+ ##
110
+ # Export a report to a String.
77
111
  def self.export(analysis, format = HowIs::DEFAULT_FORMAT)
78
112
  report = get_report_class(format).new(analysis)
79
113
 
@@ -81,6 +115,8 @@ module HowIs
81
115
  end
82
116
 
83
117
  private
118
+ # Given a format name (+format+), returns the corresponding <blah>Report
119
+ # class.
84
120
  def self.get_report_class(format)
85
121
  class_name = "#{format.capitalize}Report"
86
122
 
@@ -1,3 +1,3 @@
1
1
  module HowIs
2
- VERSION = "10.0.0"
2
+ VERSION = "11.0.0"
3
3
  end
data/lib/how_is.rb CHANGED
@@ -15,27 +15,37 @@ module HowIs
15
15
 
16
16
  DEFAULT_FORMAT = :html
17
17
 
18
+ ##
19
+ # Generate a report file.
18
20
  def self.generate_report_file(report:, **kw_args)
19
21
  analysis = self.generate_analysis(**kw_args)
20
22
 
21
- Report.export!(analysis, report)
23
+ Report.export_file(analysis, report)
22
24
  end
23
25
 
26
+ ##
27
+ # Generates and returns a report as a String.
24
28
  def self.generate_report(format:, **kw_args)
25
29
  analysis = self.generate_analysis(**kw_args)
26
30
 
27
31
  Report.export(analysis, format)
28
32
  end
29
33
 
34
+ ##
35
+ # Returns a list of possible export formats.
30
36
  def self.supported_formats
31
37
  report_constants = HowIs.constants.grep(/.Report/) - [:BaseReport]
32
38
  report_constants.map {|x| x.to_s.split('Report').first.downcase }
33
39
  end
34
40
 
41
+ ##
42
+ # Returns whether or not the specified +file+ can be exported to.
35
43
  def self.can_export_to?(file)
44
+ # TODO: Check if the file is writable?
36
45
  supported_formats.include?(file.split('.').last)
37
46
  end
38
47
 
48
+ # Generate an analysis. Used internally for generate_report{,_file}.
39
49
  Contract C::KeywordArgs[repository: String,
40
50
  from: C::Optional[C::Or[String, nil]],
41
51
  fetcher: C::Optional[Class],
data/roadmap.markdown CHANGED
@@ -1,14 +1,24 @@
1
1
  # How_is Roadmap
2
2
 
3
+ 2016-09-01
4
+
3
5
  A brief overview of how_is' goals and current status.
4
6
 
5
- ## Goals
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).
6
12
 
7
- How_is is intended to be usable both as a standalone program and a as library, with reports generated as either files or Ruby Strings. Initial export formats supported will be JSON and PDF, with HTML to follow later. When exporting a report, you can use the data from a previous JSON export to avoid making network requests.
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)).
8
17
 
9
- Metrics will be divided into two categories during implementation: Simple and Complex. Simple ones will be implementable using only the information gathered from one API call to the issue tracker. Complex metrics require things like cloning the repository or making multiple API requests.
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).
10
20
 
11
- Simple metrics will include:
21
+ Metrics that have been implemented include:
12
22
 
13
23
  * number of open Issues,
14
24
  * number of open Pull Requests,
@@ -18,6 +28,19 @@ Simple metrics will include:
18
28
  * date oldest Issue was opened,
19
29
  * date oldest Pull Request was opened.
20
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
+
21
44
  Complex metrics will include:
22
45
 
23
46
  * code churn (code change over time),
@@ -26,24 +49,34 @@ Complex metrics will include:
26
49
 
27
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.
28
51
 
29
- Once HTML export is implemented, a web service is planned to be created which tracks these metrics over time for the RubyGems repository. The details of this have not been fully fleshed out, but I am attempting to design the library in such a way to allow the flexibility required to do this.
30
-
31
- ## Current Status
32
-
33
- As of June 15th 2016, how_is supports exports to JSON or PDF, but not HTML. For JSON and PDF, all Simple metrics have been implemented in some form, although they made need some polish ([#8](https://github.com/duckinator/how_is/issues/8)). HTML export is not implemented, and no Complex metrics are implemented. Tracking the number of issues without labels has also not been implemented ([#1](https://github.com/duckinator/how_is/issues/1)).
52
+ ### Dashboard
34
53
 
35
- Exporting to Ruby Strings that contain valid JSON, PDF, or HTML documents has also not been implemented ([#7](https://github.com/duckinator/how_is/issues/7)).
54
+ The end goal for the dashboard is to have a website where you can view
55
+ information about multiple projects, and identify trends.
36
56
 
37
- Authentication is not being used, but will likely be necessary, as it would raise the API rate limits ([#6](https://github.com/duckinator/how_is/issues/6)).
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.
38
60
 
39
- ### Requirements for 1.0
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.
40
64
 
41
- Once JSON and PDF exports are fully implemented ([#1](https://github.com/duckinator/how_is/issues/1)) and the README has a proper list of the metrics covered, v1.0 will be released.
65
+ ## Milestones
42
66
 
43
- ### Requirements for 2.0
67
+ Before beginning work on the dashboard, the how_is APIs need to be
68
+ documented and possibly cleaned up.
44
69
 
45
- Once everything required for v1.0 as well as exporting to Strings ([#7](https://github.com/duckinator/how_is/issues/7)) has been implemented, v2.0 will be released.
70
+ Once that's done, the plan for beginning work on the dashboard is
71
+ roughly:
46
72
 
47
- ### Other changes
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).
48
80
 
49
- All other changes ([#8](https://github.com/duckinator/how_is/issues/8), [#6](https://github.com/duckinator/how_is/issues/6), any changes without an accompanying issue) will be grouped together in either the next major release, or a separate minor release.
81
+ Once these have been done, it should be possible to have people work on
82
+ the dashboard in parallel.
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: 10.0.0
4
+ version: 11.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: 2016-09-01 00:00:00.000000000 Z
11
+ date: 2016-11-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: github_api
@@ -164,6 +164,34 @@ dependencies:
164
164
  - - "~>"
165
165
  - !ruby/object:Gem::Version
166
166
  version: 0.8.1
167
+ - !ruby/object:Gem::Dependency
168
+ name: vcr
169
+ requirement: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - "~>"
172
+ - !ruby/object:Gem::Version
173
+ version: '3.0'
174
+ type: :development
175
+ prerelease: false
176
+ version_requirements: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - "~>"
179
+ - !ruby/object:Gem::Version
180
+ version: '3.0'
181
+ - !ruby/object:Gem::Dependency
182
+ name: webmock
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'
167
195
  description:
168
196
  email:
169
197
  - me@duckie.co
@@ -176,6 +204,7 @@ files:
176
204
  - ".rspec"
177
205
  - ".rspec-ignore-tags"
178
206
  - ".travis.yml"
207
+ - CHANGELOG.md
179
208
  - CODE_OF_CONDUCT.md
180
209
  - Gemfile
181
210
  - LICENSE.txt
@@ -183,12 +212,12 @@ files:
183
212
  - Rakefile
184
213
  - bin/console
185
214
  - bin/setup
186
- - data/issues.plg
187
215
  - exe/how_is
216
+ - fixtures/vcr_cassettes/how_is-example-repository.yml
217
+ - fixtures/vcr_cassettes/how_is-with-config-file.yml
188
218
  - how_is.gemspec
189
219
  - lib/how_is.rb
190
220
  - lib/how_is/analyzer.rb
191
- - lib/how_is/chart.rb
192
221
  - lib/how_is/cli.rb
193
222
  - lib/how_is/cli/parser.rb
194
223
  - lib/how_is/fetcher.rb
@@ -196,7 +225,6 @@ files:
196
225
  - lib/how_is/report.rb
197
226
  - lib/how_is/report/html.rb
198
227
  - lib/how_is/report/json.rb
199
- - lib/how_is/report/pdf.rb
200
228
  - lib/how_is/version.rb
201
229
  - roadmap.markdown
202
230
  homepage: https://github.com/duckinator/how_is
@@ -219,7 +247,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
219
247
  version: '0'
220
248
  requirements: []
221
249
  rubyforge_project:
222
- rubygems_version: 2.5.1
250
+ rubygems_version: 2.6.8
223
251
  signing_key:
224
252
  specification_version: 4
225
253
  summary: Quantify the health of a GitHub repository is.
data/data/issues.plg DELETED
@@ -1,22 +0,0 @@
1
- if (!exists("chartsize")) chartsize = '500,500'
2
- if (!exists("labelfont")) labelfont = 'Helvetica,12'
3
- if (!exists("chartfont")) chartfont = 'Helvetica,12'
4
- if (!exists("data")) data = 'issues-per-label.dat'
5
- if (!exists("pngfile")) data = 'issues-per-label.png'
6
-
7
- set terminal png size chartsize font chartfont
8
-
9
- set output pngfile
10
-
11
- unset key
12
- unset border
13
- set tics nomirror
14
- unset xtics
15
-
16
- set style fill solid 0.15 border
17
-
18
- plot data using 1:2 with boxes, data using 1:(0):3 with \
19
- labels left \
20
- rotate by 90 \
21
- font labelfont \
22
- offset 0,0.45