Class: GithubMetadata

Inherits:
Object
  • Object
show all
Defined in:
lib/github_metadata.rb,
lib/github_metadata/version.rb

Overview

A simple scraper that fetches data from github repos that is not available via the API. See README for an introduction and overview.

Defined Under Namespace

Classes: Commit, Contributor, RepoNotFound

Constant Summary collapse

VERSION =
"0.3.0"

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(user, repo) ⇒ GithubMetadata

Returns a new instance of GithubMetadata.



42
43
44
# File 'lib/github_metadata.rb', line 42

def initialize(user, repo)
  @user, @repo = user, repo
end

Instance Attribute Details

#repoObject (readonly)

Returns the value of attribute repo.



12
13
14
# File 'lib/github_metadata.rb', line 12

def repo
  @repo
end

#userObject (readonly)

Returns the value of attribute user.



12
13
14
# File 'lib/github_metadata.rb', line 12

def user
  @user
end

Class Method Details

.fetch(user, repo) ⇒ Object

Similar to initialization with GithubMetadata.new, but it will immediately try to fetch the repo document and importantly will swallow GithubMetadata::RepoNotFound errors, returning nil instead so you can easily do something like this:

if metadata = GithubMetadata.fetch(‘rails’, ‘rails’)

...

end



53
54
55
56
57
58
59
# File 'lib/github_metadata.rb', line 53

def self.fetch(user, repo)
  instance = new(user, repo)
  instance.issues
  instance
rescue GithubMetadata::RepoNotFound => err
  nil
end

Instance Method Details

#average_recent_committed_at(num = 100) ⇒ Object

Returns the average date of recent commits (by default all (max 20), can be modified by giving the optional argument)



151
152
153
154
155
156
# File 'lib/github_metadata.rb', line 151

def average_recent_committed_at(num=100)
  commit_times = recent_commits[0...num].map {|c| c.committed_at.to_f }
  return nil if commit_times.empty?
  average_time = commit_times.inject(0) {|s, i| s + i} / commit_times.length
  Time.at(average_time).utc
end

#branches_urlObject



69
70
71
# File 'lib/github_metadata.rb', line 69

def branches_url
  File.join(github_url, 'branches')
end

#commits_feed_urlObject



73
74
75
# File 'lib/github_metadata.rb', line 73

def commits_feed_url
  File.join(github_url, "commits/#{default_branch}.atom")
end

#contributor_namesObject

Will return all contributor real names, falling back to the username when real name is not specified



97
98
99
# File 'lib/github_metadata.rb', line 97

def contributor_names
  @contributor_names ||= contributors.map {|c| c.realname || c.username }
end

#contributor_realnamesObject

Shorthand form for getting an array of all contributor github realnames, with users that don’t have a realname specified filtered out



91
92
93
# File 'lib/github_metadata.rb', line 91

def contributor_realnames
  @contributor_realnames ||= contributors.map(&:realname).compact
end

#contributor_usernamesObject

Shorthand form for getting an array of all contributor github usernames



85
86
87
# File 'lib/github_metadata.rb', line 85

def contributor_usernames
  @contributor_usernames ||= contributors.map(&:username)
end

#contributorsObject

Returns an array of GithubMetadata::Contributor instances, one for each contributor listed on the contributors page of github



79
80
81
82
# File 'lib/github_metadata.rb', line 79

def contributors
  load_contributors unless @contributors
  @contributors
end

#contributors_urlObject



65
66
67
# File 'lib/github_metadata.rb', line 65

def contributors_url
  File.join(github_url, 'contributors')
end

#default_branchObject

Returns the default branch of the repo



133
134
135
136
137
# File 'lib/github_metadata.rb', line 133

def default_branch
  @default_branch ||= Nokogiri::HTML(open(branches_url)).at_css('tr.base td.name h3').text.strip.chomp
rescue OpenURI::HTTPError => err
  raise GithubMetadata::RepoNotFound, err.to_s
end

#github_urlObject



61
62
63
# File 'lib/github_metadata.rb', line 61

def github_url
  "https://github.com/#{user}/#{repo}/"
end

#has_issues?Boolean

Returns true if the repo has issues enabled

Returns:

  • (Boolean)


114
115
116
# File 'lib/github_metadata.rb', line 114

def has_issues?
  !!issues
end

#has_wiki?Boolean

Returns true when the repo has a wiki

Returns:

  • (Boolean)


102
103
104
# File 'lib/github_metadata.rb', line 102

def has_wiki?
  !!wiki_pages
end

#issuesObject

Returns issue count or nil if issues are disabled



119
120
121
122
123
# File 'lib/github_metadata.rb', line 119

def issues
  issue_link = document.at_css('a[highlight="issues"] .counter')
  return nil unless issue_link
  issue_link.text[/\d+/].to_i
end

#pull_requestsObject

Returns amount of pull requests



126
127
128
129
130
# File 'lib/github_metadata.rb', line 126

def pull_requests
  pull_request_link = document.at_css('a[highlight="repo_pulls"] .counter')
  return nil unless pull_request_link
  pull_request_link.text[/\d+/].to_i
end

#recent_commitsObject

Returns (at most) the last 20 commits (fetched from atom feed of the default_branch) as instances of GithubMetadata::Commit



141
142
143
144
145
146
147
# File 'lib/github_metadata.rb', line 141

def recent_commits
  @recent_commits ||= commits_feed.entries.map {|e| GithubMetadata::Commit.new(e) }
  
# TODO: Write tests for this error handling. See commits_feed method - this will result in NoMethodError 'entries' on nil
rescue NoMethodError => err
  nil
end

#wiki_pagesObject

Returns the amount of wiki pages or nil when no wiki is present



107
108
109
110
111
# File 'lib/github_metadata.rb', line 107

def wiki_pages
  wiki_link = document.at_css('a[highlight="repo_wiki"] .counter')
  return nil unless wiki_link
  wiki_link.text[/\d+/].to_i
end