Class: HowIs::Contributions
- Inherits:
-
Object
- Object
- HowIs::Contributions
- Defined in:
- lib/how_is/contributions.rb
Overview
Fetch information about who has contributed to a repository during a given period.
Usage:
github = Github.new()
c = HowIs::Contributions.new(github: github, start_date: '2017-07-01', user: 'how-is', repo: 'how_is')
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
TODO: Don’t hard-code the default branch.
- #deletions_count ⇒ Object
-
#initialize(github: Fetcher.default_github_instance, start_date:, user:, repo:) ⇒ 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] Committers keyed by GitHub login name
Returns a list of contributors that have zero commits before the @since_date.
- #pretty_end_date ⇒ Object
- #pretty_start_date ⇒ Object
- #summary(start_text: nil) ⇒ Object
Constructor Details
#initialize(github: Fetcher.default_github_instance, start_date:, user:, repo:) ⇒ Contributions
Returns an object that fetches contributor information about a particular repository for a month-long period starting on start_date
.
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
# File 'lib/how_is/contributions.rb', line 25 def initialize(github: Fetcher.default_github_instance, start_date:, user:, repo:) @github = github # IMPL. DETAIL: The external API uses "start_date" so it's clearer, # but internally we use "since_date" to match GitHub's API. @since_date = Date.strptime(start_date, "%Y-%m-%d") d = @since_date.day m = @since_date.month y = @since_date.year @until_date = Date.new(y, m + 1, d) @user = user @repo = repo end |
Instance Method Details
#additions_count ⇒ Object
112 113 114 |
# File 'lib/how_is/contributions.rb', line 112 def additions_count changes["stats"]["additions"] end |
#changed_files ⇒ Object
108 109 110 |
# File 'lib/how_is/contributions.rb', line 108 def changed_files changes["files"] end |
#changes ⇒ Object
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/how_is/contributions.rb', line 79 def changes if @stats.nil? || @changed_files.nil? @stats = { "total" => 0, "additions" => 0, "deletions" => 0, } @changed_files = [] commits.map do |commit| commit.stats.each do |k, v| @stats[k] += v end @changed_files += commit.files.map { |file| file["filename"] } end @changed_files.sort.uniq! end {"stats" => @stats, "files" => @changed_files} end |
#commit(sha) ⇒ Object
74 75 76 77 |
# File 'lib/how_is/contributions.rb', line 74 def commit(sha) @commit ||= {} @commit[sha] ||= @github.repos.commits.get(user: @user, repo: @repo, sha: sha) end |
#commits ⇒ Object
63 64 65 66 67 68 69 70 71 72 |
# File 'lib/how_is/contributions.rb', line 63 def commits return @commits if defined?(@commits) commits = @github.repos.commits.list(user: @user, repo: @repo, since: @since_date) # The commits list endpoint doesn't include all commit data, e.g. stats. # So, we make N requests here, where N == number of commits returned, # and then we die a bit inside. @commits = commits.map { |c| commit(c.sha) } end |
#compare_url ⇒ Object
120 121 122 123 124 |
# File 'lib/how_is/contributions.rb', line 120 def compare_url = @since_date.to_time.to_i = @until_date.to_time.to_i "https://github.com/#{@user}/#{@repo}/compare/#{default_branch}@%7B#{}%7D...#{default_branch}@%7B#{}%7D" end |
#contributors ⇒ Hash{String => Hash}
Returns Author information keyed by author’s email.
57 58 59 60 61 |
# File 'lib/how_is/contributions.rb', line 57 def contributors commits.map { |api_response| [api_response.commit..email, api_response.commit..to_h] }.to_h end |
#default_branch ⇒ Object
TODO: Don’t hard-code the default branch.
104 105 106 |
# File 'lib/how_is/contributions.rb', line 104 def default_branch "master" end |
#deletions_count ⇒ Object
116 117 118 |
# File 'lib/how_is/contributions.rb', line 116 def deletions_count changes["stats"]["deletions"] end |
#new_contributors ⇒ Hash{String => Hash] Committers keyed by GitHub login name
Returns a list of contributors that have zero commits before the @since_date.
45 46 47 48 49 50 51 52 53 54 |
# File 'lib/how_is/contributions.rb', line 45 def new_contributors # author: GitHub login, name or email by which to filter by commit author. @new_contributors ||= contributors.select do |email, _committer| # Returns true if +email+ never wrote a commit for +@repo+ before +@since_date+. @github.repos.commits.list(user: @user, repo: @repo, until: @since_date, author: email).count.zero? end end |
#pretty_end_date ⇒ Object
130 131 132 |
# File 'lib/how_is/contributions.rb', line 130 def pretty_end_date @until_date.strftime("%b %d, %Y") end |
#pretty_start_date ⇒ Object
126 127 128 |
# File 'lib/how_is/contributions.rb', line 126 def pretty_start_date @since_date.strftime("%b %d, %Y") end |
#summary(start_text: nil) ⇒ Object
134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 |
# File 'lib/how_is/contributions.rb', line 134 def summary(start_text: nil) # TODO: Pulse has information about _all_ branches. Do we want that? # If we do, we'd need to pass a branch name as the 'sha' parameter # to /repos/:owner/:repo/commits. # https://developer.github.com/v3/repos/commits/ start_text ||= "From #{pretty_start_date} through #{pretty_end_date}" "#{start_text}, #{@user}/#{@repo} gained "\ "<a href=\"#{compare_url}\">#{pluralize('new commit', commits.length)}</a>, " \ "contributed by #{pluralize('author', contributors.length)}. There " \ "#{(additions_count == 1) ? 'was' : 'were'} " \ "#{pluralize('addition', additions_count)} and " \ "#{pluralize('deletion', deletions_count)} across " \ "#{pluralize('file', changed_files.length)}." end |