Index: app/models/changeset.rb =================================================================== --- app/models/changeset.rb (revision 6453) +++ app/models/changeset.rb (working copy) @@ -91,17 +91,19 @@ end TIMELOG_RE = / - ( - ((\d+)(h|hours?))((\d+)(m|min)?)? + (?: + (?:\d+(?:h|hours?))(?:\d+(?:m|min)?)? | - ((\d+)(h|hours?|m|min)) + (?:\d+(?:h|hours?|m|min)) | - (\d+):(\d+) + \d+:\d+ | - (\d+([\.,]\d+)?)h? + (?:\d+(?:[\.,]\d+)?)h? ) /x + DONE_RE = /\d0%/ + def scan_comment_for_issue_ids return if comments.blank? # keywords used to reference issues @@ -114,15 +116,19 @@ referenced_issues = [] - comments.scan(/([\s\(\[,-]|^)((#{kw_regexp})[\s:]+)?(#\d+(\s+@#{TIMELOG_RE})?([\s,;&]+#\d+(\s+@#{TIMELOG_RE})?)*)(?=[[:punct:]]|\s|<|$)/i) do |match| - action, refs = match[2], match[3] + comments.scan(/(?:[\s\(\[,-]|^)(?:(#{kw_regexp})[\s:]+)?(#\d+(?:\s+@#{DONE_RE})?(?:\s+@#{TIMELOG_RE})?(?:[\s,;&]+#\d+(?:\s+@#{DONE_RE})?(?:\s+@#{TIMELOG_RE})?)*)(?=[[:punct:]]|\s|<|$)/i) do |match| + action, refs = match[0], match[1] next unless action.present? || ref_keywords_any - refs.scan(/#(\d+)(\s+@#{TIMELOG_RE})?/).each do |m| - issue, hours = find_referenced_issue_by_id(m[0].to_i), m[2] + refs.scan(/#(\d+)(?:\s+@(#{DONE_RE}))?(?:\s+@(#{TIMELOG_RE}))?/).each do |m| + issue, done_ratio, hours = find_referenced_issue_by_id(m[0].to_i), m[1], m[2] if issue referenced_issues << issue - fix_issue(issue) if fix_keywords.include?(action.to_s.downcase) + if fix_keywords.include?(action.to_s.downcase) + fix_issue(issue) + elsif done_ratio.present? + update_issue(issue, done_ratio.sub(/[^\d]+/,'').to_i, comments) + end log_time(issue, hours) if hours && Setting.commit_logtime_enabled? end end @@ -215,6 +221,31 @@ issue end + def update_issue(issue, done_ratio, notes) + status = 8 # "In Progress" - TODO make this configurable + #status = IssueStatus.find_by_id(Setting.commit_progress_status_id.to_i) + if status.nil? + logger.warn("No status macthes commit_progress_status_id setting (#{Setting.commit_progress_status_id})") if logger + return issue + end + + # the issue may have been updated by the closure of another one (eg. duplicate) + issue.reload + # don't change the status is the issue is closed + return if issue.status && issue.status.is_closed? + + notes = ll(Setting.default_language, :text_status_changed_by_changeset, text_tag) + "\n\n" + notes + journal = issue.init_journal(user || User.anonymous, notes) + issue.status = status + issue.done_ratio = done_ratio + Redmine::Hook.call_hook(:model_changeset_scan_commit_for_issue_ids_pre_issue_update, + { :changeset => self, :issue => issue }) + unless issue.save + logger.warn("Issue ##{issue.id} could not be saved by changeset #{id}: #{issue.errors.full_messages}") if logger + end + issue + end + def log_time(issue, hours) time_entry = TimeEntry.new( :user => user,