app/models/scm_changeset.rb
# encoding: UTF-8
# commit
# author - author of the commit, string
# user - author of the commit, User (NULL if author not registered in system)
class ScmChangeset < ActiveRecord::Base
belongs_to :user
belongs_to :scm_project
belongs_to :task, :touch => true, :class_name => 'TaskRecord'
has_many :scm_files, :dependent => :destroy
validates_presence_of :scm_project
validates_presence_of :author
accepts_nested_attributes_for :scm_files
before_create do |changeset|
if changeset.user_id.nil?
user = User.by_email(changeset.author).first
user = User.find_by(:username => changeset.author) if user.nil?
user = User.find_by(:name => changeset.author) if user.nil?
changeset.user = user
end
num= changeset.message.scan(/#(\d+)/).first
unless num.nil? or num.first.blank?
changeset.task = changeset.scm_project.company.tasks.find_by(:task_num => num.first)
end
end
def issue_num
name = "[#{self.changeset_rev}]"
end
def name
n = "#{self.scm_project.scm_type.upcase} Commit"
if self.scm_project.scm_type == 'svn'
n << " (r#{self.changeset_rev})"
end
if self.scm_files && self.scm_files.size > 0
n << " [#{self.scm_files.size} #{self.scm_files.size == 1 ? 'file' : 'files'}]"
end
n
end
def full_name
"#{self.scm_project.location}"
end
def ScmChangeset.github_parser(payload)
payload = JSON.parse(payload)
payload['commits'].collect do |commit|
changeset= {}
changeset[:changeset_rev]= commit['id']
changeset[:scm_files_attributes]=[]
changeset[:scm_files_attributes] << commit['modified'].collect { |file| {:path => file, :state => 'M'} } unless commit['modified'].nil?
changeset[:scm_files_attributes] << commit['added'].collect { |file| {:path => file, :state => 'A'} } unless commit['added'].nil?
changeset[:scm_files_attributes] << commit['deleted'].collect { |file| {:path => file, :state => 'D'} } unless commit['deleted'].nil?
changeset[:scm_files_attributes].flatten!
changeset[:author] = commit['author']['name']
changeset[:message] = commit['message']
changeset[:commit_date] = commit['timestamp']
changeset
end
end
def ScmChangeset.google_parser(payload)
payload = JSON.parse(payload)
payload['revisions'].collect do |commit|
changeset= {}
changeset[:changeset_rev]= commit['revision']
changeset[:scm_files_attributes]=[]
changeset[:scm_files_attributes] << commit['modified'].collect { |file| {:path => file, :state => 'M'} } unless commit['modified'].nil?
changeset[:scm_files_attributes] << commit['added'].collect { |file| {:path => file, :state => 'A'} } unless commit['added'].nil?
changeset[:scm_files_attributes] << commit['removed'].collect { |file| {:path => file, :state => 'D'} } unless commit['removed'].nil?
changeset[:scm_files_attributes].flatten!
changeset[:author] = commit['author']
changeset[:message] = commit['message']
changeset[:commit_date] = Time.at(commit['timestamp'])
changeset
end
end
def ScmChangeset.gitorious_parser(payload)
payload = JSON.parse(payload)
changeset= {}
payload['commits'].collect do |commit|
changeset= {}
changeset[:changeset_rev]= commit['id']
changeset[:scm_files_attributes]={}
changeset[:author] = commit['author']['name'] + ' <' + commit['author']['email'] + '>'
changeset[:message] = commit['message']
changeset[:commit_date] = commit['timestamp']
changeset
end
end
def ScmChangeset.create_from_web_hook(params)
scm_project = ScmProject.find_by(:secret_key => params[:secret_key])
if scm_project.nil?
return false
end
case params[:provider]
when 'github' then
github_parser(params[:payload])
when 'google', 'json' then
google_parser(params[:payload])
when 'gitorious' then
gitorious_parser(params[:payload])
else
return false
end.collect do |changeset|
scm_changeset = ScmChangeset.find_or_create_by(:scm_project_id => scm_project.id, :changeset_rev => changeset[:changeset_rev].to_s)
task_id = /refs\s+#(?<task_id>[0-9]+)/i.match(changeset[:message])
unless task_id.nil?
changeset[:task_id] = task_id[:task_id]
end
scm_changeset.attributes=changeset
return false unless scm_changeset.save
scm_changeset
end
end
def ScmChangeset.for_list(params)
conditions={}
unless params[:scm_project_id].blank?
conditions[:scm_project_id]= params[:scm_project_id]
end
unless params[:task_id].blank?
conditions[:task_id]=params[:task_id]
end
return nil if conditions.empty?
ScmChangeset.where(conditions)
end
end
# == Schema Information
#
# Table name: scm_changesets
#
# id :integer(4) not null, primary key
# user_id :integer(4)
# scm_project_id :integer(4)
# author :string(255)
# changeset_num :integer(4)
# commit_date :datetime
# changeset_rev :string(255)
# message :text
# scm_files_count :integer(4)
# task_id :integer(4)
#
# Indexes
#
# scm_changesets_author_index (author)
# scm_changesets_commit_date_index (commit_date)
# fk_scm_changesets_user_id (user_id)
#