Module: Commiti::PrOpener

Extended by:
PrRemoteParser
Defined in:
lib/services/git/pr/pr_opener.rb

Constant Summary collapse

SCP_REMOTE =
%r{\A(?<user>[^@]+)@(?<host>[^:\s/]+):(?<path>[^\s]+)\z}
MAX_PREFILLED_URL_LENGTH =
1800
MAX_PREFILLED_TITLE_LENGTH =
120

Class Method Summary collapse

Methods included from PrRemoteParser

extract_remote_info

Class Method Details

.compare_url(origin_url:, base_branch:, head_branch:, title:, body:) ⇒ Object



15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# File 'lib/services/git/pr/pr_opener.rb', line 15

def self.compare_url(origin_url:, base_branch:, head_branch:, title:, body:)
  remote = extract_remote_info(origin_url)
  raise 'Supported providers for browser PR opening are GitHub, GitLab, and GitBucket.' if remote.nil?

  compare_url_candidates(
    remote: remote,
    base_branch: base_branch,
    head_branch: head_branch,
    title: title,
    body: body
  ).find { |url| url.length <= MAX_PREFILLED_URL_LENGTH } || compare_url_candidates(
    remote: remote,
    base_branch: base_branch,
    head_branch: head_branch,
    title: title,
    body: body
  ).last
end

.encode_branch_for_path(branch) ⇒ Object



194
195
196
# File 'lib/services/git/pr/pr_opener.rb', line 194

def self.encode_branch_for_path(branch)
  URI.encode_www_form_component(branch.to_s).gsub('+', '%20')
end

.extract_owner_repo(origin_url) ⇒ Object



221
222
223
224
225
226
# File 'lib/services/git/pr/pr_opener.rb', line 221

def self.extract_owner_repo(origin_url)
  info = extract_remote_info(origin_url)
  return nil if info.nil?

  { owner: info[:namespace], repo: info[:repo] }
end

.github_like_compare_url(remote:, base_branch:, head_branch:, title:, body:, include_title: true, include_body: true) ⇒ Object



153
154
155
156
157
158
159
160
161
162
163
164
165
166
# File 'lib/services/git/pr/pr_opener.rb', line 153

def self.github_like_compare_url(remote:, base_branch:, head_branch:, title:, body:, include_title: true, include_body: true)
  query_params = {
    github_compare_prefill_param(remote[:provider]) => '1'
  }
  normalized_title = normalize_title(title)
  query_params['title'] = normalized_title if include_title && !normalized_title.empty?
  query_params['body'] = body.to_s if include_body && !body.to_s.empty?
  query = URI.encode_www_form(query_params)

  base = "#{remote[:web_scheme]}://#{remote[:host]}"
  path = "#{remote[:namespace]}/#{remote[:repo]}"

  "#{base}/#{path}/compare/#{encode_branch_for_path(base_branch)}...#{encode_branch_for_path(head_branch)}?#{query}"
end

.gitlab_mr_url(remote:, base_branch:, head_branch:, title:, body:, include_title: true, include_description: true) ⇒ Object



173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
# File 'lib/services/git/pr/pr_opener.rb', line 173

def self.gitlab_mr_url(remote:, base_branch:, head_branch:, title:, body:, include_title: true, include_description: true)
  query_params = {
    'merge_request[source_branch]' => head_branch,
    'merge_request[target_branch]' => base_branch
  }
  normalized_title = normalize_title(title)
  query_params['merge_request[title]'] = normalized_title if include_title && !normalized_title.empty?
  query_params['merge_request[description]'] = body.to_s if include_description && !body.to_s.empty?
  query = URI.encode_www_form(query_params)

  base = "#{remote[:web_scheme]}://#{remote[:host]}"
  path = "#{remote[:namespace]}/#{remote[:repo]}"

  "#{base}/#{path}/-/merge_requests/new?#{query}"
end

.open_in_browser(url) ⇒ Object



217
218
219
# File 'lib/services/git/pr/pr_opener.rb', line 217

def self.open_in_browser(url)
  Commiti::PrBrowserOpener.open_in_browser(url)
end

.suggest_title(pr_body, head_branch:) ⇒ Object



198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
# File 'lib/services/git/pr/pr_opener.rb', line 198

def self.suggest_title(pr_body, head_branch:)
  in_summary = false
  pr_body.to_s.each_line do |line|
    stripped = line.strip
    if stripped == '## Summary'
      in_summary = true
      next
    end

    break if in_summary && stripped.start_with?('## ')
    next unless in_summary
    next if stripped.empty? || stripped.start_with?('-', '*')

    return stripped[0, 72]
  end

  "Update #{head_branch}"
end