Class: Commit

Inherits:
ActiveRecord::Base
  • Object
show all
Defined in:
app/models/commit.rb

Constant Summary collapse

TAG_PATTERN =
/^\s*\[([^\]]+)\]\s*/.freeze
TICKET_PATTERN =
/\[#(\d+)([a-z]*)\]/.freeze
TIME_PATTERN =
/\((\d*\.?\d+) ?(h|hrs?|hours?|m|min|minutes?)\)/.freeze
EXTRA_ATTRIBUTE_PATTERN =
/\{\{([^:\}]+):[ \s]*([^\}]+)\}\}/.freeze
MERGE_COMMIT_PATTERN =
/^Merge\b/.freeze

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.attributes_from_native_commit(native) ⇒ Object



76
77
78
79
80
81
82
83
# File 'app/models/commit.rb', line 76

def self.attributes_from_native_commit(native)
  { :sha => native.sha,
    :parent_sha => native.parent_sha,
    :message => native.message.to_s.strip,
    :authored_at => native.authored_at,
    :committer => native.author_name,
    :committer_email => native.author_email.to_s.downcase }
end

.during(range) ⇒ Object



38
39
40
# File 'app/models/commit.rb', line 38

def during(range)
  where(authored_at: range)
end

.earliestObject



50
51
52
# File 'app/models/commit.rb', line 50

def earliest
  first
end

.find_by_sha(sha) ⇒ Object



30
31
32
# File 'app/models/commit.rb', line 30

def find_by_sha(sha)
  with_sha_like(sha).first if sha
end

.from_native_commit(native) ⇒ Object



72
73
74
# File 'app/models/commit.rb', line 72

def self.from_native_commit(native)
  new attributes_from_native_commit(native)
end

.latestObject



46
47
48
# File 'app/models/commit.rb', line 46

def latest
  last
end

.normalize_commit_message(message) ⇒ Object



178
179
180
181
# File 'app/models/commit.rb', line 178

def self.normalize_commit_message(message)
  message = message[/^.*(?=\n\n)/] || message # just take the first paragraph of the commit message
  message = message.gsub(/[\n\s]+/, ' ') # normalize white space within the message
end

.parse_message(message) ⇒ Object



163
164
165
166
167
168
169
170
171
172
173
174
175
176
# File 'app/models/commit.rb', line 163

def self.parse_message(message)
  tags = []
  tickets = []
  attributes = {}
  hours = 0
  clean_message = normalize_commit_message(message)

  clean_message.gsub!(TICKET_PATTERN) { tickets << [$1.to_i, $2]; "" }
  clean_message.gsub!(TIME_PATTERN) { hours = $1.to_f; hours /= 60 if $2.starts_with?("m"); "" }
  clean_message.gsub!(EXTRA_ATTRIBUTE_PATTERN) { (attributes[$1] ||= []).push($2); "" }
  while clean_message.gsub!(TAG_PATTERN) { tags << $1; "" }; end

  {tags: tags, tickets: tickets, hours_worked: hours, attributes: attributes, clean_message: clean_message.strip}
end

.reachableObject



42
43
44
# File 'app/models/commit.rb', line 42

def reachable
  where(unreachable: false)
end

.releasedObject



54
55
56
57
# File 'app/models/commit.rb', line 54

def released
  commits_releases = Arel::Table.new("commits_releases")
  where(arel_table[:id].in(commits_releases.project(:commit_id)))
end

.with_sha_like(sha) ⇒ Object



34
35
36
# File 'app/models/commit.rb', line 34

def with_sha_like(sha)
  where(["sha LIKE ?", "#{sha.strip}%"])
end

Instance Method Details

#antecedentsObject



144
145
146
# File 'app/models/commit.rb', line 144

def antecedents
  extra_attributes.fetch("err", []).map { |id| TicketAntecedent.new(self, "Errbit", id) }
end

#associate_committers_with_selfObject



209
210
211
# File 'app/models/commit.rb', line 209

def associate_committers_with_self
  self.committers = identify_committers
end

#associate_tasks_with_selfObject



201
202
203
204
205
206
207
# File 'app/models/commit.rb', line 201

def associate_tasks_with_self
  self.tasks = identify_tasks

  tasks.each do |task|
    task.committed!(self)
  end
end

#associate_tickets_with_selfObject



197
198
199
# File 'app/models/commit.rb', line 197

def associate_tickets_with_self
  self.tickets = identify_tickets
end

#clean_messageObject



122
123
124
# File 'app/models/commit.rb', line 122

def clean_message
  parsed_message[:clean_message]
end

#committer_hoursObject



150
151
152
# File 'app/models/commit.rb', line 150

def committer_hours
  (hours_worked || 0) * committers.count
end

#create_test_run!Object



215
216
217
# File 'app/models/commit.rb', line 215

def create_test_run!
  super(project: project, sha: sha, commit: self)
end

#descriptionObject



66
67
68
# File 'app/models/commit.rb', line 66

def description
  message.lines[1..-1].join("\n")
end

#extra_attributesObject



140
141
142
# File 'app/models/commit.rb', line 140

def extra_attributes
  parsed_message[:attributes]
end

#hours_workedObject



136
137
138
# File 'app/models/commit.rb', line 136

def hours_worked
  parsed_message[:hours_worked]
end

#identify_committersObject



156
157
158
159
# File 'app/models/commit.rb', line 156

def identify_committers
  emails = Houston.config.identify_committers(self)
  User.with_email_address(emails).to_a
end

#merge?Boolean

Returns:

  • (Boolean)


112
113
114
# File 'app/models/commit.rb', line 112

def merge?
  (message =~ MERGE_COMMIT_PATTERN).present?
end

#native_commitObject



85
86
87
# File 'app/models/commit.rb', line 85

def native_commit
  project.repo.native_commit(sha)
end

#skip?Boolean

Returns:

  • (Boolean)


108
109
110
# File 'app/models/commit.rb', line 108

def skip?
  merge? || tags.member?("skip")
end

#summaryObject



62
63
64
# File 'app/models/commit.rb', line 62

def summary
  message[/^.*$/]
end

#tagsObject



118
119
120
# File 'app/models/commit.rb', line 118

def tags
  parsed_message[:tags]
end

#ticket_numbersObject



126
127
128
# File 'app/models/commit.rb', line 126

def ticket_numbers
  parsed_message[:tickets].map { |(number, task)| number }
end

#ticket_tasksObject



130
131
132
133
134
# File 'app/models/commit.rb', line 130

def ticket_tasks
  @ticket_tasks ||= parsed_message[:tickets].each_with_object({}) do |(number, task), tasks_by_ticket|
    (tasks_by_ticket[number] ||= []).push(task) unless task.blank?
  end
end

#to_sObject



95
96
97
# File 'app/models/commit.rb', line 95

def to_s
  sha
end

#to_strObject



91
92
93
# File 'app/models/commit.rb', line 91

def to_str
  sha
end

#urlObject



99
100
101
102
103
104
# File 'app/models/commit.rb', line 99

def url
  @url ||= begin
    repo = project.repo if project
    repo.commit_url(sha) if repo.respond_to?(:commit_url)
  end
end