Class: Inq::Sources::Github::Contributions
- Inherits:
-
Object
- Object
- Inq::Sources::Github::Contributions
- Includes:
- Inq::Sources::GithubHelpers
- Defined in:
- lib/inq/sources/github/contributions.rb
Overview
Fetch information about who has contributed to a repository during a given period.
Usage:
c = Inq::Contributions.new(start_date: '2017-07-01', user: 'duckinator', repo: 'inq')
c.commits #=> All commits during July 2017.
c.contributors #=> All contributors during July 2017.
c.new_contributors #=> New contributors during July 2017.
Instance Method Summary collapse
- #additions_count ⇒ Object
- #changed_files ⇒ Object
- #changes ⇒ Object
- #commit(sha) ⇒ Object
- #commits ⇒ Object
- #compare_url ⇒ Object
-
#contributors ⇒ Hash{String => Hash}
Author information keyed by author’s email.
- #default_branch ⇒ Object
- #deletions_count ⇒ Object
-
#initialize(config, start_date, end_date, cache) ⇒ Contributions
constructor
Returns an object that fetches contributor information about a particular repository for a month-long period starting on
start_date
. -
#new_contributors ⇒ Hash{String => Hash}
Returns a list of contributors that have zero commits before the @since_date.
- #new_contributors_html ⇒ Object
- #stats ⇒ Object
-
#to_html(start_text: nil) ⇒ Object
rubocop:disable Metrics/AbcSize.
Methods included from Inq::Sources::GithubHelpers
#average_age_for, #newest_for, #obj_to_array_of_hashes, #oldest_for, #sort_iops_by_created_at
Constructor Details
#initialize(config, start_date, end_date, cache) ⇒ Contributions
Returns an object that fetches contributor information about a particular repository for a month-long period starting on start_date
.
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
# File 'lib/inq/sources/github/contributions.rb', line 35 def initialize(config, start_date, end_date, cache) raise "Got String, need Hash. The Github::Contributions API changed." if config.is_a?(String) @config = config @cache = cache @github = Sources::Github.new(config) @repository = config["repository"] @user, @repo = @repository.split("/") @github = ::Github.new(auto_pagination: true) { |conf| conf.basic_auth = @github.basic_auth } # IMPL. DETAIL: The external API uses "end_date" so it's clearer, # but internally we use "until_date" to match GitHub's API. @since_date = start_date @until_date = end_date @commit = {} @stats = nil @changed_files = nil end |
Instance Method Details
#additions_count ⇒ Object
165 166 167 |
# File 'lib/inq/sources/github/contributions.rb', line 165 def additions_count changes["stats"]["additions"] end |
#changed_files ⇒ Object
153 154 155 156 157 158 159 |
# File 'lib/inq/sources/github/contributions.rb', line 153 def changed_files return @changed_files if @changed_files files = commits.flat_map do |commit| commit.files.map { |file| file["filename"] } end @changed_files = files.sort.uniq end |
#changes ⇒ Object
161 162 163 |
# File 'lib/inq/sources/github/contributions.rb', line 161 def changes {"stats" => stats, "files" => changed_files} end |
#commit(sha) ⇒ Object
135 136 137 138 139 |
# File 'lib/inq/sources/github/contributions.rb', line 135 def commit(sha) @commit[sha] ||= @cache.cached("repos_commit_#{sha}") do @github.repos.commits.get(user: @user, repo: @repo, sha: sha) end end |
#commits ⇒ Object
110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 |
# File 'lib/inq/sources/github/contributions.rb', line 110 def commits return @commits if instance_variable_defined?(:@commits) args = { user: @user, repo: @repo, since: @since_date, until: @until_date, } Inq::Text.print "Fetching #{@repository} commit data." # The commits list endpoint doesn't include all stats. # So, to compensate, we make N requests here, where N is number # of commits returned, and then we die a bit inside. @commits = @cache.cached("repos_commits", args.to_json) do @github.repos.commits.list(**args).map { |c| Inq::Text.print "." commit(c.sha) } end Inq::Text.puts @commits end |
#compare_url ⇒ Object
173 174 175 |
# File 'lib/inq/sources/github/contributions.rb', line 173 def compare_url "https://github.com/#{@user}/#{@repo}/compare/#{default_branch}@%7B#{@since_date}%7D...#{default_branch}@%7B#{@until_date}%7D" # rubocop:disable Metrics/LineLength end |
#contributors ⇒ Hash{String => Hash}
Returns Author information keyed by author’s email.
104 105 106 107 108 |
# File 'lib/inq/sources/github/contributions.rb', line 104 def contributors commits.map { |api_response| [api_response.commit..email, api_response.commit..to_h] }.to_h end |
#default_branch ⇒ Object
177 178 179 180 181 |
# File 'lib/inq/sources/github/contributions.rb', line 177 def default_branch @default_branch ||= @cache.cached("repos_default_branch") do @github.repos.get(user: @user, repo: @repo).default_branch end end |
#deletions_count ⇒ Object
169 170 171 |
# File 'lib/inq/sources/github/contributions.rb', line 169 def deletions_count changes["stats"]["deletions"] end |
#new_contributors ⇒ Hash{String => Hash}
Returns a list of contributors that have zero commits before the @since_date.
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
# File 'lib/inq/sources/github/contributions.rb', line 61 def new_contributors @new_contributors ||= contributors.select { |email, _committer| args = { user: @user, repo: @repo, until: @since_date, author: email, } # True if +email+ never wrote a commit for +@repo+ before +@since_date+, false otherwise. commits = @cache.cached("repos_commits", args.to_json) do @github.repos.commits.list(**args) end commits.count.zero? } end |
#new_contributors_html ⇒ Object
77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 |
# File 'lib/inq/sources/github/contributions.rb', line 77 def new_contributors_html names = new_contributors.values.map { |c| c["name"] } list_items = names.map { |n| " <li>#{n}</li>" }.join("\n") if names.length.zero? num_new_contributors = "no" else num_new_contributors = names.length end if names.length == 1 was_were = "was" contributor_s = "" else was_were = "were" contributor_s = "s" end Template.apply("new_contributors_partial.html", { was_were: was_were, contributor_s: contributor_s, number_of_new_contributors: num_new_contributors, list_items: list_items, }).strip end |
#stats ⇒ Object
141 142 143 144 145 146 147 148 149 150 151 |
# File 'lib/inq/sources/github/contributions.rb', line 141 def stats return @stats if @stats stats = {"total" => 0, "additions" => 0, "deletions" => 0} commits.map do |commit| stats.keys.each do |key| stats[key] += commit.stats[key] end end @stats = stats end |
#to_html(start_text: nil) ⇒ Object
rubocop:disable Metrics/AbcSize
184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 |
# File 'lib/inq/sources/github/contributions.rb', line 184 def to_html(start_text: nil) start_text ||= "From #{pretty_date(@since_date)} through #{pretty_date(@until_date)}" Inq::Template.apply("contributions_partial.html", { start_text: start_text, user: @user, repo: @repo, compare_url: compare_url, additions_count_str: (additions_count == 1) ? "was" : "were", authors: pluralize("author", contributors.length), new_commits: pluralize("new commit", commits.length), additions: pluralize("addition", additions_count), deletions: pluralize("deletion", deletions_count), changed_files: pluralize("file", changed_files.length), }).strip end |