Module: PryGithub::GithubHelpers

Defined in:
lib/pry-github.rb

Instance Method Summary collapse

Instance Method Details

#find_git_root(dir) ⇒ Object



40
41
42
43
44
45
46
47
48
# File 'lib/pry-github.rb', line 40

def find_git_root(dir)
  git_root = "."
  Dir.chdir dir do
    git_root =  `git rev-parse --show-toplevel`.chomp
  end

  raise "No associated git repository found!" if git_root =~ /fatal:/
  git_root
end

#find_github_remote(repo) ⇒ Object



50
51
52
53
54
55
56
# File 'lib/pry-github.rb', line 50

def find_github_remote(repo)
  remote_urls = repo.remotes.map { |remote| repo.config["remote.#{remote.name.split('/')[0]}.url"] }
  gh_url = remote_urls.find { |url| url =~ /github\.com/ }

  raise "No GitHub remote found!" unless gh_url
  gh_url
end

#get_file_from_commit(path) ⇒ Object



12
13
14
15
16
17
18
19
20
21
22
# File 'lib/pry-github.rb', line 12

def get_file_from_commit(path)
  git_root = find_git_root(File.dirname(path))
  repo = Grit::Repo.new(git_root)
  head = repo.commits.first
  tree_names = relative_path(git_root, path).split("/")
  start_tree = head.tree
  blob_name = tree_names.last
  tree = tree_names[0..-2].inject(start_tree)  { |a, v|  a.trees.find { |t| t.basename == v } }
  blob = tree.blobs.find { |v| v.basename == blob_name }
  blob.data
end

#get_github_url(meth, url_type = "blob") ⇒ Object



58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/pry-github.rb', line 58

def get_github_url(meth, url_type="blob")
  file_name = meth.source_location.first
  code, start_line = method_code_from_head(meth)

  git_root = find_git_root(File.dirname(file_name))

  repo = Grit::Repo.new(git_root)
  gh_url = find_github_remote(repo)

  # ssh urls can't be parsed with URI.parse
  if gh_url[0..3] == "git@"
    gh_url = gh_url.gsub(":", "/")
    gh_url[0..3] = "https://"
  end

  uri = URI.parse(gh_url)
  https_url = "https://#{uri.host}#{uri.path}".gsub(".git", "")
  https_url += "/#{url_type}/#{repo.commit("HEAD").sha}"
  https_url += file_name.gsub(repo.working_dir, '')
  https_url += "#L#{start_line}-L#{start_line + code.lines.to_a.size}"

  uri = URI.parse(https_url)
  response = nil
  Net::HTTP.start(uri.host, uri.port, :use_ssl => uri.scheme == 'https') do |http|
    response = http.head(uri.path)
  end

  if response.code == "404"
    https_url = https_url.gsub(repo.commit("HEAD").sha, repo.head.name)
  end

  https_url
end

#method_code_from_head(meth) ⇒ Object



24
25
26
27
28
29
30
31
32
33
# File 'lib/pry-github.rb', line 24

def method_code_from_head(meth)
  code = get_file_from_commit(meth.source_location.first)
  search_line = meth.source.lines.first.strip
  _, start_line = code.lines.to_a.each_with_index.find { |v, i| v.strip == search_line }

  raise "Can't find #{args[0]} in the repo. Perhaps it hasn't been committed yet." unless start_line

  start_line
  [Pry.new(:input => StringIO.new(code.lines.to_a[start_line..-1].join)).r(target), start_line + 1]
end

#relative_path(root, path) ⇒ Object



35
36
37
38
# File 'lib/pry-github.rb', line 35

def relative_path(root, path)
  path =~ /#{root}\/(.*)/
  $1
end