Skip to content

Instantly share code, notes, and snippets.

@dux
Last active March 2, 2022 19:06
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save dux/2012441c075ac4d0a2fa08dfedf34aa8 to your computer and use it in GitHub Desktop.
Save dux/2012441c075ac4d0a2fa08dfedf34aa8 to your computer and use it in GitHub Desktop.
prepares github pull request with full clean view of the selected files
#!/usr/bin/env ruby
# prepares github pull request with full clean view of the selected files
# to run it
# * delete some files after commit that is pushed, and leave them unstaged
# * pull-request-prepare.rb will
# * create branch-review-start with all marked files deleted
# * create branch-review-end with all marked files re-added
# * leave starting branch untouched
# * open github url for pull request
require 'slop'
require 'colorize'
module Sys
extend self
def die data=nil
puts data.red if data
yield if block_given?
exit
end
def run command
puts command.blue
system "#{command} 2>&1"
end
def open command
system "open '%s'" % command
end
end
class PullRequest
def initialize(opts)
# define vars
@opts = opts
@files = `git ls-files -m`.chomp.split($/)
@current_branch = `git rev-parse --abbrev-ref HEAD`.to_s.chomp.sub(/\*\s/,'')
@currenct_hash = `git rev-parse HEAD`.chomp
@branch_suffix = opts[:hash] ? @currenct_hash[0,7] : @current_branch
@review_branch_start = 'review-%s-start' % @branch_suffix
@review_branch_end = 'review-%s-end' % @branch_suffix
end
def clean_branches
Sys.run 'git push origin --delete %s' % @review_branch_start
Sys.run 'git push origin --delete %s' % @review_branch_end
Sys.run 'git branch -D %s' % @review_branch_start
Sys.run 'git branch -D %s' % @review_branch_end
end
def execute
if @opts[:execute]
Sys.die 'To define files that need review, delete or modify them.' if @files.length == 0
# can't be in review branch when executing
Sys.die 'Current branch cant be review branch (%s)' % @current_branch if @current_branch.index('-review')
prepare
prepare_start_branch
prepare_end_branch
push_and_finish
elsif [:update]
# git diff review-master-start..review-master-end --name-only
end
end
def prepare
# revert to state before deletion of files and prepare branches
Sys.run 'git reset --mixed'
clean_branches
end
def prepare_start_branch
Sys.run 'git checkout -b %s' % @review_branch_start
# remove files in start review branch
@files.each { |file| Sys.run 'rm %s' % file }
# and commit changes
Sys.run "git add -A && git commit -m 'review start'"
end
def prepare_end_branch
Sys.run 'git checkout -b %s' % @review_branch_end
# re-add files in end review branch
@files.each { |file| Sys.run "git checkout %s '%s'" % [@current_branch, file] }
Sys.run "git add -A && git commit -m 'review end for %d files'" % @files.length
end
def push_and_finish
Sys.run 'git checkout %s' % @current_branch
Sys.run 'git push origin %s' % @review_branch_start
Sys.run 'git push origin %s' % @review_branch_end
Sys.run 'git reset %s --hard' % @currenct_hash
end
def open_url
url_parts = `git remote -v | grep origin`.split(/[\s:]/)
domain = url_parts[1].split('@').last
path = url_parts[2].sub('.git', '')
case domain
when 'bitbucket.org'
Sys.open 'https://bitbucket.org/dino_reic/raum-dog/pull-requests/new?source=%s&t=1#diff' % @review_branch_end
when 'github.com'
Sys.open 'https://github.com/%s/compare/%s...%s' % [path, @review_branch_start, @review_branch_end]
else
Sys.die 'Unsuported url for domain %s' % domain
end
end
end
###
opts = Slop.parse do |o|
o.bool '-x', '--execute', 'execute the creation of pull request'
o.bool '-u', '--update', 'update end branch with changed files'
o.bool '-c', '--clean', 'clean all branches and exit'
o.bool '-h', '--hash', 'hash branch name to make it unique'
o.bool '-o', '--open', 'open github url'
end
Sys.die { puts opts } unless ARGV[0]
pr = PullRequest.new opts
opts.clean? && Sys.die { pr.clean_branches }
pr.execute if opts.execute? || opts.update?
opts.open? && pr.open_url
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment