Class: GitReview

Inherits:
Object
  • Object
show all
Defined in:
lib/git-review.rb

Instance Method Summary collapse

Instance Method Details

#browseObject

Open a browser window and review a specified request.



57
58
59
# File 'lib/git-review.rb', line 57

def browse
  Launchy.open(@pending_request['html_url']) if request_exists?
end

#checkoutObject

Checkout a specified request’s changes to your local repository.



62
63
64
65
66
67
68
69
70
71
# File 'lib/git-review.rb', line 62

def checkout
  return unless request_exists?
  create_local_branch = @args.shift == '--branch' ? '' : 'origin/'
  puts 'Checking out changes to your local repository.'
  puts 'To get back to your original state, just run:'
  puts
  puts '  git checkout master'
  puts
  git_call "checkout #{create_local_branch}#{@pending_request['head']['ref']}"
end

#closeObject

Close a specified request.



102
103
104
105
106
# File 'lib/git-review.rb', line 102

def close
  return unless request_exists?
  Octokit.post("issues/close/#{source_repo}/#{@pending_request['number']}")
  puts 'Successfully closed request.' unless request_exists?(@pending_request['number'])
end

#consoleObject

Start a console session (used for debugging).



162
163
164
165
166
167
168
169
# File 'lib/git-review.rb', line 162

def console
  puts 'Entering debug console.'
  request_exists?
  require 'ruby-debug'
  Debugger.start
  debugger
  puts 'Leaving debug console.'
end

#createObject

Create a new request. TODO: Support creating requests to other repositories and branches (like the original repo, this has been forked from).



136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
# File 'lib/git-review.rb', line 136

def create
  # Prepare @local_branch.
  prepare
  unless git_call("cherry #{target_branch}").empty?
    # Push latest commits to the remote branch (and by that, create it if necessary).
    git_call "push --set-upstream origin #{@local_branch}"
    # Gather information.
    last_request_id = @pending_requests.collect{|req| req['number'] }.sort.last.to_i
    title = "[Review] Request from '#{git_config['github.login']}' @ '#{source}'"
    # TODO: Insert commit messages (that are not yet in master) into body (since this will be displayed inside the mail that is sent out).
    body = 'Please review the following changes:'
    # Create the actual pull request.
    Octokit.create_pull_request(target_repo, target_branch, source_branch, title, body)
    # Switch back to target_branch and check for success.
    git_call "checkout #{target_branch}"
    update
    potential_new_request = @pending_requests.find{ |req| req['title'] == title }
    if potential_new_request and potential_new_request['number'] > last_request_id
      puts 'Successfully created new request.'
    end
  else
    "Nothing to push to remote yet. Commit something first."
  end
end

#listObject

List all pending requests.



13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# File 'lib/git-review.rb', line 13

def list
  @pending_requests.reverse! if @args.shift == '--reverse'
  output = @pending_requests.collect do |pending_request|
    # Find only pending (= unmerged) requests and output summary. GitHub might
    # still think of them as pending, as it doesn't know about local changes.
    next if merged?(pending_request['head']['sha'])
    line = format_text(pending_request['number'], 8)
    date_string = format_time(pending_request['updated_at'])
    line << format_text(date_string, 11)
    line << format_text(pending_request['comments'], 10)
    line << format_text(pending_request['title'], 91)
    line
  end
  if output.compact.empty?
    puts "No pending requests for '#{source}'"
    return
  end
  puts "Pending requests for '#{source}'"
  puts 'ID      Updated    Comments  Title'
  puts output.compact
end

#mergeObject

Accept a specified request by merging it into master.



74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
# File 'lib/git-review.rb', line 74

def merge
  return unless request_exists?
  option = @args.shift
  unless @pending_request['head']['repository']
    # Someone deleted the source repo.
    user = @pending_request['head']['user']['login']
    url = @pending_request['patch_url']
    puts "Sorry, #{user} deleted the source repository, git-review doesn't support this."
    puts 'You can manually patch your repo by running:'
    puts
    puts "  curl #{url} | git am"
    puts
    puts 'Tell the contributor not to do this.'
    return false
  end
  message = "Accept request ##{@pending_request['number']} and merge changes into \"#{target}\""
  exec_cmd = "merge #{option} -m '#{message}' #{@pending_request['head']['sha']}"
  puts
  puts 'Request title:'
  puts "  #{@pending_request['title']}"
  puts
  puts 'Merge command:'
  puts "  git #{exec_cmd}"
  puts
  puts git_call(exec_cmd)
end

#prepareObject

Prepare local repository to create a new request. Sets @local_branch.



110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
# File 'lib/git-review.rb', line 110

def prepare
  # People should work on local branches, but especially for single commit changes,
  # more often than not, they don't. Therefore we create a branch for them,
  # to be able to use code review the way it is intended.
  if source_branch == target_branch
    # Unless a branch name is already provided, ask for one.
    if (branch_name = @args.shift).nil?
      puts 'Please provide a name for the branch:'
      branch_name = gets.chomp.gsub(/\W+/, '_').downcase
    end
    # Create the new branch (as a copy of the current one).
    @local_branch = "review_#{Time.now.strftime("%y%m%d")}_#{branch_name}"
    git_call "checkout -b #{@local_branch}"
    if source_branch == @local_branch
      # Go back to master and get rid of pending commits (as these are now on the new branch).
      git_call "checkout #{target_branch}"
      git_call "reset --hard origin/#{target_branch}"
      git_call "checkout #{@local_branch}"
    end
  else
    @local_branch = source_branch
  end
end

#showObject

Show details for a single request.



36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/git-review.rb', line 36

def show
  return unless request_exists?
  option = @args.shift == '--full' ? '' : '--stat '
  sha = @pending_request['head']['sha']
  puts "ID        : #{@pending_request['number']}"
  puts "Label     : #{@pending_request['head']['label']}"
  puts "Updated   : #{format_time(@pending_request['updated_at'])}"
  puts "Comments  : #{@pending_request['comments']}"
  puts
  puts @pending_request['title']
  puts
  puts @pending_request['body']
  puts
  puts git_call("diff --color=always #{option}HEAD...#{sha}")
  puts
  puts "Progress  :"
  puts
  discussion
end