Module: Git::Pr::Release::Util
- Included in:
- CLI, PullRequest, PullRequest
- Defined in:
- lib/git/pr/release/util.rb
Constant Summary collapse
- DEFAULT_PR_TEMPLATE =
First line will be the title of the PR
<<ERB Release <%= Time.now %> <% pull_requests.each do |pr| -%> <%= pr.to_checklist_item %> <% end -%> ERB
Instance Method Summary collapse
- #build_pr_title_and_body(release_pr, merged_prs, changed_files, template_path) ⇒ Object
- #dump_result_as_json(release_pr, merged_prs, changed_files) ⇒ Object
- #git(*command) ⇒ Object
- #git_config(key) ⇒ Object
- #git_config_set(key, value) ⇒ Object
- #host_and_repository_and_scheme ⇒ Object
- #merge_pr_body(old_body, new_body) ⇒ Object
- #obtain_token! ⇒ Object
- #request_authorization(client, two_factor_code) ⇒ Object
- #say(message, level) ⇒ Object
Instance Method Details
#build_pr_title_and_body(release_pr, merged_prs, changed_files, template_path) ⇒ Object
86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
# File 'lib/git/pr/release/util.rb', line 86 def build_pr_title_and_body(release_pr, merged_prs, changed_files, template_path) release_pull_request = target_pull_request = release_pr ? PullRequest.new(release_pr) : DummyPullRequest.new merged_pull_requests = pull_requests = merged_prs.map { |pr| PullRequest.new(pr) } template = if template_path template_fullpath = File.join(git('rev-parse', '--show-toplevel').first.chomp, template_path) File.read(template_fullpath) else DEFAULT_PR_TEMPLATE end erb = if RUBY_VERSION >= '2.6' ERB.new template, trim_mode: '-' else ERB.new template, nil, '-' end content = erb.result binding content.split(/\n/, 2) end |
#dump_result_as_json(release_pr, merged_prs, changed_files) ⇒ Object
106 107 108 109 110 111 112 |
# File 'lib/git/pr/release/util.rb', line 106 def dump_result_as_json(release_pr, merged_prs, changed_files) puts( { :release_pull_request => (release_pr ? PullRequest.new(release_pr) : DummyPullRequest.new).to_hash, :merged_pull_requests => merged_prs.map { |pr| PullRequest.new(pr).to_hash }, :changed_files => changed_files.map { |file| file.to_hash } }.to_json ) end |
#git(*command) ⇒ Object
48 49 50 51 52 53 54 55 56 |
# File 'lib/git/pr/release/util.rb', line 48 def git(*command) command = [ 'git', *command.map(&:to_s) ] say "Executing `#{command.join(' ')}`", :trace out, status = Open3.capture2(*command) unless status.success? raise "Executing `#{command.join(' ')}` failed: #{status}" end out.each_line end |
#git_config(key) ⇒ Object
58 59 60 61 62 63 64 65 66 67 68 69 |
# File 'lib/git/pr/release/util.rb', line 58 def git_config(key) host, _ = host_and_repository_and_scheme() plain_key = [ 'pr-release', key ].join('.') host_aware_key = [ 'pr-release', host, key ].compact.join('.') begin git(:config, '-f', '.git-pr-release', plain_key).first.chomp rescue git(:config, host_aware_key).first.chomp rescue nil end end |
#git_config_set(key, value) ⇒ Object
71 72 73 74 75 76 |
# File 'lib/git/pr/release/util.rb', line 71 def git_config_set(key, value) host, _ = host_and_repository_and_scheme() host_aware_key = [ 'pr-release', host, key ].compact.join('.') git :config, '--global', host_aware_key, value end |
#host_and_repository_and_scheme ⇒ Object
12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
# File 'lib/git/pr/release/util.rb', line 12 def host_and_repository_and_scheme @host_and_repository_and_scheme ||= begin remote = git(:config, 'remote.origin.url').first.chomp unless %r(^\w+://) === remote remote = "ssh://#{remote.sub(':', '/')}" end remote_url = URI.parse(remote) repository = remote_url.path.sub(%r(^/), '').sub(/\.git$/, '') host = remote_url.host == 'github.com' ? nil : remote_url.host [ host, repository, remote_url.scheme === 'http' ? 'http' : 'https' ] end end |
#merge_pr_body(old_body, new_body) ⇒ Object
114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 |
# File 'lib/git/pr/release/util.rb', line 114 def merge_pr_body(old_body, new_body) # Try to take over checklist statuses pr_body_lines = [] check_status = {} old_body.split(/\r?\n/).each { |line| line.match(/^- \[(?<check_value>[ x])\] #(?<issue_number>\d+)/) { |m| say "Found pull-request checkbox \##{m[:issue_number]} is #{m[:check_value]}.", :trace check_status[m[:issue_number]] = m[:check_value] } } old_body_unchecked = old_body.gsub /^- \[[ x]\] \#(\d+)/, '- [ ] #\1' Diff::LCS.traverse_balanced(old_body_unchecked.split(/\r?\n/), new_body.split(/\r?\n/)) do |event| say "diff: #{event.inspect}", :trace action, old, new = *event old_nr, old_line = *old new_nr, new_line = *new case action when '=', '+' say "Use line as is: #{new_line}", :trace pr_body_lines << new_line when '-' say "Use old line: #{old_line}", :trace pr_body_lines << old_line when '!' if [ old_line, new_line ].all? { |line| /^- \[ \]/ === line } say "Found checklist diff; use old one: #{old_line}", :trace pr_body_lines << old_line else # not a checklist diff, use both line say "Use line as is: #{old_line}", :trace pr_body_lines << old_line say "Use line as is: #{new_line}", :trace pr_body_lines << new_line end else say "Unknown diff event: #{event}", :warn end end merged_body = pr_body_lines.join("\n") check_status.each { |issue_number, check_value| say "Update pull-request checkbox \##{issue_number} to #{check_value}.", :trace merged_body.gsub! /^- \[ \] \##{issue_number}/, "- [#{check_value}] \##{issue_number}" } merged_body end |
#obtain_token! ⇒ Object
166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 |
# File 'lib/git/pr/release/util.rb', line 166 def obtain_token! token = ENV.fetch('GIT_PR_RELEASE_TOKEN') { git_config('token') } unless token require 'highline/import' STDERR.puts 'Could not obtain GitHub API token.' STDERR.puts 'Trying to generate token...' username = ask('username? ') { |q| q.default = ENV['USER'] } password = ask('password? (not saved) ') { |q| q.echo = '*' } temporary_client = Octokit::Client.new :login => username, :password => password auth = (temporary_client, nil) token = auth.token git_config_set 'token', token end token end |
#request_authorization(client, two_factor_code) ⇒ Object
188 189 190 191 192 193 194 195 196 197 198 199 200 201 |
# File 'lib/git/pr/release/util.rb', line 188 def (client, two_factor_code) params = { :scopes => [ 'public_repo', 'repo' ], :note => 'git-pr-release' } params[:headers] = { "X-GitHub-OTP" => two_factor_code} if two_factor_code auth = nil begin auth = client.(params) rescue Octokit::OneTimePasswordRequired two_factor_code = ask('two-factor authentication code? ') auth = (client, two_factor_code) end auth end |
#say(message, level) ⇒ Object
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
# File 'lib/git/pr/release/util.rb', line 27 def say(, level) color = case level when :trace return unless ENV['DEBUG'] nil when :debug return unless ENV['DEBUG'] :blue when :info :green when :notice :yellow when :warn :magenta when :error :red end STDERR.puts .colorize(color) end |