[#19] add issue references from commit

This commit is contained in:
Alexander Machehin 2013-03-22 22:46:26 +06:00
parent 9d8b8d8a1e
commit ce2ca6646e
11 changed files with 172 additions and 99 deletions

View File

@ -53,7 +53,7 @@ class Projects::CommentsController < Projects::BaseController
end
def find_or_build_comment
@comment = params[:id].present? && Comment.find(params[:id]) ||
@comment = params[:id].present? && Comment.where(:automatic => false).find(params[:id]) ||
current_user.comments.build(params[:comment]) {|c| c.commentable = @commentable; c.project = @project}
end
end

View File

@ -10,6 +10,7 @@ class Projects::IssuesController < Projects::BaseController
layout false, :only => [:update, :search_collaborators]
def index(status = 200)
@system_user = User.find_by_uname 'rosa_system'
@labels = params[:labels] || []
@issues = @project.issues.without_pull_requests
@issues = @issues.where(:assignee_id => current_user.id) if @is_assigned_to_me = params[:filter] == 'to_me'

View File

@ -34,6 +34,7 @@ class ActivityFeedObserver < ActiveRecord::Observer
end
when 'Comment'
return if record.automatic
if record.issue_comment?
subscribes = record.commentable.subscribes
subscribes.each do |subscribe|
@ -95,6 +96,7 @@ class ActivityFeedObserver < ActiveRecord::Observer
commits = commits[0...-3]
options.merge!({:other_commits_count => commits.count, :other_commits => "#{commits[0].sha[0..9]}...#{commits[-1].sha[0..9]}"})
end
Comment.create_link_on_issues_from_commits(record, last_commits) if last_commits.count > 0
end
options.merge!({:user_id => record.user.id, :user_name => record.user.name, :user_email => record.user.email}) if record.user
@ -156,5 +158,4 @@ class ActivityFeedObserver < ActiveRecord::Observer
end
end
end
end

View File

@ -1,11 +1,12 @@
# -*- encoding : utf-8 -*-
class Comment < ActiveRecord::Base
belongs_to :commentable, :polymorphic => true, :touch => true
belongs_to :commentable, :polymorphic => true
belongs_to :user
belongs_to :project
serialize :data
validates :body, :user_id, :commentable_id, :commentable_type, :project_id, :presence => true
validates :body, :commentable_id, :commentable_type, :project_id, :presence => true
validates :user_id, :presence => true, :unless => lambda {|c| c.automatic}
scope :for_commit, lambda {|c| where(:commentable_id => c.id.hex, :commentable_type => c.class)}
default_scope order("#{table_name}.created_at")
@ -129,6 +130,30 @@ class Comment < ActiveRecord::Base
return true
end
def self.create_link_on_issues_from_commits git_hook, commits
system_user = User.find_by_uname 'rosa_system'
commits.each do |commit|
commit[1].scan(/(?:[a-zA-Z0-9\-_]*\/)?(?:[a-zA-Z0-9\-_]*)?#[0-9]+/).each do |hash|
hash =~ /([a-zA-Z0-9\-_]*\/)?([a-zA-Z0-9\-_]*)?#([0-9]+)/
owner_uname = Regexp.last_match[1].presence || git_hook.project.owner.uname
project_name = Regexp.last_match[2].presence || git_hook.project.name
serial_id = Regexp.last_match[3]
project = Project.find_by_owner_and_name(owner_uname.chomp('/'), project_name)
next unless project
next unless Ability.new(git_hook.user).can? :read, project
issue = project.issues.where(:serial_id => serial_id).first
next unless issue
repo_commit = git_hook.project.repo.commit commit[0]
comment = system_user.comments.new :body => 'automatic comment'
comment.commentable = issue
comment.automatic = true
comment.project = project
comment.data = {:commit_project_id => git_hook.project.id, :commit_hash => commit[0]}
comment.save
end
end
end
protected
def subscribe_on_reply

View File

@ -2,33 +2,55 @@
class GitPresenters::CommitAsMessagePresenter < ApplicationPresenter
include CommitHelper
attr_accessor :commit, :options
attr_accessor :commit
attr_reader :header, :image, :date, :caption, :content, :expandable
def initialize(commit, opts = {})
@commit = commit
@options = opts
comment = opts[:comment]
@issue_reference = !!comment # is it reference issue from commit
@project = if comment
Project.where(:id => opts[:comment].data[:commit_project_id]).first
else
opts[:project]
end
if @project
commit = commit || @project.repo.commit(comment.data[:commit_hash])
@committer = commit.committer
@commit_hash = commit.id
@committed_date, @authored_date = commit.committed_date, commit.authored_date
@commit_message = commit.message
else
@committer = t('layout.commits.unknown_committer')
@commit_hash = comment.data[:commit_hash]
@committed_date = @authored_date = comment.created_at
@commit_message = t('layout.commits.deleted')
end
prepare_message
end
def header
@header ||= if options[:project].present?
I18n.t("layout.messages.commits.header",
:committer => committer_link, :commit => commit_link, :project => options[:project].name)
end.html_safe
@header ||= if @issue_reference
I18n.t('layout.commits.reference', :committer => committer_link, :commit => commit_link)
elsif @project.present?
I18n.t('layout.messages.commits.header',
:committer => committer_link, :commit => commit_link, :project => @project.name)
end.html_safe
end
def image
c = committer
@image ||= if c.class == User
helpers.avatar_url(c, :medium)
@image ||= if committer.is_a? User
helpers.avatar_url(committer, :medium)
elsif committer.is_a? Grit::Actor
helpers.avatar_url_by_email(committer.email, :medium)
else
helpers.avatar_url_by_email(c.email, :medium)
size = User.new.avatar.styles[:medium].geometry.split('x').first
helpers.gravatar_url('email', size)
end
end
def date
@date ||= I18n.l(@commit.committed_date || @commit.authored_date, :format => :long)
@date ||= I18n.l(@committed_date || @authored_date, :format => :long)
end
def expandable?
@ -53,31 +75,37 @@ class GitPresenters::CommitAsMessagePresenter < ApplicationPresenter
protected
def committer
@committer ||= User.where(:email => @commit.committer.email).first || @commit.committer
end
def committer
@committer ||= User.where(:email => @commiter.email).first || @commiter
end
def committer_link
@committer_link ||= if committer.is_a? User
link_to committer.uname, user_path(committer)
else
mail_to committer.email, committer.name
end
def committer_link
@committer_link ||= if committer.is_a? User
link_to committer.uname, user_path(committer)
elsif committer.is_a? Grit::Actor
mail_to committer.email, committer.name
else # unknown committer
committer
end
end
def commit_link
link_to shortest_hash_id(@commit.id), commit_path(options[:project], @commit.id)
def commit_link
if @project
link_to shortest_hash_id(@commit_hash), commit_path(@project, @commit_hash)
else
shortest_hash_id(@commit_hash)
end
end
def prepare_message
(@caption, @content) = @commit.message.split("\n\n", 2)
@caption = 'empty message' unless @caption.present?
if @caption.length > 72
tmp = '...' + @caption[69..-1]
@content = (@content.present?) ? tmp + @content : tmp
@caption = @caption[0..68] + '...'
end
def prepare_message
(@caption, @content) = @commit_message.split("\n\n", 2)
@caption = 'empty message' unless @caption.present?
if @caption.length > 72
tmp = '...' + @caption[69..-1]
@content = (@content.present?) ? tmp + @content : tmp
@caption = @caption[0..68] + '...'
end
# @content = @content.gsub("\n", "<br />").html_safe if @content
@content = simple_format(@content, {}, :sanitize => true).html_safe if @content
end
@content = simple_format(@content, {}, :sanitize => true).html_safe if @content
end
end

View File

@ -1,6 +1,12 @@
%a{ :name => "comments" }
.hr
%h3#block-list= t("layout.comments.comments_header")
- counter = 1
- list.each do |comment|
= render 'projects/comments/comment', :comment => comment, :data => {:project => project, :commentable => commentable}
-if comment.automatic
- GitPresenters::CommitAsMessagePresenter.present(nil, :comment => comment) do |presenter|
= render 'shared/feed_message', :presenter => presenter, :item_no => counter
- counter += 1
-else
= render 'projects/comments/comment', :comment => comment, :data => {:project => project, :commentable => commentable}
= render "projects/comments/markdown_help"

View File

@ -24,5 +24,5 @@
%a{:href => "#{path}#block-list"}
.answers
.pic= image_tag 'answers.png'
.count=issue.comments.count
.count=issue.comments.where(:automatic => false).count
.both

View File

@ -6,4 +6,7 @@ en:
pluralize:
commit: commit
commits: commits
commits2: commits
commits2: commits
reference: "%{committer} referenced this issue from a commit %{commit}"
deleted: Commit has since been removed from the git-repository and is no longer available.
unknown_committer: Unknown

View File

@ -6,4 +6,7 @@ ru:
pluralize:
commit: коммит
commits: коммита
commits2: коммитов
commits2: коммитов
reference: "%{committer} ссылается на данную задачу в коммите %{commit}"
deleted: Коммит был удален и более недоступен в git-репозитории.
unknown_committer: Неизвестный

View File

@ -0,0 +1,5 @@
class AddAutomaticToComments < ActiveRecord::Migration
def change
add_column :comments, :automatic, :boolean, :default => false
end
end

View File

@ -11,14 +11,14 @@
#
# It's strongly recommended to check this file into your version control system.
ActiveRecord::Schema.define(:version => 20130227102900) do
ActiveRecord::Schema.define(:version => 20130319172358) do
create_table "activity_feeds", :force => true do |t|
t.integer "user_id", :null => false
t.string "kind"
t.text "data"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "advisories", :force => true do |t|
@ -53,8 +53,8 @@ ActiveRecord::Schema.define(:version => 20130227102900) do
create_table "arches", :force => true do |t|
t.string "name", :null => false
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.datetime "created_at"
t.datetime "updated_at"
end
add_index "arches", ["name"], :name => "index_arches_on_name", :unique => true
@ -63,8 +63,8 @@ ActiveRecord::Schema.define(:version => 20130227102900) do
t.integer "user_id"
t.string "provider"
t.string "uid"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.datetime "created_at"
t.datetime "updated_at"
end
add_index "authentications", ["provider", "uid"], :name => "index_authentications_on_provider_and_uid", :unique => true
@ -75,8 +75,8 @@ ActiveRecord::Schema.define(:version => 20130227102900) do
t.integer "level"
t.integer "status"
t.integer "build_list_id"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.datetime "created_at"
t.datetime "updated_at"
t.string "version"
end
@ -110,8 +110,8 @@ ActiveRecord::Schema.define(:version => 20130227102900) do
t.integer "project_id"
t.integer "arch_id"
t.datetime "notified_at"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.datetime "created_at"
t.datetime "updated_at"
t.boolean "is_circle", :default => false
t.text "additional_repos"
t.string "name"
@ -149,11 +149,12 @@ ActiveRecord::Schema.define(:version => 20130227102900) do
t.string "commentable_type"
t.integer "user_id"
t.text "body"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.datetime "created_at"
t.datetime "updated_at"
t.decimal "commentable_id", :precision => 50, :scale => 0
t.integer "project_id"
t.text "data"
t.boolean "automatic", :default => false
end
create_table "event_logs", :force => true do |t|
@ -168,8 +169,8 @@ ActiveRecord::Schema.define(:version => 20130227102900) do
t.string "controller"
t.string "action"
t.text "message"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "flash_notifies", :force => true do |t|
@ -183,8 +184,8 @@ ActiveRecord::Schema.define(:version => 20130227102900) do
create_table "groups", :force => true do |t|
t.integer "owner_id"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.datetime "created_at"
t.datetime "updated_at"
t.string "uname"
t.integer "own_projects_count", :default => 0, :null => false
t.text "description"
@ -201,8 +202,8 @@ ActiveRecord::Schema.define(:version => 20130227102900) do
t.string "title"
t.text "body"
t.string "status", :default => "open"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.datetime "created_at"
t.datetime "updated_at"
t.integer "user_id"
t.datetime "closed_at"
t.integer "closed_by"
@ -279,14 +280,14 @@ ActiveRecord::Schema.define(:version => 20130227102900) do
t.string "description"
t.string "name", :null => false
t.integer "parent_platform_id"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.datetime "created_at"
t.datetime "updated_at"
t.boolean "released", :default => false, :null => false
t.integer "owner_id"
t.string "owner_type"
t.string "visibility", :default => "open", :null => false
t.string "platform_type", :default => "main", :null => false
t.string "distrib_type"
t.string "distrib_type", :null => false
end
add_index "platforms", ["name"], :name => "index_platforms_on_name", :unique => true, :case_sensitive => false
@ -295,16 +296,16 @@ ActiveRecord::Schema.define(:version => 20130227102900) do
t.integer "platform_id"
t.string "login"
t.string "password"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.datetime "created_at"
t.datetime "updated_at"
t.integer "user_id"
end
create_table "product_build_lists", :force => true do |t|
t.integer "product_id"
t.integer "status", :default => 3, :null => false
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.integer "status", :default => 2, :null => false
t.datetime "created_at"
t.datetime "updated_at"
t.integer "project_id"
t.string "project_version"
t.string "commit_hash"
@ -321,8 +322,8 @@ ActiveRecord::Schema.define(:version => 20130227102900) do
create_table "products", :force => true do |t|
t.string "name", :null => false
t.integer "platform_id", :null => false
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.datetime "created_at"
t.datetime "updated_at"
t.text "description"
t.integer "project_id"
t.string "params"
@ -335,8 +336,8 @@ ActiveRecord::Schema.define(:version => 20130227102900) do
t.string "name"
t.string "version"
t.datetime "file_mtime"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.datetime "created_at"
t.datetime "updated_at"
t.integer "platform_id"
end
@ -355,27 +356,27 @@ ActiveRecord::Schema.define(:version => 20130227102900) do
create_table "project_to_repositories", :force => true do |t|
t.integer "project_id"
t.integer "repository_id"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.datetime "created_at"
t.datetime "updated_at"
end
add_index "project_to_repositories", ["repository_id", "project_id"], :name => "index_project_to_repositories_on_repository_id_and_project_id", :unique => true
create_table "projects", :force => true do |t|
t.string "name"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.datetime "created_at"
t.datetime "updated_at"
t.integer "owner_id"
t.string "owner_type"
t.string "visibility", :default => "open"
t.text "description"
t.string "ancestry"
t.boolean "has_issues", :default => true
t.boolean "has_wiki", :default => false
t.string "srpm_file_name"
t.string "srpm_content_type"
t.integer "srpm_file_size"
t.datetime "srpm_updated_at"
t.string "srpm_content_type"
t.boolean "has_wiki", :default => false
t.string "default_branch", :default => "master"
t.boolean "is_package", :default => true, :null => false
t.integer "average_build_time", :default => 0, :null => false
@ -406,8 +407,8 @@ ActiveRecord::Schema.define(:version => 20130227102900) do
t.string "token"
t.boolean "approved", :default => false
t.boolean "rejected", :default => false
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.datetime "created_at"
t.datetime "updated_at"
t.string "interest"
t.text "more"
t.string "language"
@ -421,16 +422,16 @@ ActiveRecord::Schema.define(:version => 20130227102900) do
t.string "actor_type"
t.integer "target_id"
t.string "target_type"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.datetime "created_at"
t.datetime "updated_at"
t.string "role"
end
create_table "repositories", :force => true do |t|
t.string "description", :null => false
t.integer "platform_id", :null => false
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.datetime "created_at"
t.datetime "updated_at"
t.string "name", :null => false
t.boolean "publish_without_qa", :default => true
end
@ -444,8 +445,8 @@ ActiveRecord::Schema.define(:version => 20130227102900) do
t.boolean "new_comment_reply", :default => true
t.boolean "new_issue", :default => true
t.boolean "issue_assign", :default => true
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.datetime "created_at"
t.datetime "updated_at"
t.boolean "new_comment_commit_owner", :default => true
t.boolean "new_comment_commit_repo_owner", :default => true
t.boolean "new_comment_commit_commentor", :default => true
@ -468,8 +469,8 @@ ActiveRecord::Schema.define(:version => 20130227102900) do
create_table "subscribes", :force => true do |t|
t.string "subscribeable_type"
t.integer "user_id"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.datetime "created_at"
t.datetime "updated_at"
t.boolean "status", :default => true
t.integer "project_id"
t.decimal "subscribeable_id", :precision => 50, :scale => 0
@ -477,21 +478,18 @@ ActiveRecord::Schema.define(:version => 20130227102900) do
create_table "users", :force => true do |t|
t.string "name"
t.string "email", :default => "", :null => false
t.string "encrypted_password", :default => "", :null => false
t.string "email", :default => "", :null => false
t.string "encrypted_password", :limit => 128, :default => "", :null => false
t.string "reset_password_token"
t.datetime "reset_password_sent_at"
t.datetime "remember_created_at"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.datetime "created_at"
t.datetime "updated_at"
t.text "ssh_key"
t.string "uname"
t.string "role"
t.string "language", :default => "en"
t.integer "own_projects_count", :default => 0, :null => false
t.string "confirmation_token"
t.datetime "confirmed_at"
t.datetime "confirmation_sent_at"
t.string "language", :default => "en"
t.integer "own_projects_count", :default => 0, :null => false
t.text "professional_experience"
t.string "site"
t.string "company"
@ -500,11 +498,14 @@ ActiveRecord::Schema.define(:version => 20130227102900) do
t.string "avatar_content_type"
t.integer "avatar_file_size"
t.datetime "avatar_updated_at"
t.integer "failed_attempts", :default => 0
t.integer "failed_attempts", :default => 0
t.string "unlock_token"
t.datetime "locked_at"
t.string "confirmation_token"
t.datetime "confirmed_at"
t.datetime "confirmation_sent_at"
t.string "authentication_token"
t.integer "build_priority", :default => 50
t.integer "build_priority", :default => 50
end
add_index "users", ["authentication_token"], :name => "index_users_on_authentication_token"