Module: RuVim::Gh::Link
- Defined in:
- lib/ruvim/gh/link.rb
Defined Under Namespace
Modules: HandlerMethods
Class Method Summary collapse
-
.build_url(base_url, ref, relative_path, line_start, line_end = nil) ⇒ Object
Build a GitHub blob URL.
-
.file_differs_from_remote?(root, remote_name, branch, file_path) ⇒ Boolean
Check if a file differs from the remote tracking branch.
-
.find_github_remote(root, remote_name = nil) ⇒ Object
Find a GitHub remote.
-
.github_url_from_remote(remote_url) ⇒ Object
Parse a git remote URL and return the GitHub HTTPS base URL.
-
.osc52_copy_sequence(text) ⇒ Object
Generate OSC 52 escape sequence for clipboard copy.
-
.pr_search_url(base_url, branch) ⇒ Object
Build a GitHub PR search URL for a branch.
-
.resolve(file_path, line_start, line_end = nil, remote_name: nil) ⇒ Object
Resolve GitHub link for a file path at given line(s).
-
.resolve_pr(file_path) ⇒ Object
Resolve GitHub PR URL for the current repo.
Class Method Details
.build_url(base_url, ref, relative_path, line_start, line_end = nil) ⇒ Object
Build a GitHub blob URL.
25 26 27 28 29 30 31 32 |
# File 'lib/ruvim/gh/link.rb', line 25 def build_url(base_url, ref, relative_path, line_start, line_end = nil) fragment = if line_end && line_end != line_start "#L#{line_start}-L#{line_end}" else "#L#{line_start}" end "#{base_url}/blob/#{ref}/#{relative_path}#{fragment}" end |
.file_differs_from_remote?(root, remote_name, branch, file_path) ⇒ Boolean
Check if a file differs from the remote tracking branch.
74 75 76 77 78 79 80 81 |
# File 'lib/ruvim/gh/link.rb', line 74 def file_differs_from_remote?(root, remote_name, branch, file_path) remote_ref = "#{remote_name}/#{branch}" diff_out, _, status = Open3.capture3("git", "diff", remote_ref, "--", file_path, chdir: root) # If the remote ref doesn't exist or diff fails, consider it as differing return true unless status.success? !diff_out.empty? end |
.find_github_remote(root, remote_name = nil) ⇒ Object
Find a GitHub remote. If remote_name is given, use that specific remote. Otherwise, scan all remotes (preferring "origin", then "upstream", then others). Returns [remote_name, base_url] or [nil, nil].
43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
# File 'lib/ruvim/gh/link.rb', line 43 def find_github_remote(root, remote_name = nil) if remote_name url, _, status = Open3.capture3("git", "remote", "get-url", remote_name, chdir: root) return [nil, nil] unless status.success? base = github_url_from_remote(url.strip) return base ? [remote_name, base] : [nil, nil] end remotes_out, _, status = Open3.capture3("git", "remote", chdir: root) return [nil, nil] unless status.success? remotes = remotes_out.lines(chomp: true) # Prefer origin, then upstream, then others ordered = [] ordered << "origin" if remotes.include?("origin") ordered << "upstream" if remotes.include?("upstream") remotes.each { |r| ordered << r unless ordered.include?(r) } ordered.each do |name| url, _, st = Open3.capture3("git", "remote", "get-url", name, chdir: root) next unless st.success? base = github_url_from_remote(url.strip) return [name, base] if base end [nil, nil] end |
.github_url_from_remote(remote_url) ⇒ Object
Parse a git remote URL and return the GitHub HTTPS base URL. Returns nil if the remote is not a GitHub URL.
12 13 14 15 16 17 18 19 20 21 22 |
# File 'lib/ruvim/gh/link.rb', line 12 def github_url_from_remote(remote_url) url = remote_url.to_s.strip return nil if url.empty? case url when %r{\Agit@github\.com:(.+?)(?:\.git)?\z} "https://github.com/#{$1}" when %r{\Ahttps://github\.com/(.+?)(?:\.git)?\z} "https://github.com/#{$1}" end end |
.osc52_copy_sequence(text) ⇒ Object
Generate OSC 52 escape sequence for clipboard copy.
35 36 37 38 |
# File 'lib/ruvim/gh/link.rb', line 35 def osc52_copy_sequence(text) encoded = [text].pack("m0") "\e]52;c;#{encoded}\a" end |
.pr_search_url(base_url, branch) ⇒ Object
Build a GitHub PR search URL for a branch.
113 114 115 |
# File 'lib/ruvim/gh/link.rb', line 113 def pr_search_url(base_url, branch) "#{base_url}/pulls?q=head:#{branch}" end |
.resolve(file_path, line_start, line_end = nil, remote_name: nil) ⇒ Object
Resolve GitHub link for a file path at given line(s). Returns [url, warning, error_message].
85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 |
# File 'lib/ruvim/gh/link.rb', line 85 def resolve(file_path, line_start, line_end = nil, remote_name: nil) root, err = RuVim::Git.repo_root(file_path) return [nil, nil, err] unless root found_remote, base_url = find_github_remote(root, remote_name) unless base_url msg = remote_name ? "Remote '#{remote_name}' is not a GitHub remote" : "No GitHub remote found" return [nil, nil, msg] end branch, _, status = Open3.capture3("git", "rev-parse", "--abbrev-ref", "HEAD", chdir: root) unless status.success? return [nil, nil, "Cannot determine branch"] end branch = branch.strip relative_path = file_path.sub(%r{\A#{Regexp.escape(root)}/?}, "") url = build_url(base_url, branch, relative_path, line_start, line_end) warning = nil if file_differs_from_remote?(root, found_remote, branch, file_path) warning = "(remote may differ)" end [url, warning, nil] end |
.resolve_pr(file_path) ⇒ Object
Resolve GitHub PR URL for the current repo. Returns [url, error_message].
119 120 121 122 123 124 125 126 127 128 129 130 |
# File 'lib/ruvim/gh/link.rb', line 119 def resolve_pr(file_path) root, err = RuVim::Git.repo_root(file_path) return [nil, err] unless root _, base_url = find_github_remote(root) return [nil, "No GitHub remote found"] unless base_url branch, _, status = Open3.capture3("git", "rev-parse", "--abbrev-ref", "HEAD", chdir: root) return [nil, "Cannot determine branch"] unless status.success? [pr_search_url(base_url, branch.strip), nil] end |