diff options
Diffstat (limited to 'app/models/changeset.rb')
-rw-r--r-- | app/models/changeset.rb | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/app/models/changeset.rb b/app/models/changeset.rb index 00775f337..824fa12f5 100644 --- a/app/models/changeset.rb +++ b/app/models/changeset.rb @@ -18,6 +18,7 @@ class Changeset < ActiveRecord::Base belongs_to :repository has_many :changes, :dependent => :delete_all + has_and_belongs_to_many :issues validates_presence_of :repository_id, :revision, :committed_on, :commit_date validates_numericality_of :revision, :only_integer => true @@ -27,4 +28,41 @@ class Changeset < ActiveRecord::Base self.commit_date = date super end + + def after_create + scan_comment_for_issue_ids + end + + def scan_comment_for_issue_ids + return if comment.blank? + # keywords used to reference issues + ref_keywords = Setting.commit_ref_keywords.downcase.split(",") + # keywords used to fix issues + fix_keywords = Setting.commit_fix_keywords.downcase.split(",") + # status applied + fix_status = IssueStatus.find_by_id(Setting.commit_fix_status_id) + + kw_regexp = (ref_keywords + fix_keywords).collect{|kw| Regexp.escape(kw.strip)}.join("|") + return if kw_regexp.blank? + + # remove any associated issues + self.issues.clear + + comment.scan(Regexp.new("(#{kw_regexp})[\s:]+(([\s,;&]*#?\\d+)+)", Regexp::IGNORECASE)).each do |match| + action = match[0] + target_issue_ids = match[1].scan(/\d+/) + target_issues = repository.project.issues.find_all_by_id(target_issue_ids) + if fix_status && fix_keywords.include?(action.downcase) + # update status of issues + logger.debug "Issues fixed by changeset #{self.revision}: #{issue_ids.join(', ')}." if logger && logger.debug? + target_issues.each do |issue| + # don't change the status is the issue is already closed + next if issue.status.is_closed? + issue.status = fix_status + issue.save + end + end + self.issues << target_issues + end + end end |