2012-04-16 19:40:50 +01:00
|
|
|
class PullRequest < Issue
|
2012-04-18 18:08:53 +01:00
|
|
|
extend StateMachine::MacroMethods # no method state_machine WTF?!
|
2012-04-16 19:40:50 +01:00
|
|
|
serialize :data
|
2012-04-18 18:08:53 +01:00
|
|
|
#TODO add validates to serialized data
|
|
|
|
scope :needed_checking, where(:state => ['open', 'blocked', 'ready'])
|
2012-04-16 19:40:50 +01:00
|
|
|
|
|
|
|
state_machine :initial => :open do
|
2012-04-18 18:08:53 +01:00
|
|
|
#after_transition [:ready, :blocked] => [:merged, :closed] do |pull, transition|
|
|
|
|
# FileUtils.rm_rf(pull.path) # What about diff?
|
|
|
|
#end
|
2012-04-16 19:40:50 +01:00
|
|
|
|
2012-04-18 18:08:53 +01:00
|
|
|
event :ready do
|
|
|
|
transition [:open, :blocked] => :ready
|
2012-04-16 19:40:50 +01:00
|
|
|
end
|
|
|
|
|
|
|
|
event :block do
|
2012-04-19 20:08:33 +01:00
|
|
|
transition [:open, :ready] => :blocked
|
2012-04-16 19:40:50 +01:00
|
|
|
end
|
|
|
|
|
2012-04-20 17:23:28 +01:00
|
|
|
event :already do
|
|
|
|
transition [:open, :blocked, :ready] => :already
|
|
|
|
end
|
|
|
|
|
2012-04-18 18:08:53 +01:00
|
|
|
event :merging do
|
|
|
|
transition :ready => :merged
|
2012-04-16 19:40:50 +01:00
|
|
|
end
|
|
|
|
|
|
|
|
event :close do
|
2012-04-18 18:08:53 +01:00
|
|
|
transition [:open, :ready, :blocked] => :closed
|
|
|
|
end
|
|
|
|
|
|
|
|
event :reopen do
|
|
|
|
transition :closed => :open
|
2012-04-16 19:40:50 +01:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def can_merge?
|
2012-04-18 18:08:53 +01:00
|
|
|
state == 'ready'
|
|
|
|
end
|
|
|
|
|
|
|
|
def check
|
2012-04-20 17:23:28 +01:00
|
|
|
ret = merge
|
|
|
|
if ret =~ /Already up-to-date/
|
|
|
|
already
|
|
|
|
elsif ret =~ /Merge made by recursive/
|
2012-04-18 18:08:53 +01:00
|
|
|
system("cd #{path} && git reset --hard HEAD^") # remove merge commit
|
|
|
|
ready
|
|
|
|
else
|
|
|
|
system("cd #{path} && git reset --hard HEAD")
|
|
|
|
block
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def merge!(who)
|
|
|
|
return false unless can_merge?
|
|
|
|
Dir.chdir(path) do
|
2012-04-20 16:17:43 +01:00
|
|
|
system "git config user.name \"#{who.uname}\" && git config user.email \"#{who.email}\""
|
2012-04-18 18:08:53 +01:00
|
|
|
if merge
|
|
|
|
merging
|
|
|
|
system("git push origin HEAD")
|
|
|
|
end
|
|
|
|
end
|
2012-04-16 19:40:50 +01:00
|
|
|
end
|
|
|
|
|
|
|
|
protected
|
|
|
|
|
|
|
|
def path
|
2012-04-18 18:08:53 +01:00
|
|
|
filename = [id, project.owner.uname, project.name].join('-')
|
2012-04-16 19:40:50 +01:00
|
|
|
if Rails.env == "production"
|
2012-04-18 18:08:53 +01:00
|
|
|
File.join('/srv/rosa_build/shared/tmp', "pull_requests", filename)
|
2012-04-16 19:40:50 +01:00
|
|
|
else
|
2012-04-18 18:08:53 +01:00
|
|
|
File.join(Rails.root, "tmp", Rails.env, "pull_requests", filename)
|
2012-04-16 19:40:50 +01:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def merge
|
|
|
|
clone
|
2012-04-20 17:23:28 +01:00
|
|
|
%x(cd #{path} && git checkout #{data[:base_branch]} && git merge --no-ff #{data[:head_branch]}) #FIXME need sanitize branch name!
|
2012-04-16 19:40:50 +01:00
|
|
|
end
|
|
|
|
|
|
|
|
def clone
|
2012-04-18 18:08:53 +01:00
|
|
|
git = Grit::Git.new(path)
|
2012-04-16 19:40:50 +01:00
|
|
|
|
|
|
|
unless git.exist?
|
|
|
|
FileUtils.mkdir_p(path)
|
2012-04-19 20:08:33 +01:00
|
|
|
system("git clone --local --no-hardlinks #{project.path} #{path}")
|
|
|
|
end
|
|
|
|
Dir.chdir(path) do
|
|
|
|
[data[:base_branch], data[:head_branch]].each do |branch|
|
2012-04-20 17:23:28 +01:00
|
|
|
system 'git', 'checkout', branch
|
|
|
|
system 'git', 'pull', 'origin', branch
|
2012-04-16 19:40:50 +01:00
|
|
|
end
|
|
|
|
end
|
|
|
|
# TODO catch errors
|
|
|
|
end
|
|
|
|
|
2012-04-18 18:08:53 +01:00
|
|
|
def set_serial_id
|
|
|
|
self.update_attribute :serial_id, self.project.pull_requests.count
|
|
|
|
end
|
2012-04-16 19:40:50 +01:00
|
|
|
end
|