##// END OF EJS Templates
scm: use #blank? instead of #nil? || #empty? at Repository#find_changeset_by_name(name) (#7307)....
Toshi MARUYAMA -
r4592:acb0d9661739
parent child
Show More
@@ -1,223 +1,223
1 1 # redMine - project management software
2 2 # Copyright (C) 2006-2007 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 class Repository < ActiveRecord::Base
19 19 belongs_to :project
20 20 has_many :changesets, :order => "#{Changeset.table_name}.committed_on DESC, #{Changeset.table_name}.id DESC"
21 21 has_many :changes, :through => :changesets
22 22
23 23 # Raw SQL to delete changesets and changes in the database
24 24 # has_many :changesets, :dependent => :destroy is too slow for big repositories
25 25 before_destroy :clear_changesets
26 26
27 27 # Checks if the SCM is enabled when creating a repository
28 28 validate_on_create { |r| r.errors.add(:type, :invalid) unless Setting.enabled_scm.include?(r.class.name.demodulize) }
29 29
30 30 # Removes leading and trailing whitespace
31 31 def url=(arg)
32 32 write_attribute(:url, arg ? arg.to_s.strip : nil)
33 33 end
34 34
35 35 # Removes leading and trailing whitespace
36 36 def root_url=(arg)
37 37 write_attribute(:root_url, arg ? arg.to_s.strip : nil)
38 38 end
39 39
40 40 def scm
41 41 @scm ||= self.scm_adapter.new url, root_url, login, password
42 42 update_attribute(:root_url, @scm.root_url) if root_url.blank?
43 43 @scm
44 44 end
45 45
46 46 def scm_name
47 47 self.class.scm_name
48 48 end
49 49
50 50 def supports_cat?
51 51 scm.supports_cat?
52 52 end
53 53
54 54 def supports_annotate?
55 55 scm.supports_annotate?
56 56 end
57 57
58 58 def entry(path=nil, identifier=nil)
59 59 scm.entry(path, identifier)
60 60 end
61 61
62 62 def entries(path=nil, identifier=nil)
63 63 scm.entries(path, identifier)
64 64 end
65 65
66 66 def branches
67 67 scm.branches
68 68 end
69 69
70 70 def tags
71 71 scm.tags
72 72 end
73 73
74 74 def default_branch
75 75 scm.default_branch
76 76 end
77 77
78 78 def properties(path, identifier=nil)
79 79 scm.properties(path, identifier)
80 80 end
81 81
82 82 def cat(path, identifier=nil)
83 83 scm.cat(path, identifier)
84 84 end
85 85
86 86 def diff(path, rev, rev_to)
87 87 scm.diff(path, rev, rev_to)
88 88 end
89 89
90 90 def diff_format_revisions(cs, cs_to, sep=':')
91 91 text = ""
92 92 text << cs_to.format_identifier + sep if cs_to
93 93 text << cs.format_identifier if cs
94 94 text
95 95 end
96 96
97 97 # Returns a path relative to the url of the repository
98 98 def relative_path(path)
99 99 path
100 100 end
101
101
102 102 # Finds and returns a revision with a number or the beginning of a hash
103 103 def find_changeset_by_name(name)
104 return nil if name.nil? || name.empty?
104 return nil if name.blank?
105 105 changesets.find(:first, :conditions => (name.match(/^\d*$/) ? ["revision = ?", name.to_s] : ["revision LIKE ?", name + '%']))
106 106 end
107
107
108 108 def latest_changeset
109 109 @latest_changeset ||= changesets.find(:first)
110 110 end
111 111
112 112 # Returns the latest changesets for +path+
113 113 # Default behaviour is to search in cached changesets
114 114 def latest_changesets(path, rev, limit=10)
115 115 if path.blank?
116 116 changesets.find(:all, :include => :user,
117 117 :order => "#{Changeset.table_name}.committed_on DESC, #{Changeset.table_name}.id DESC",
118 118 :limit => limit)
119 119 else
120 120 changes.find(:all, :include => {:changeset => :user},
121 121 :conditions => ["path = ?", path.with_leading_slash],
122 122 :order => "#{Changeset.table_name}.committed_on DESC, #{Changeset.table_name}.id DESC",
123 123 :limit => limit).collect(&:changeset)
124 124 end
125 125 end
126 126
127 127 def scan_changesets_for_issue_ids
128 128 self.changesets.each(&:scan_comment_for_issue_ids)
129 129 end
130 130
131 131 # Returns an array of committers usernames and associated user_id
132 132 def committers
133 133 @committers ||= Changeset.connection.select_rows("SELECT DISTINCT committer, user_id FROM #{Changeset.table_name} WHERE repository_id = #{id}")
134 134 end
135 135
136 136 # Maps committers username to a user ids
137 137 def committer_ids=(h)
138 138 if h.is_a?(Hash)
139 139 committers.each do |committer, user_id|
140 140 new_user_id = h[committer]
141 141 if new_user_id && (new_user_id.to_i != user_id.to_i)
142 142 new_user_id = (new_user_id.to_i > 0 ? new_user_id.to_i : nil)
143 143 Changeset.update_all("user_id = #{ new_user_id.nil? ? 'NULL' : new_user_id }", ["repository_id = ? AND committer = ?", id, committer])
144 144 end
145 145 end
146 146 @committers = nil
147 147 @found_committer_users = nil
148 148 true
149 149 else
150 150 false
151 151 end
152 152 end
153 153
154 154 # Returns the Redmine User corresponding to the given +committer+
155 155 # It will return nil if the committer is not yet mapped and if no User
156 156 # with the same username or email was found
157 157 def find_committer_user(committer)
158 158 unless committer.blank?
159 159 @found_committer_users ||= {}
160 160 return @found_committer_users[committer] if @found_committer_users.has_key?(committer)
161 161
162 162 user = nil
163 163 c = changesets.find(:first, :conditions => {:committer => committer}, :include => :user)
164 164 if c && c.user
165 165 user = c.user
166 166 elsif committer.strip =~ /^([^<]+)(<(.*)>)?$/
167 167 username, email = $1.strip, $3
168 168 u = User.find_by_login(username)
169 169 u ||= User.find_by_mail(email) unless email.blank?
170 170 user = u
171 171 end
172 172 @found_committer_users[committer] = user
173 173 user
174 174 end
175 175 end
176 176
177 177 # Fetches new changesets for all repositories of active projects
178 178 # Can be called periodically by an external script
179 179 # eg. ruby script/runner "Repository.fetch_changesets"
180 180 def self.fetch_changesets
181 181 Project.active.has_module(:repository).find(:all, :include => :repository).each do |project|
182 182 if project.repository
183 183 project.repository.fetch_changesets
184 184 end
185 185 end
186 186 end
187 187
188 188 # scan changeset comments to find related and fixed issues for all repositories
189 189 def self.scan_changesets_for_issue_ids
190 190 find(:all).each(&:scan_changesets_for_issue_ids)
191 191 end
192 192
193 193 def self.scm_name
194 194 'Abstract'
195 195 end
196 196
197 197 def self.available_scm
198 198 subclasses.collect {|klass| [klass.scm_name, klass.name]}
199 199 end
200 200
201 201 def self.factory(klass_name, *args)
202 202 klass = "Repository::#{klass_name}".constantize
203 203 klass.new(*args)
204 204 rescue
205 205 nil
206 206 end
207 207
208 208 private
209 209
210 210 def before_save
211 211 # Strips url and root_url
212 212 url.strip!
213 213 root_url.strip!
214 214 true
215 215 end
216 216
217 217 def clear_changesets
218 218 cs, ch, ci = Changeset.table_name, Change.table_name, "#{table_name_prefix}changesets_issues#{table_name_suffix}"
219 219 connection.delete("DELETE FROM #{ch} WHERE #{ch}.changeset_id IN (SELECT #{cs}.id FROM #{cs} WHERE #{cs}.repository_id = #{id})")
220 220 connection.delete("DELETE FROM #{ci} WHERE #{ci}.changeset_id IN (SELECT #{cs}.id FROM #{cs} WHERE #{cs}.repository_id = #{id})")
221 221 connection.delete("DELETE FROM #{cs} WHERE #{cs}.repository_id = #{id}")
222 222 end
223 223 end
General Comments 0
You need to be logged in to leave comments. Login now