merge_request.rb 2.98 KB
Newer Older
1
2
require File.join(Rails.root, "app/models/commit")

Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
3
4
5
6
class MergeRequest < ActiveRecord::Base
  belongs_to :project
  belongs_to :author, :class_name => "User"
  belongs_to :assignee, :class_name => "User"
7
  has_many :notes, :as => :noteable, :dependent => :destroy
Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
8

9
10
11
  serialize :st_commits
  serialize :st_diffs

Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
12
  attr_protected :author, :author_id, :project, :project_id
13
  attr_accessor :author_id_of_changes
Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
14
15
16
17
18
19

  validates_presence_of :project_id
  validates_presence_of :assignee_id
  validates_presence_of :author_id
  validates_presence_of :source_branch
  validates_presence_of :target_branch
20
  validate :validate_branches
Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39

  delegate :name,
           :email,
           :to => :author,
           :prefix => true

  delegate :name,
           :email,
           :to => :assignee,
           :prefix => true

  validates :title,
            :presence => true,
            :length   => { :within => 0..255 }

  scope :opened, where(:closed => false)
  scope :closed, where(:closed => true)
  scope :assigned, lambda { |u| where(:assignee_id => u.id)}

40
41
42
43
  def self.search query
    where("title like :query", :query => "%#{query}%")
  end

44
  def validate_branches
45
    if target_branch == source_branch
46
47
48
49
      errors.add :base, "You can not use same branch for source and target branches"
    end
  end

Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
50
51
52
  def new?
    today? && created_at == updated_at
  end
Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
53
54

  def diffs
55
56
57
58
59
60
61
62
63
64
65
66
    st_diffs || []
  end

  def reloaded_diffs
    if open? && unmerged_diffs.any?
      self.st_diffs = unmerged_diffs
      save
    end
    diffs
  end

  def unmerged_diffs
Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
67
    commits = project.repo.commits_between(target_branch, source_branch).map {|c| Commit.new(c)}
68
    diffs = project.repo.diff(commits.first.prev_commit.id, commits.last.id) rescue []
Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
69
70
71
  end

  def last_commit
72
    commits.first
Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
73
  end
74

Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
75
76
77
78
  def merge_event
    self.project.events.where(:target_id => self.id, :target_type => "MergeRequest", :action => Event::Merged).last
  end

79
80
81
82
  # Return the number of +1 comments (upvotes)
  def upvotes
    notes.select(&:upvote?).size
  end
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117

  def commits
    st_commits || []
  end

  def probably_merged?
    unmerged_commits.empty? && 
      commits.any? && open?
  end

  def open?
    !closed
  end

  def mark_as_merged!
    self.merged = true
    self.closed = true
    save
  end

  def reloaded_commits 
    if open? && unmerged_commits.any? 
      self.st_commits = unmerged_commits
      save
    end
    commits
  end

  def unmerged_commits
    self.project.repo.
      commits_between(self.target_branch, self.source_branch).
      map {|c| Commit.new(c)}.
      sort_by(&:created_at).
      reverse
  end
Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
118
end
Valery Sizov's avatar
Valery Sizov committed
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
# == Schema Information
#
# Table name: merge_requests
#
#  id            :integer         not null, primary key
#  target_branch :string(255)     not null
#  source_branch :string(255)     not null
#  project_id    :integer         not null
#  author_id     :integer
#  assignee_id   :integer
#  title         :string(255)
#  closed        :boolean         default(FALSE), not null
#  created_at    :datetime
#  updated_at    :datetime
#