From 16c9d0ec15a44dbc2dd087041007eb5e92ce5ab7 Mon Sep 17 00:00:00 2001 From: "konstantin.grabar" Date: Sat, 31 Dec 2011 14:51:47 +0400 Subject: [PATCH 01/67] [refs #54] Fix some bugs of issues and comments + add comment body to email --- app/controllers/comments_controller.rb | 2 +- app/mailers/user_mailer.rb | 2 +- app/models/comment.rb | 8 +++----- app/views/issues/show.html.haml | 2 +- app/views/user_mailer/new_comment_notification.haml | 2 ++ 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/app/controllers/comments_controller.rb b/app/controllers/comments_controller.rb index e20aa3af1..4b70d8127 100644 --- a/app/controllers/comments_controller.rb +++ b/app/controllers/comments_controller.rb @@ -16,7 +16,7 @@ class CommentsController < ApplicationController @comment.user = current_user if @comment.save flash[:notice] = I18n.t("flash.comment.saved") - redirect_to :back + redirect_to [@commentable.project, @commentable] else flash[:error] = I18n.t("flash.comment.save_error") render :action => 'new' diff --git a/app/mailers/user_mailer.rb b/app/mailers/user_mailer.rb index 2c43482e1..9be195dd4 100644 --- a/app/mailers/user_mailer.rb +++ b/app/mailers/user_mailer.rb @@ -1,7 +1,7 @@ # coding: UTF-8 class UserMailer < ActionMailer::Base - default :from => APP_CONFIG['no-reply-email'] + default :from => APP_CONFIG['do-not-reply-email'] def new_user_notification(user) @user = user diff --git a/app/models/comment.rb b/app/models/comment.rb index 439fd0733..aceb80a7a 100644 --- a/app/models/comment.rb +++ b/app/models/comment.rb @@ -9,11 +9,9 @@ class Comment < ActiveRecord::Base protected def deliver_new_comment_notification - recipients = self.commentable.project.relations.by_role('admin').where(:object_type => 'User').map { |rel| rel.read_attribute(:object_id) } - recipients = recipients | [self.commentable.user_id] - recipients = recipients | [self.commentable.project.owner_id] if self.commentable.project.owner_type == 'User' - recipients.each do |recipient_id| - recipient = User.find(recipient_id) + subscribes = self.commentable.subscribes + subscribes.each do |subscribe| + recipient = subscribe.user UserMailer.delay.new_comment_notification(self, recipient) end end diff --git a/app/views/issues/show.html.haml b/app/views/issues/show.html.haml index 49b229b5c..2a79e66a3 100644 --- a/app/views/issues/show.html.haml +++ b/app/views/issues/show.html.haml @@ -52,5 +52,5 @@ %h2.title = t("layout.comments.new_header") .inner - = form_for :comment, :url => project_issue_comments_path(@project, @issue), :method => :post, :html => { :class => :form } do |f| + = form_for :comment, :url => project_issue_comments_path(@project, @issue.id), :method => :post, :html => { :class => :form } do |f| = render :partial => "comments/form", :locals => {:f => f} diff --git a/app/views/user_mailer/new_comment_notification.haml b/app/views/user_mailer/new_comment_notification.haml index 88692f64e..315a56b88 100644 --- a/app/views/user_mailer/new_comment_notification.haml +++ b/app/views/user_mailer/new_comment_notification.haml @@ -3,5 +3,7 @@ %p К задаче #{ link_to @comment.commentable.title, [@comment.commentable.project, @comment.commentable] } был добавлен новый комментарий. +%p "#{ @comment.body }" + %p== Команда поддержки «ROSA Build System» From 4132c336d62616df5cca276c981ef1513e9fdc7f Mon Sep 17 00:00:00 2001 From: "konstantin.grabar" Date: Sat, 31 Dec 2011 14:55:49 +0400 Subject: [PATCH 02/67] [refs #54] Fix comment update path --- app/views/comments/edit.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/comments/edit.html.haml b/app/views/comments/edit.html.haml index 516ddd476..5f2dc3ffd 100644 --- a/app/views/comments/edit.html.haml +++ b/app/views/comments/edit.html.haml @@ -6,5 +6,5 @@ %h2.title = t("layout.issues.edit_header") .inner - = form_for @comment, :url => project_issue_comment_path(@project, @issue, @comment), :html => { :class => :form } do |f| + = form_for @comment, :url => project_issue_comment_path(@project, @issue.id, @comment), :html => { :class => :form } do |f| = render :partial => "form", :locals => {:f => f} From 60a7f3e87f3540b07fca4cc6c5ee32416ec4ea7f Mon Sep 17 00:00:00 2001 From: "konstantin.grabar" Date: Tue, 10 Jan 2012 15:24:43 +0400 Subject: [PATCH 03/67] [refs #54] Fix comments specs --- spec/models/comment_spec.rb | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/spec/models/comment_spec.rb b/spec/models/comment_spec.rb index 0b969c134..5408a2330 100644 --- a/spec/models/comment_spec.rb +++ b/spec/models/comment_spec.rb @@ -1,7 +1,7 @@ require 'spec_helper' require "cancan/matchers" -def set_testable_data +def set_comments_data @ability = Ability.new(@user) @project = Factory(:project) @@ -19,7 +19,7 @@ describe Comment do @user = Factory(:admin) @stranger = Factory(:user) - set_testable_data + set_comments_data end it 'should create comment' do @@ -48,7 +48,7 @@ describe Comment do @user = Factory(:user) @stranger = Factory(:user) - set_testable_data + set_comments_data @project.relations.create!(:object_type => 'User', :object_id => @user.id, :role => 'admin') end @@ -75,7 +75,7 @@ describe Comment do @user = Factory(:user) @stranger = Factory(:user) - set_testable_data + set_comments_data @project.update_attribute(:owner, @user) @project.relations.create!(:object_type => 'User', :object_id => @user.id, :role => 'admin') @@ -103,7 +103,7 @@ describe Comment do @user = Factory(:user) @stranger = Factory(:user) - set_testable_data + set_comments_data end it 'should create comment' do From dda40d9e9d36c497fa13dff0bf06d4cfa5c5a8e9 Mon Sep 17 00:00:00 2001 From: "konstantin.grabar" Date: Wed, 11 Jan 2012 11:12:23 +0400 Subject: [PATCH 04/67] [refs #54] Mailer specs for comments and issues --- spec/mailers/user_mailer_spec.rb | 114 +++++++++++++++++++++++++++++++ spec/models/comment_spec.rb | 6 +- 2 files changed, 119 insertions(+), 1 deletion(-) diff --git a/spec/mailers/user_mailer_spec.rb b/spec/mailers/user_mailer_spec.rb index 8d004b3ed..ff86fcc9d 100644 --- a/spec/mailers/user_mailer_spec.rb +++ b/spec/mailers/user_mailer_spec.rb @@ -2,4 +2,118 @@ require "spec_helper" describe UserMailer do pending "add some examples to (or delete) #{__FILE__}" + + context 'On Issue create' do + before(:each) do + stub_rsync_methods + + @project = Factory(:project) + @issue_user = Factory(:user) + + any_instance_of(Project, :versions => ['v1.0', 'v2.0']) + + @issue = Factory(:issue, :project_id => @project.id, :user_id => @issue_user.id) + @email = UserMailer.new_issue_notification(@issue, @issue_user).deliver + end + + it 'should have correct subject' do + @email.subject.should == I18n.t("notifications.subjects.new_issue_notification") + end + + it 'should render receiver email' do + @email.to.should == [@issue_user.email] + end + + it 'should render the sender email' do + @email.from.should == [APP_CONFIG['do-not-reply-email']] + end + + it 'should assign user name' do + @email.body.encoded.should match(@issue_user.name) + end + + it 'should assign issue project name' do + @email.body.encoded.should match(@issue.project.name) + end + + it 'should assign issue title' do + @email.body.encoded.should match(@issue.title) + end + end + + context 'On Issue assign' do + before(:each) do + stub_rsync_methods + + @project = Factory(:project) + @issue_user = Factory(:user) + @user = Factory(:user) + + any_instance_of(Project, :versions => ['v1.0', 'v2.0']) + + @issue = Factory(:issue, :project_id => @project.id, :user_id => @issue_user.id) + @email = UserMailer.issue_assign_notification(@issue, @user).deliver + end + + it 'should have correct subject' do + @email.subject.should == I18n.t("notifications.subjects.issue_assign_notification") + end + + it 'should render receiver email' do + @email.to.should == [@user.email] + end + + it 'should render the sender email' do + @email.from.should == [APP_CONFIG['do-not-reply-email']] + end + + it 'should assign user name' do + @email.body.encoded.should match(@user.name) + end + + it 'should assign issue title' do + @email.body.encoded.should match(@issue.title) + end + end + + + context 'On Comment create' do + before(:each) do + stub_rsync_methods + + @project = Factory(:project) + @issue_user = Factory(:user) + @user = Factory(:user) + + any_instance_of(Project, :versions => ['v1.0', 'v2.0']) + + @issue = Factory(:issue, :project_id => @project.id, :user_id => @issue_user.id) + @comment = Factory(:comment, :commentable => @issue, :user_id => @user.id) + @email = UserMailer.new_comment_notification(@comment, @issue_user).deliver + end + + it 'should have correct subject' do + @email.subject.should == I18n.t("notifications.subjects.new_comment_notification") + end + + it 'should render receiver email' do + @email.to.should == [@issue_user.email] + end + + it 'should render the sender email' do + @email.from.should == [APP_CONFIG['do-not-reply-email']] + end + + it 'should assign user name' do + @email.body.encoded.should match(@issue_user.name) + end + + it 'should assign comment body' do + @email.body.encoded.should match(@comment.body) + end + + it 'should assign issue title' do + @email.body.encoded.should match(@issue.title) + end + end end diff --git a/spec/models/comment_spec.rb b/spec/models/comment_spec.rb index 5408a2330..f7d43cb14 100644 --- a/spec/models/comment_spec.rb +++ b/spec/models/comment_spec.rb @@ -26,6 +26,10 @@ describe Comment do @ability.should be_able_to(:create, Comment.new(:commentable => @issue, :user => @user)) end + pending "sends an e-mail" do + ActionMailer::Base.deliveries.last.to.include?(@stranger.email).should == true + end + it 'should update comment' do @ability.should be_able_to(:update, @comment) end @@ -35,7 +39,7 @@ describe Comment do end it 'should destroy own comment' do - @ability.should be_able_to(:destroy, @comment) + @ability.should be_able_to(:destroy, @comment) end it 'should destroy stranger comment' do From 2b8aca5f098c2e56102632c3aa2c82723dfb79d0 Mon Sep 17 00:00:00 2001 From: "konstantin.grabar" Date: Wed, 11 Jan 2012 17:58:13 +0400 Subject: [PATCH 05/67] [refs #54] Add settings notifier --- .../settings/notifiers_controller.rb | 22 ++++++++++++++++++ app/helpers/settings/notifiers_helper.rb | 2 ++ app/models/ability.rb | 2 ++ app/models/issue.rb | 9 ++++++-- app/models/settings.rb | 5 ++++ app/models/settings/notifier.rb | 5 ++++ app/models/user.rb | 10 ++++++++ app/views/devise/registrations/edit.html.haml | 2 ++ app/views/settings/notifiers/_form.html.haml | 23 +++++++++++++++++++ app/views/settings/notifiers/show.html.haml | 5 ++++ config/locales/ru.yml | 18 +++++++++++++++ config/routes.rb | 3 +++ ...0120111072106_create_settings_notifiers.rb | 17 ++++++++++++++ ...5443_add_settings_notifier_to_all_users.rb | 13 +++++++++++ db/schema.rb | 23 +++++++++++++------ .../settings/notifiers_controller_spec.rb | 5 ++++ spec/factories/settings_notifiers.rb | 6 +++++ .../helpers/settings/notifiers_helper_spec.rb | 15 ++++++++++++ spec/models/settings/notifier_spec.rb | 5 ++++ 19 files changed, 181 insertions(+), 9 deletions(-) create mode 100644 app/controllers/settings/notifiers_controller.rb create mode 100644 app/helpers/settings/notifiers_helper.rb create mode 100644 app/models/settings.rb create mode 100644 app/models/settings/notifier.rb create mode 100644 app/views/settings/notifiers/_form.html.haml create mode 100644 app/views/settings/notifiers/show.html.haml create mode 100644 db/migrate/20120111072106_create_settings_notifiers.rb create mode 100644 db/migrate/20120111135443_add_settings_notifier_to_all_users.rb create mode 100644 spec/controllers/settings/notifiers_controller_spec.rb create mode 100644 spec/factories/settings_notifiers.rb create mode 100644 spec/helpers/settings/notifiers_helper_spec.rb create mode 100644 spec/models/settings/notifier_spec.rb diff --git a/app/controllers/settings/notifiers_controller.rb b/app/controllers/settings/notifiers_controller.rb new file mode 100644 index 000000000..03df52237 --- /dev/null +++ b/app/controllers/settings/notifiers_controller.rb @@ -0,0 +1,22 @@ +class Settings::NotifiersController < ApplicationController + layout "sessions" + + before_filter :authenticate_user! + + load_and_authorize_resource :user + load_and_authorize_resource :class => Settings::Notifier, :through => :user, :singleton => true, :shallow => true + + def show + end + + def update + if @notifier.update_attributes(params[:settings_notifier]) + flash[:notice] = I18n.t("flash.settings.saved") + redirect_to [@user, @notifier] + else + flash[:notice] = I18n.t("flash.settings.save_error") + redirect_to [@user, @notifier] + end + end + +end diff --git a/app/helpers/settings/notifiers_helper.rb b/app/helpers/settings/notifiers_helper.rb new file mode 100644 index 000000000..295af1e51 --- /dev/null +++ b/app/helpers/settings/notifiers_helper.rb @@ -0,0 +1,2 @@ +module Settings::NotifiersHelper +end diff --git a/app/models/ability.rb b/app/models/ability.rb index 1b7509a2b..3697ea035 100644 --- a/app/models/ability.rb +++ b/app/models/ability.rb @@ -28,6 +28,8 @@ class Ability else # Registered user rights can [:show, :autocomplete_user_uname], User + can [:show, :update], Settings::Notifier, :user_id => user.id + can [:read, :create], Group can [:update, :manage_members], Group do |group| group.objects.exists?(:object_type => 'User', :object_id => user.id, :role => 'admin') # or group.owner_id = user.id diff --git a/app/models/issue.rb b/app/models/issue.rb index 9ae96f439..193254e47 100644 --- a/app/models/issue.rb +++ b/app/models/issue.rb @@ -41,7 +41,7 @@ class Issue < ActiveRecord::Base end def deliver_issue_assign_notification - UserMailer.delay.issue_assign_notification(self, self.user) if self.user_id_was != self.user_id + UserMailer.delay.issue_assign_notification(self, self.user) if self.user_id_was != self.user_id && self.user.notifier.issue_assign end def subscribe_users @@ -56,7 +56,12 @@ class Issue < ActiveRecord::Base recipients = self.project.relations.by_role('admin').where(:object_type => 'User').map { |rel| rel.read_attribute(:object_id) } recipients = recipients | [self.user_id] if self.user_id recipients = recipients | [self.project.owner_id] if self.project.owner_type == 'User' + + # filter by notification settings + recipients = recipients.select do |recipient| + User.find(recipient).notifier.new_issue + end + recipients end - end diff --git a/app/models/settings.rb b/app/models/settings.rb new file mode 100644 index 000000000..f6af89076 --- /dev/null +++ b/app/models/settings.rb @@ -0,0 +1,5 @@ +module Settings + def self.table_name_prefix + 'settings_' + end +end diff --git a/app/models/settings/notifier.rb b/app/models/settings/notifier.rb new file mode 100644 index 000000000..af21fd811 --- /dev/null +++ b/app/models/settings/notifier.rb @@ -0,0 +1,5 @@ +class Settings::Notifier < ActiveRecord::Base + belongs_to :user + + validates :user_id, :presence => true +end diff --git a/app/models/user.rb b/app/models/user.rb index 07e59a71f..c246dd6f9 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -4,6 +4,8 @@ class User < ActiveRecord::Base devise :database_authenticatable, :registerable, :omniauthable, # :token_authenticatable, :encryptable, :timeoutable :recoverable, :rememberable, :validatable #, :trackable, :confirmable, :lockable + has_one :notifier, :class_name => 'Settings::Notifier' #:notifier + has_many :authentications, :dependent => :destroy has_many :build_lists, :dependent => :destroy @@ -31,6 +33,8 @@ class User < ActiveRecord::Base attr_readonly :uname attr_accessor :login + after_create :create_settings_notifier + def admin? role == 'admin' end @@ -75,5 +79,11 @@ class User < ActiveRecord::Base clean_up_passwords result end + + private + + def create_settings_notifier + self.create_notifier + end end diff --git a/app/views/devise/registrations/edit.html.haml b/app/views/devise/registrations/edit.html.haml index 75d6fcfa0..c4b6052ab 100644 --- a/app/views/devise/registrations/edit.html.haml +++ b/app/views/devise/registrations/edit.html.haml @@ -68,3 +68,5 @@ %span.text_button_padding = link_to t('layout.back'), :back, :class => "text_button_padding link_button" + .group.navform.wat-cf + = link_to t('layout.settings.notifier'), user_settings_notifier_path(current_user)#, :class => "text_button_padding link_button" diff --git a/app/views/settings/notifiers/_form.html.haml b/app/views/settings/notifiers/_form.html.haml new file mode 100644 index 000000000..140de2655 --- /dev/null +++ b/app/views/settings/notifiers/_form.html.haml @@ -0,0 +1,23 @@ +.group + = f.label :new_comment, t('activerecord.attributes.settings.notifier.new_comment'), :class => :label + = f.check_box :new_comment#, :class => 'text_field' + +.group + = f.label :new_comment_reply, t('activerecord.attributes.settings.notifier.new_comment_reply'), :class => :label + = f.check_box :new_comment_reply#, :class => 'text_field' + +.group + = f.label :new_issue, t('activerecord.attributes.settings.notifier.new_issue'), :class => :label + = f.check_box :new_issue#, :class => 'text_field' + +.group + = f.label :issue_assign, t('activerecord.attributes.settings.notifier.issue_assign'), :class => :label + = f.check_box :issue_assign#, :class => 'text_field' + +.group.navform.wat-cf + %button.button{:type => "submit"} + = image_tag("web-app-theme/icons/tick.png", :alt => t("layout.save")) + = t("layout.save") + %span.text_button_padding= t("layout.or") + = link_to t("layout.cancel"), user_settings_notifier_path(@user), :class => "text_button_padding link_button" + diff --git a/app/views/settings/notifiers/show.html.haml b/app/views/settings/notifiers/show.html.haml new file mode 100644 index 000000000..97f82b931 --- /dev/null +++ b/app/views/settings/notifiers/show.html.haml @@ -0,0 +1,5 @@ +#block-signup.block + %h2= title t("layout.settings.notifiers.edit_header") + .content + = form_for @notifier, :url => user_settings_notifier_path(@user), :html => { :class => :form } do |f| + = render :partial => "form", :locals => {:f => f} diff --git a/config/locales/ru.yml b/config/locales/ru.yml index ef20defa1..a9bffa4a5 100644 --- a/config/locales/ru.yml +++ b/config/locales/ru.yml @@ -30,6 +30,10 @@ ru: not_access: Нет доступа! owner: Владелец confirm: Уверенны? + settings: + notifier: Настройки оповещений + notifiers: + edit_header: Настройки оповещений downloads: title: Статистика закачек пакетов @@ -353,6 +357,11 @@ ru: project_version_not_found: версия не найден flash: + settings: + saved: Настройки успешно сохранены + save_error: При обновлении настроек произошла ошибка + + subscribe: saved: Вы подписаны на оповещения для этой задачи destroyed: Подписка на оповещения для этой задачи убрана @@ -478,8 +487,17 @@ ru: build_list_item: Элемент сборочного листа download: Статистика auto_build_list: Автоматическая пересборка пакетов + settings: + notifier: Настройки оповещений attributes: + settings: + notifier: + new_comment: Оповещать о новом комментарии в задаче + new_comment_reply: Оповещать о новом ответе на мой комментарий + new_issue: Оповещать о новых задачах в моих проектах + issue_assign: Оповещать, когда на меня выставляют задачу + auto_build_list: project_id: Проект project: Проект diff --git a/config/routes.rb b/config/routes.rb index 7f3449cde..f44ccc250 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -9,6 +9,9 @@ Rosa::Application.routes.draw do resources :users do resources :groups, :only => [:new, :create, :index] get :autocomplete_user_uname, :on => :collection + namespace :settings do + resource :notifier, :only => [:show, :update] + end end resources :event_logs, :only => :index diff --git a/db/migrate/20120111072106_create_settings_notifiers.rb b/db/migrate/20120111072106_create_settings_notifiers.rb new file mode 100644 index 000000000..ab8da3aaf --- /dev/null +++ b/db/migrate/20120111072106_create_settings_notifiers.rb @@ -0,0 +1,17 @@ +class CreateSettingsNotifiers < ActiveRecord::Migration + def self.up + create_table :settings_notifiers do |t| + t.integer :user_id, :null => false + t.boolean :new_comment, :default => true + t.boolean :new_comment_reply, :default => true + t.boolean :new_issue, :default => true + t.boolean :issue_assign, :default => true + + t.timestamps + end + end + + def self.down + drop_table :settings_notifiers + end +end diff --git a/db/migrate/20120111135443_add_settings_notifier_to_all_users.rb b/db/migrate/20120111135443_add_settings_notifier_to_all_users.rb new file mode 100644 index 000000000..de018150a --- /dev/null +++ b/db/migrate/20120111135443_add_settings_notifier_to_all_users.rb @@ -0,0 +1,13 @@ +class AddSettingsNotifierToAllUsers < ActiveRecord::Migration + def self.up + User.all.each do |user| + user.create_notifier + end + end + + def self.down + User.all.each do |user| + user.notifier.destroy + end + end +end diff --git a/db/schema.rb b/db/schema.rb index c4eb51827..b91476bc7 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended to check this file into your version control system. -ActiveRecord::Schema.define(:version => 20111228182425) do +ActiveRecord::Schema.define(:version => 20120111135443) do create_table "arches", :force => true do |t| t.string "name", :null => false @@ -246,7 +246,6 @@ ActiveRecord::Schema.define(:version => 20111228182425) do t.string "object_type" t.integer "target_id" t.string "target_type" - t.integer "role_id" t.datetime "created_at" t.datetime "updated_at" t.string "role" @@ -273,6 +272,16 @@ ActiveRecord::Schema.define(:version => 20111228182425) do add_index "rpms", ["project_id", "arch_id"], :name => "index_rpms_on_project_id_and_arch_id" add_index "rpms", ["project_id"], :name => "index_rpms_on_project_id" + create_table "settings_notifiers", :force => true do |t| + t.integer "user_id", :null => false + t.boolean "new_comment", :default => true + t.boolean "new_comment_reply", :default => true + t.boolean "new_issue", :default => true + t.boolean "issue_assign", :default => true + t.datetime "created_at" + t.datetime "updated_at" + end + create_table "subscribes", :force => true do |t| t.integer "subscribeable_id" t.string "subscribeable_type" @@ -283,16 +292,16 @@ ActiveRecord::Schema.define(:version => 20111228182425) do create_table "users", :force => true do |t| t.string "name" - t.string "email", :default => "", :null => false - t.string "encrypted_password", :limit => 128, :default => "", :null => false + t.string "email", :default => "", :null => false + t.string "encrypted_password", :limit => 128, :default => "", :null => false + t.string "password_salt", :default => "", :null => false t.string "reset_password_token" - t.datetime "reset_password_sent_at" + t.string "remember_token" t.datetime "remember_created_at" t.datetime "created_at" t.datetime "updated_at" - t.string "uname" t.text "ssh_key" - t.integer "role_id" + t.string "uname" t.string "role" end diff --git a/spec/controllers/settings/notifiers_controller_spec.rb b/spec/controllers/settings/notifiers_controller_spec.rb new file mode 100644 index 000000000..3ffcced81 --- /dev/null +++ b/spec/controllers/settings/notifiers_controller_spec.rb @@ -0,0 +1,5 @@ +require 'spec_helper' + +describe Settings::NotifiersController do + +end diff --git a/spec/factories/settings_notifiers.rb b/spec/factories/settings_notifiers.rb new file mode 100644 index 000000000..d189db60e --- /dev/null +++ b/spec/factories/settings_notifiers.rb @@ -0,0 +1,6 @@ +# Read about factories at http://github.com/thoughtbot/factory_girl + +FactoryGirl.define do + factory :notifier do + end +end \ No newline at end of file diff --git a/spec/helpers/settings/notifiers_helper_spec.rb b/spec/helpers/settings/notifiers_helper_spec.rb new file mode 100644 index 000000000..9b16f8bda --- /dev/null +++ b/spec/helpers/settings/notifiers_helper_spec.rb @@ -0,0 +1,15 @@ +require 'spec_helper' + +# Specs in this file have access to a helper object that includes +# the Settings::NotifiersHelper. For example: +# +# describe Settings::NotifiersHelper do +# describe "string concat" do +# it "concats two strings with spaces" do +# helper.concat_strings("this","that").should == "this that" +# end +# end +# end +describe Settings::NotifiersHelper do + pending "add some examples to (or delete) #{__FILE__}" +end diff --git a/spec/models/settings/notifier_spec.rb b/spec/models/settings/notifier_spec.rb new file mode 100644 index 000000000..fb73cfe7d --- /dev/null +++ b/spec/models/settings/notifier_spec.rb @@ -0,0 +1,5 @@ +require 'spec_helper' + +describe Settings::Notifier do + pending "add some examples to (or delete) #{__FILE__}" +end From c18b71bf0b9971c0571df95bbf67468264bf7139 Mon Sep 17 00:00:00 2001 From: Alexander Machehin Date: Thu, 12 Jan 2012 00:10:23 +0600 Subject: [PATCH 06/67] [refs #18] changed refs id to string --- app/models/issue.rb | 6 +++++- .../20120111080234_change_commentable_id.rb | 9 +++++++++ db/schema.rb | 19 +++++++++++++++++-- 3 files changed, 31 insertions(+), 3 deletions(-) create mode 100644 db/migrate/20120111080234_change_commentable_id.rb diff --git a/app/models/issue.rb b/app/models/issue.rb index 9ae96f439..04ec41356 100644 --- a/app/models/issue.rb +++ b/app/models/issue.rb @@ -4,7 +4,11 @@ class Issue < ActiveRecord::Base belongs_to :project belongs_to :user - has_many :comments, :as => :commentable + has_many :comments, :as => :commentable, + :finder_sql => 'SELECT comments.* FROM comments ' + + 'WHERE comments.commentable_id = \'#{self.id}\' ' + + ' AND comments.commentable_type = \'#{self.class.name}\' ' + + 'ORDER BY comments.created_at' has_many :subscribes, :as => :subscribeable validates :title, :body, :project_id, :presence => true diff --git a/db/migrate/20120111080234_change_commentable_id.rb b/db/migrate/20120111080234_change_commentable_id.rb new file mode 100644 index 000000000..60c3c3268 --- /dev/null +++ b/db/migrate/20120111080234_change_commentable_id.rb @@ -0,0 +1,9 @@ +class ChangeCommentableId < ActiveRecord::Migration + def self.up + change_column :comments, :commentable_id, :string + end + + def self.down + change_column :comments, :commentable_id, :integer + end +end diff --git a/db/schema.rb b/db/schema.rb index c4eb51827..a943f2d61 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended to check this file into your version control system. -ActiveRecord::Schema.define(:version => 20111228182425) do +ActiveRecord::Schema.define(:version => 20120111080234) do create_table "arches", :force => true do |t| t.string "name", :null => false @@ -87,7 +87,7 @@ ActiveRecord::Schema.define(:version => 20111228182425) do end create_table "comments", :force => true do |t| - t.integer "commentable_id" + t.string "commentable_id" t.string "commentable_type" t.integer "user_id" t.text "body" @@ -165,6 +165,13 @@ ActiveRecord::Schema.define(:version => 20111228182425) do add_index "issues", ["project_id", "serial_id"], :name => "index_issues_on_project_id_and_serial_id", :unique => true + create_table "permissions", :force => true do |t| + t.integer "right_id" + t.integer "role_id" + t.datetime "created_at" + t.datetime "updated_at" + end + create_table "platforms", :force => true do |t| t.string "description" t.string "name" @@ -262,6 +269,14 @@ ActiveRecord::Schema.define(:version => 20111228182425) do t.string "owner_type" end + create_table "rights", :force => true do |t| + t.string "name", :null => false + t.string "controller", :null => false + t.string "action", :null => false + t.datetime "created_at" + t.datetime "updated_at" + end + create_table "rpms", :force => true do |t| t.string "name", :null => false t.integer "arch_id", :null => false From 41933604449dd22ff8993fc983ad6dfa0d7b1d5d Mon Sep 17 00:00:00 2001 From: Alexander Machehin Date: Thu, 12 Jan 2012 00:15:35 +0600 Subject: [PATCH 07/67] [refs #18] add comments to commit --- app/controllers/comments_controller.rb | 17 ++++++++++++----- app/models/comment.rb | 3 ++- app/models/project.rb | 14 ++++++++++++-- app/models/repository.rb | 2 +- app/views/comments/_form.html.haml | 2 +- app/views/comments/edit.html.haml | 4 ++-- app/views/git/blobs/show.html.haml | 19 ++++++++++++++++++- app/views/git/commits/show.html.haml | 18 ++++++++++++++++++ config/routes.rb | 17 ++++++++++------- 9 files changed, 76 insertions(+), 20 deletions(-) diff --git a/app/controllers/comments_controller.rb b/app/controllers/comments_controller.rb index 4b70d8127..c295d39f0 100644 --- a/app/controllers/comments_controller.rb +++ b/app/controllers/comments_controller.rb @@ -1,7 +1,7 @@ class CommentsController < ApplicationController before_filter :authenticate_user! before_filter :set_commentable, :only => [:index, :edit, :create] - before_filter :find_project, :only => [:index] + before_filter :find_project, :only => [:index, :edit] before_filter :find_comment, :only => [:edit, :update, :destroy] authorize_resource :only => [:show, :edit, :update, :destroy] @@ -24,8 +24,14 @@ class CommentsController < ApplicationController end def edit - @issue = @commentable - @project = @issue.project + if @commentable + @issue = @commentable + @update_url = project_issue_comment_path(@project, @issue.id, @comment) + end + if @comment.commentable_type == 'Commit' + @commit = @project.git_repository.commit(@comment.commentable_id) + @update_url = project_commit_comment_path(@project, @commit, @comment) + end end def update @@ -55,7 +61,8 @@ class CommentsController < ApplicationController # end #end #nil - return Issue.find(params[:issue_id]) + return nil if params[:issue_id].nil? + Issue.find(params[:issue_id]) end def set_commentable @@ -67,6 +74,6 @@ class CommentsController < ApplicationController end def find_project - @project = @comment.commentable.project + @project = Project.find(params[:project_id]) end end diff --git a/app/models/comment.rb b/app/models/comment.rb index aceb80a7a..aa9dcf11a 100644 --- a/app/models/comment.rb +++ b/app/models/comment.rb @@ -9,7 +9,8 @@ class Comment < ActiveRecord::Base protected def deliver_new_comment_notification - subscribes = self.commentable.subscribes + return if self.commentable_type = 'Commit' + subscribes = self.commentable.try(:subscribes) subscribes.each do |subscribe| recipient = subscribe.user UserMailer.delay.new_comment_notification(self, recipient) diff --git a/app/models/project.rb b/app/models/project.rb index 8ef6d8753..428384b27 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -66,7 +66,7 @@ class Project < ActiveRecord::Base res = tags.select{|tag| tag.name =~ /^v\./} return res if res and res.size > 0 tags - end + end def collected_project_versions project_versions.collect{|tag| tag.name.gsub(/^\w+\./, "")} end @@ -118,7 +118,7 @@ class Project < ActiveRecord::Base return true else raise "Failed to create project #{name} (repo #{repository.name}) inside platform #{repository.platform.name} in path #{path} with code #{result}." - end + end end def xml_rpc_destroy(repository) @@ -134,6 +134,16 @@ class Project < ActiveRecord::Base @platforms ||= repositories.map(&:platform).uniq end + class << self + def commit_comments(commit) + Comment.where(:commentable_id => commit.id, :commentable_type => 'Commit') + end + + def build_commit_comment(commit) + Comment.new(:commentable_id => commit.id, :commentable_type => "Commit") + end + end + protected def build_path(dir) diff --git a/app/models/repository.rb b/app/models/repository.rb index 13c4e2a02..b9246f86a 100644 --- a/app/models/repository.rb +++ b/app/models/repository.rb @@ -48,7 +48,7 @@ class Repository < ActiveRecord::Base return true else raise "Failed to create repository #{name} inside platform #{platform.name} with code #{result}." - end + end end def xml_rpc_destroy diff --git a/app/views/comments/_form.html.haml b/app/views/comments/_form.html.haml index 4078f495e..03d6ce434 100644 --- a/app/views/comments/_form.html.haml +++ b/app/views/comments/_form.html.haml @@ -7,4 +7,4 @@ = image_tag("web-app-theme/icons/tick.png", :alt => t("layout.save")) = t("layout.save") %span.text_button_padding= t("layout.or") - = link_to t("layout.cancel"), [@issue.project, @issue], :class => "text_button_padding link_button" + = link_to t("layout.cancel"), [@project, @issue], :class => "text_button_padding link_button" diff --git a/app/views/comments/edit.html.haml b/app/views/comments/edit.html.haml index 5f2dc3ffd..5b039f318 100644 --- a/app/views/comments/edit.html.haml +++ b/app/views/comments/edit.html.haml @@ -1,10 +1,10 @@ .block .secondary-navigation %ul.wat-cf - %li.first= link_to t("layout.issues.list"), project_issue_path(@project, @issue) + %li.first= link_to t("layout.issues.list"), @issue ? project_issue_path(@project, @issue) : commit_path(@project, @commit) .content %h2.title = t("layout.issues.edit_header") .inner - = form_for @comment, :url => project_issue_comment_path(@project, @issue.id, @comment), :html => { :class => :form } do |f| + = form_for @comment, :url => @update_url, :html => { :class => :form } do |f| = render :partial => "form", :locals => {:f => f} diff --git a/app/views/git/blobs/show.html.haml b/app/views/git/blobs/show.html.haml index 2059f0a03..b9c8e79a8 100644 --- a/app/views/git/blobs/show.html.haml +++ b/app/views/git/blobs/show.html.haml @@ -31,4 +31,21 @@ :plain
#{render_blob(@blob)}
-- content_for :sidebar, render(:partial => 'git/shared/sidebar') \ No newline at end of file +- content_for :sidebar, render(:partial => 'git/shared/sidebar') + +%a{ :name => "comments" } +.block#block-list + .content + %h2.title + = t("layout.issues.comments_header") + .inner + %ul.list + - @project.commit_comments(@commit).each do |comment| + %li + .left + = link_to comment.user.uname, user_path(comment.user.uname) + .item + = comment.body + %br + %br + diff --git a/app/views/git/commits/show.html.haml b/app/views/git/commits/show.html.haml index e5d39833e..bb45ade99 100644 --- a/app/views/git/commits/show.html.haml +++ b/app/views/git/commits/show.html.haml @@ -26,3 +26,21 @@ %p= t 'layout.git.repositories.commit_diff_too_big' - content_for :sidebar, render(:partial => 'git/shared/sidebar') + +%a{ :name => "comments" } +.block#block-list + .content + %h2.title + = t("layout.issues.comments_header") + .inner + %ul.list + - Project.commit_comments(@commit).each do |comment| + %li + .left + = link_to comment.user.uname, user_path(comment.user.uname) + .item + = comment.body + %br + %br + = link_to t("layout.edit"), edit_project_commit_comment_path(@project, @commit, comment) if can? :update, comment + = link_to image_tag("web-app-theme/icons/cross.png", :alt => t("layout.delete")) + " " + t("layout.delete"), project_commit_comment_path(@project, @commit, comment), :method => "delete", :class => "button", :confirm => t("layout.comments.confirm_delete") if can? :delete, comment diff --git a/config/routes.rb b/config/routes.rb index 7f3449cde..253b886f7 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,11 +1,11 @@ Rosa::Application.routes.draw do # XML RPC match 'api/xmlrpc' => 'rpc#xe_index' - + devise_for :users, :controllers => {:omniauth_callbacks => 'users/omniauth_callbacks'} do get '/users/auth/:provider' => 'users/omniauth_callbacks#passthru' end - + resources :users do resources :groups, :only => [:new, :create, :index] get :autocomplete_user_uname, :on => :collection @@ -142,20 +142,23 @@ Rosa::Application.routes.draw do # Tree match '/projects/:project_id/git/tree/:treeish(/*path)', :controller => "git/trees", :action => :show, :treeish => /[0-9a-zA-Z_.\-]*/, :defaults => { :treeish => :master }, :as => :tree - + # Commits match '/projects/:project_id/git/commits/:treeish(/*path)', :controller => "git/commits", :action => :index, :treeish => /[0-9a-zA-Z_.\-]*/, :defaults => { :treeish => :master }, :as => :commits match '/projects/:project_id/git/commit/:id(.:format)', :controller => "git/commits", :action => :show, :defaults => { :format => :html }, :as => :commit - + # Commit Comments + match '/projects/:project_id/git/commit/:commit_id/:id(.:format)', :controller => "comments", :action => :edit, :as => :edit_project_commit_comment, :via => :get + match '/projects/:project_id/git/commit/:commit_id/:id(.:format)', :controller => "comments", :action => :update, :as => :project_commit_comment, :via => :put + match '/projects/:project_id/git/commit/:commit_id/:id(.:format)', :controller => "comments", :action => :delete, :via => :delete # Blobs match '/projects/:project_id/git/blob/:treeish/*path', :controller => "git/blobs", :action => :show, :treeish => /[0-9a-zA-Z_.\-]*/, :defaults => { :treeish => :master }, :as => :blob match '/projects/:project_id/git/commit/blob/:commit_hash/*path', :controller => "git/blobs", :action => :show, :project_name => /[0-9a-zA-Z_.\-]*/, :as => :blob_commit - + # Blame match '/projects/:project_id/git/blame/:treeish/*path', :controller => "git/blobs", :action => :blame, :treeish => /[0-9a-zA-Z_.\-]*/, :defaults => { :treeish => :master }, :as => :blame match '/projects/:project_id/git/commit/blame/:commit_hash/*path', :controller => "git/blobs", :action => :blame, :as => :blame_commit - - # Raw + + # Raw match '/projects/:project_id/git/raw/:treeish/*path', :controller => "git/blobs", :action => :raw, :treeish => /[0-9a-zA-Z_.\-]*/, :defaults => { :treeish => :master }, :as => :raw match '/projects/:project_id/git/commit/raw/:commit_hash/*path', :controller => "git/blobs", :action => :raw, :as => :raw_commit From 07dc7a48007ef111839063805f387d630105a2e1 Mon Sep 17 00:00:00 2001 From: Alexander Machehin Date: Thu, 12 Jan 2012 00:15:35 +0600 Subject: [PATCH 08/67] [refs #18] add comments to commit --- app/controllers/comments_controller.rb | 29 ++++++++++++++++------- app/controllers/git/commits_controller.rb | 2 +- app/models/comment.rb | 3 ++- app/models/project.rb | 10 ++++++-- app/models/repository.rb | 2 +- app/views/comments/_form.html.haml | 2 +- app/views/comments/edit.html.haml | 4 ++-- app/views/git/blobs/show.html.haml | 19 ++++++++++++++- app/views/git/commits/show.html.haml | 26 ++++++++++++++++++++ config/routes.rb | 18 ++++++++------ 10 files changed, 90 insertions(+), 25 deletions(-) diff --git a/app/controllers/comments_controller.rb b/app/controllers/comments_controller.rb index 4b70d8127..da4bfc127 100644 --- a/app/controllers/comments_controller.rb +++ b/app/controllers/comments_controller.rb @@ -1,8 +1,8 @@ class CommentsController < ApplicationController before_filter :authenticate_user! - before_filter :set_commentable, :only => [:index, :edit, :create] - before_filter :find_project, :only => [:index] before_filter :find_comment, :only => [:edit, :update, :destroy] + before_filter :set_commentable, :only => [:index, :edit, :create, :update] + #before_filter :find_project, :only => [:index, :edit] authorize_resource :only => [:show, :edit, :update, :destroy] authorize_resource :project, :only => [:index] @@ -12,11 +12,12 @@ class CommentsController < ApplicationController end def create - @comment = @commentable.comments.build(params[:comment]) + @comment = @commentable.comments.build(params[:comment]) if @commentable.class == Issue + @comment = Comment.new(params[:comment].merge(:commentable_id => @commentable.id, :commentable_type => @commentable.class.name)) if @commentable.class == Grit::Commit @comment.user = current_user if @comment.save flash[:notice] = I18n.t("flash.comment.saved") - redirect_to [@commentable.project, @commentable] + redirect_to :back else flash[:error] = I18n.t("flash.comment.save_error") render :action => 'new' @@ -24,15 +25,19 @@ class CommentsController < ApplicationController end def edit - @issue = @commentable - @project = @issue.project + @update_url = case @commentable.class.name + when "Issue" + project_issue_comment_path(@project, @commentable, @comment) + when "Grit::Commit" + project_commit_comment_path(@project, @commentable.id, @comment) + end end def update if @comment.update_attributes(params[:comment]) flash[:notice] = I18n.t("flash.comment.saved") #redirect_to :back - redirect_to [@comment.commentable.project, @comment.commentable] + redirect_to @commentable_path else flash[:error] = I18n.t("flash.comment.save_error") render :action => 'new' @@ -55,11 +60,17 @@ class CommentsController < ApplicationController # end #end #nil - return Issue.find(params[:issue_id]) + if params[:issue_id].present? + return Issue.find(params[:issue_id]) + elsif params[:commit_id].present? + return @project.git_repository.commit(params[:commit_id]) + end end def set_commentable + find_project @commentable = find_commentable + @commentable_path = @commentable.class == Issue ? project_issue_path(@project, @commentable) : commit_path(@project.id, @commentable.id) end def find_comment @@ -67,6 +78,6 @@ class CommentsController < ApplicationController end def find_project - @project = @comment.commentable.project + @project = Project.find(params[:project_id]) end end diff --git a/app/controllers/git/commits_controller.rb b/app/controllers/git/commits_controller.rb index 04b1a94dc..021d60cee 100644 --- a/app/controllers/git/commits_controller.rb +++ b/app/controllers/git/commits_controller.rb @@ -23,4 +23,4 @@ class Git::CommitsController < Git::BaseController end end -end \ No newline at end of file +end diff --git a/app/models/comment.rb b/app/models/comment.rb index aceb80a7a..aa9dcf11a 100644 --- a/app/models/comment.rb +++ b/app/models/comment.rb @@ -9,7 +9,8 @@ class Comment < ActiveRecord::Base protected def deliver_new_comment_notification - subscribes = self.commentable.subscribes + return if self.commentable_type = 'Commit' + subscribes = self.commentable.try(:subscribes) subscribes.each do |subscribe| recipient = subscribe.user UserMailer.delay.new_comment_notification(self, recipient) diff --git a/app/models/project.rb b/app/models/project.rb index 8ef6d8753..82dd4f563 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -66,7 +66,7 @@ class Project < ActiveRecord::Base res = tags.select{|tag| tag.name =~ /^v\./} return res if res and res.size > 0 tags - end + end def collected_project_versions project_versions.collect{|tag| tag.name.gsub(/^\w+\./, "")} end @@ -118,7 +118,7 @@ class Project < ActiveRecord::Base return true else raise "Failed to create project #{name} (repo #{repository.name}) inside platform #{repository.platform.name} in path #{path} with code #{result}." - end + end end def xml_rpc_destroy(repository) @@ -134,6 +134,12 @@ class Project < ActiveRecord::Base @platforms ||= repositories.map(&:platform).uniq end + class << self + def commit_comments(commit) + Comment.where(:commentable_id => commit.id, :commentable_type => 'Commit') + end + end + protected def build_path(dir) diff --git a/app/models/repository.rb b/app/models/repository.rb index 13c4e2a02..b9246f86a 100644 --- a/app/models/repository.rb +++ b/app/models/repository.rb @@ -48,7 +48,7 @@ class Repository < ActiveRecord::Base return true else raise "Failed to create repository #{name} inside platform #{platform.name} with code #{result}." - end + end end def xml_rpc_destroy diff --git a/app/views/comments/_form.html.haml b/app/views/comments/_form.html.haml index 4078f495e..03d6ce434 100644 --- a/app/views/comments/_form.html.haml +++ b/app/views/comments/_form.html.haml @@ -7,4 +7,4 @@ = image_tag("web-app-theme/icons/tick.png", :alt => t("layout.save")) = t("layout.save") %span.text_button_padding= t("layout.or") - = link_to t("layout.cancel"), [@issue.project, @issue], :class => "text_button_padding link_button" + = link_to t("layout.cancel"), [@project, @issue], :class => "text_button_padding link_button" diff --git a/app/views/comments/edit.html.haml b/app/views/comments/edit.html.haml index 5f2dc3ffd..b5bbe01c4 100644 --- a/app/views/comments/edit.html.haml +++ b/app/views/comments/edit.html.haml @@ -1,10 +1,10 @@ .block .secondary-navigation %ul.wat-cf - %li.first= link_to t("layout.issues.list"), project_issue_path(@project, @issue) + %li.first= link_to t("layout.issues.list"), @commentable_path .content %h2.title = t("layout.issues.edit_header") .inner - = form_for @comment, :url => project_issue_comment_path(@project, @issue.id, @comment), :html => { :class => :form } do |f| + = form_for @comment, :url => @update_url, :html => { :class => :form } do |f| = render :partial => "form", :locals => {:f => f} diff --git a/app/views/git/blobs/show.html.haml b/app/views/git/blobs/show.html.haml index 2059f0a03..b9c8e79a8 100644 --- a/app/views/git/blobs/show.html.haml +++ b/app/views/git/blobs/show.html.haml @@ -31,4 +31,21 @@ :plain
#{render_blob(@blob)}
-- content_for :sidebar, render(:partial => 'git/shared/sidebar') \ No newline at end of file +- content_for :sidebar, render(:partial => 'git/shared/sidebar') + +%a{ :name => "comments" } +.block#block-list + .content + %h2.title + = t("layout.issues.comments_header") + .inner + %ul.list + - @project.commit_comments(@commit).each do |comment| + %li + .left + = link_to comment.user.uname, user_path(comment.user.uname) + .item + = comment.body + %br + %br + diff --git a/app/views/git/commits/show.html.haml b/app/views/git/commits/show.html.haml index e5d39833e..25269c581 100644 --- a/app/views/git/commits/show.html.haml +++ b/app/views/git/commits/show.html.haml @@ -26,3 +26,29 @@ %p= t 'layout.git.repositories.commit_diff_too_big' - content_for :sidebar, render(:partial => 'git/shared/sidebar') + +%a{ :name => "comments" } +.block#block-list + .content + %h2.title + = t("layout.issues.comments_header") + .inner + %ul.list + - Project.commit_comments(@commit).each do |comment| + %li + .left + = link_to comment.user.uname, user_path(comment.user.uname) + .item + = comment.body + %br + %br + = link_to t("layout.edit"), edit_project_commit_comment_path(@project, @commit.id, comment) if can? :update, comment + = link_to image_tag("web-app-theme/icons/cross.png", :alt => t("layout.delete")) + " " + t("layout.delete"), project_commit_comment_path(@project, @commit.id, comment), :method => "delete", :class => "button", :confirm => t("layout.comments.confirm_delete") if can? :delete, comment + +.block + .content + %h2.title + = t("layout.comments.new_header") + .inner + = form_for :comment, :url => project_commit_comments_path(@project, @commit.id), :method => :post, :html => { :class => :form } do |f| + = render :partial => "comments/form", :locals => {:f => f} diff --git a/config/routes.rb b/config/routes.rb index 7f3449cde..5cd3cc3c1 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,11 +1,11 @@ Rosa::Application.routes.draw do # XML RPC match 'api/xmlrpc' => 'rpc#xe_index' - + devise_for :users, :controllers => {:omniauth_callbacks => 'users/omniauth_callbacks'} do get '/users/auth/:provider' => 'users/omniauth_callbacks#passthru' end - + resources :users do resources :groups, :only => [:new, :create, :index] get :autocomplete_user_uname, :on => :collection @@ -142,20 +142,24 @@ Rosa::Application.routes.draw do # Tree match '/projects/:project_id/git/tree/:treeish(/*path)', :controller => "git/trees", :action => :show, :treeish => /[0-9a-zA-Z_.\-]*/, :defaults => { :treeish => :master }, :as => :tree - + # Commits match '/projects/:project_id/git/commits/:treeish(/*path)', :controller => "git/commits", :action => :index, :treeish => /[0-9a-zA-Z_.\-]*/, :defaults => { :treeish => :master }, :as => :commits match '/projects/:project_id/git/commit/:id(.:format)', :controller => "git/commits", :action => :show, :defaults => { :format => :html }, :as => :commit - + # Commit Comments + match '/projects/:project_id/git/commit/:commit_id/comments/:id(.:format)', :controller => "comments", :action => :edit, :as => :edit_project_commit_comment, :via => :get + match '/projects/:project_id/git/commit/:commit_id/comments/:id(.:format)', :controller => "comments", :action => :update, :as => :project_commit_comment, :via => :put + match '/projects/:project_id/git/commit/:commit_id/comments/:id(.:format)', :controller => "comments", :action => :destroy, :via => :delete + match '/projects/:project_id/git/commit/:commit_id/comments(.:format)', :controller => "comments", :action => :create, :as => :project_commit_comments, :via => :post # Blobs match '/projects/:project_id/git/blob/:treeish/*path', :controller => "git/blobs", :action => :show, :treeish => /[0-9a-zA-Z_.\-]*/, :defaults => { :treeish => :master }, :as => :blob match '/projects/:project_id/git/commit/blob/:commit_hash/*path', :controller => "git/blobs", :action => :show, :project_name => /[0-9a-zA-Z_.\-]*/, :as => :blob_commit - + # Blame match '/projects/:project_id/git/blame/:treeish/*path', :controller => "git/blobs", :action => :blame, :treeish => /[0-9a-zA-Z_.\-]*/, :defaults => { :treeish => :master }, :as => :blame match '/projects/:project_id/git/commit/blame/:commit_hash/*path', :controller => "git/blobs", :action => :blame, :as => :blame_commit - - # Raw + + # Raw match '/projects/:project_id/git/raw/:treeish/*path', :controller => "git/blobs", :action => :raw, :treeish => /[0-9a-zA-Z_.\-]*/, :defaults => { :treeish => :master }, :as => :raw match '/projects/:project_id/git/commit/raw/:commit_hash/*path', :controller => "git/blobs", :action => :raw, :as => :raw_commit From f8d00f52353b0ad4412c0c6111ff367e96fc0dd3 Mon Sep 17 00:00:00 2001 From: Alexander Machehin Date: Thu, 12 Jan 2012 17:22:12 +0600 Subject: [PATCH 09/67] [refs #18] Fix cancan ability for commit comments --- app/models/ability.rb | 11 ++++++----- app/models/comment.rb | 1 + app/models/project.rb | 5 +++-- app/views/git/commits/show.html.haml | 2 +- 4 files changed, 11 insertions(+), 8 deletions(-) diff --git a/app/models/ability.rb b/app/models/ability.rb index 1b7509a2b..0c1684db0 100644 --- a/app/models/ability.rb +++ b/app/models/ability.rb @@ -1,8 +1,8 @@ # If rules goes one by one CanCan joins them by 'OR' sql operator # If rule has multiple conditions CanCan joins them by 'AND' sql operator -# WARNING: +# WARNING: # - put cannot rules _after_ can rules and not before! -# - beware inner joins. Use sub queries against them! +# - beware inner joins. Use sub queries against them! class Ability include CanCan::Ability @@ -89,9 +89,10 @@ class Ability can([:update, :destroy], Issue) {|issue| issue.user_id == user.id or local_admin?(issue.project)} cannot :manage, Issue, :project => {:has_issues => false} # switch off issues - can(:create, Comment) {|comment| can? :read, comment.commentable.project} - can(:update, Comment) {|comment| comment.user_id == user.id or local_admin?(comment.commentable.project)} - cannot :manage, Comment, :commentable => {:project => {:has_issues => false}} # switch off issues + can(:create, Comment) {|comment| can? :read, comment.project || comment.commentable.project} + can([:update, :delete], Comment) {|comment| comment.user_id == user.id or local_admin?(comment.project || comment.commentable.project)} + #cannot :manage, Comment, :commentable => {:project => {:has_issues => false}} # switch off issues + cannot(:manage, Comment) {|comment| comment.commentable_type == 'Issue' && !comment.commentable.project.has_issues} # switch off issues end end diff --git a/app/models/comment.rb b/app/models/comment.rb index aa9dcf11a..6925a28d7 100644 --- a/app/models/comment.rb +++ b/app/models/comment.rb @@ -1,6 +1,7 @@ class Comment < ActiveRecord::Base belongs_to :commentable, :polymorphic => true belongs_to :user + attr_accessor :project validates :body, :user_id, :commentable_id, :commentable_type, :presence => true diff --git a/app/models/project.rb b/app/models/project.rb index 82dd4f563..4cc5c143c 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -135,8 +135,9 @@ class Project < ActiveRecord::Base end class << self - def commit_comments(commit) - Comment.where(:commentable_id => commit.id, :commentable_type => 'Commit') + def commit_comments(commit, project) + comments = Comment.where(:commentable_id => commit.id, :commentable_type => 'Grit::Commit') + comments.each {|x| x.project = project} end end diff --git a/app/views/git/commits/show.html.haml b/app/views/git/commits/show.html.haml index 25269c581..421c5d2e2 100644 --- a/app/views/git/commits/show.html.haml +++ b/app/views/git/commits/show.html.haml @@ -34,7 +34,7 @@ = t("layout.issues.comments_header") .inner %ul.list - - Project.commit_comments(@commit).each do |comment| + - Project.commit_comments(@commit, @project).each do |comment| %li .left = link_to comment.user.uname, user_path(comment.user.uname) From f6e4de3b727d20e30d735515be1c680caf06b242 Mon Sep 17 00:00:00 2001 From: "konstantin.grabar" Date: Thu, 12 Jan 2012 17:07:54 +0400 Subject: [PATCH 10/67] [refs #54] Fix issue assign user subscribe update filter --- app/controllers/issues_controller.rb | 4 ++-- app/models/issue.rb | 10 ++++++++++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/app/controllers/issues_controller.rb b/app/controllers/issues_controller.rb index 3f1a6f4ec..af02d409c 100644 --- a/app/controllers/issues_controller.rb +++ b/app/controllers/issues_controller.rb @@ -41,12 +41,12 @@ class IssuesController < ApplicationController def edit @user_id = @issue.user_id - @user_uname = @issue.user.uname + @user_uname = @issue.assign_uname end def update @user_id = params[:user_id].blank? ? @issue.user_id : params[:user_id] - @user_uname = params[:user_uname].blank? ? @issue.user.uname : params[:user_uname] + @user_uname = params[:user_uname].blank? ? @issue.assign_uname : params[:user_uname] if @issue.update_attributes( params[:issue].merge({:user_id => @user_id}) ) flash[:notice] = I18n.t("flash.issue.saved") diff --git a/app/models/issue.rb b/app/models/issue.rb index 193254e47..5bdde0246 100644 --- a/app/models/issue.rb +++ b/app/models/issue.rb @@ -16,6 +16,7 @@ class Issue < ActiveRecord::Base after_create :deliver_new_issue_notification after_create :deliver_issue_assign_notification after_update :deliver_issue_assign_notification + after_update :subscribe_issue_assigned_user def assign_uname user.uname if user @@ -64,4 +65,13 @@ class Issue < ActiveRecord::Base recipients end + + def subscribe_issue_assigned_user + if self.user_id_was != self.user_id + self.subscribes.where(:user_id => self.user_id_was).first.destroy + if self.user.notifier.issue_assign && !self.subscribes.exists?(:user_id => self.user_id) + self.subscribes.create(:user_id => self.user_id) + end + end + end end From 980e455b31e221df57d06baaacbe15ae4314c572 Mon Sep 17 00:00:00 2001 From: "konstantin.grabar" Date: Thu, 12 Jan 2012 17:45:22 +0400 Subject: [PATCH 11/67] [refs #54] Fix comment deliver notification user check --- app/models/comment.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/comment.rb b/app/models/comment.rb index aceb80a7a..1f8d3b779 100644 --- a/app/models/comment.rb +++ b/app/models/comment.rb @@ -12,7 +12,7 @@ class Comment < ActiveRecord::Base subscribes = self.commentable.subscribes subscribes.each do |subscribe| recipient = subscribe.user - UserMailer.delay.new_comment_notification(self, recipient) + UserMailer.delay.new_comment_notification(self, recipient) unless self.user_id == subscribe.user_id end end end From 636c90e6e42d8ea5416ce6b50449b9a515b22669 Mon Sep 17 00:00:00 2001 From: Alexander Machehin Date: Thu, 12 Jan 2012 20:27:33 +0600 Subject: [PATCH 12/67] [refs #18] add some I18n --- app/views/comments/edit.html.haml | 4 ++-- config/locales/ru.yml | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/app/views/comments/edit.html.haml b/app/views/comments/edit.html.haml index b5bbe01c4..eb586af80 100644 --- a/app/views/comments/edit.html.haml +++ b/app/views/comments/edit.html.haml @@ -1,10 +1,10 @@ .block .secondary-navigation %ul.wat-cf - %li.first= link_to t("layout.issues.list"), @commentable_path + %li.first= link_to t(@comment.commentable_type == 'Grit::Commit' ? "layout.git.repositories.commits" : "layout.issues.list"), @commentable_path .content %h2.title - = t("layout.issues.edit_header") + = t("layout.#{@comment.commentable_type == 'Grit::Commit' ? 'comments' : 'issues'}.edit_header") .inner = form_for @comment, :url => @update_url, :html => { :class => :form } do |f| = render :partial => "form", :locals => {:f => f} diff --git a/config/locales/ru.yml b/config/locales/ru.yml index ef20defa1..dfa655fc9 100644 --- a/config/locales/ru.yml +++ b/config/locales/ru.yml @@ -114,6 +114,7 @@ ru: comments: confirm_delete: Вы уверены, что хотите удалить комментарий? new_header: Новый комментарий + edit_header: Редактирование комментария platforms: admin_id: Владелец From 630346d2e30dc284d4ae08702aabad2df9f2a675 Mon Sep 17 00:00:00 2001 From: Alexander Machehin Date: Thu, 12 Jan 2012 20:48:08 +0600 Subject: [PATCH 13/67] [refs #18] fix cancel button --- app/views/comments/_form.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/comments/_form.html.haml b/app/views/comments/_form.html.haml index 03d6ce434..462aca983 100644 --- a/app/views/comments/_form.html.haml +++ b/app/views/comments/_form.html.haml @@ -7,4 +7,4 @@ = image_tag("web-app-theme/icons/tick.png", :alt => t("layout.save")) = t("layout.save") %span.text_button_padding= t("layout.or") - = link_to t("layout.cancel"), [@project, @issue], :class => "text_button_padding link_button" + = link_to t("layout.cancel"), :back , :class => "text_button_padding link_button" From caf7adef70cbf62889220c1f63045c4be1f7592f Mon Sep 17 00:00:00 2001 From: Alexander Machehin Date: Thu, 12 Jan 2012 20:50:27 +0600 Subject: [PATCH 14/67] [refs #18] FIXME subscribe don't work --- app/models/comment.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/models/comment.rb b/app/models/comment.rb index 6925a28d7..6f3c6045a 100644 --- a/app/models/comment.rb +++ b/app/models/comment.rb @@ -10,8 +10,8 @@ class Comment < ActiveRecord::Base protected def deliver_new_comment_notification - return if self.commentable_type = 'Commit' - subscribes = self.commentable.try(:subscribes) + return if self.commentable_type == 'Grit::Commit' # FIXME + subscribes = self.commentable.subscribes subscribes.each do |subscribe| recipient = subscribe.user UserMailer.delay.new_comment_notification(self, recipient) From db0a66846bb00563fff6fa98cea551d16df75f0d Mon Sep 17 00:00:00 2001 From: "konstantin.grabar" Date: Fri, 13 Jan 2012 19:07:01 +0400 Subject: [PATCH 15/67] [refs #94] Add new notifier rules. Fix some issues and comments bugs --- app/controllers/issues_controller.rb | 3 +++ app/mailers/user_mailer.rb | 8 ++++++++ app/models/comment.rb | 13 ++++++++++++- app/models/issue.rb | 16 +++++++++++----- app/views/issues/index.html.haml | 2 +- app/views/settings/notifiers/_form.html.haml | 14 ++++++++++---- .../new_comment_reply_notification.haml | 9 +++++++++ config/locales/ru.yml | 1 + .../20120111072106_create_settings_notifiers.rb | 2 ++ ...20113121748_add_issue_status_default_value.rb | 9 +++++++++ db/schema.rb | 5 +++-- public/javascripts/application.js | 14 ++++++++++++++ 12 files changed, 83 insertions(+), 13 deletions(-) create mode 100644 app/views/user_mailer/new_comment_reply_notification.haml create mode 100644 db/migrate/20120113121748_add_issue_status_default_value.rb diff --git a/app/controllers/issues_controller.rb b/app/controllers/issues_controller.rb index af02d409c..99f13be95 100644 --- a/app/controllers/issues_controller.rb +++ b/app/controllers/issues_controller.rb @@ -30,7 +30,10 @@ class IssuesController < ApplicationController @issue = Issue.new(params[:issue]) @issue.user_id = @user_id @issue.project_id = @project.id + if @issue.save + @issue.subscribe_creator(current_user.id) + flash[:notice] = I18n.t("flash.issue.saved") redirect_to project_issues_path(@project) else diff --git a/app/mailers/user_mailer.rb b/app/mailers/user_mailer.rb index 9be195dd4..39ceffa17 100644 --- a/app/mailers/user_mailer.rb +++ b/app/mailers/user_mailer.rb @@ -18,6 +18,14 @@ class UserMailer < ActionMailer::Base end end + def new_comment_reply_notification(comment, user) + @user = user + @comment = comment + mail(:to => user.email, :subject => I18n.t("notifications.subjects.new_comment_reply_notification")) do |format| + format.html + end + end + def new_issue_notification(issue, user) @user = user @issue = issue diff --git a/app/models/comment.rb b/app/models/comment.rb index 1f8d3b779..41ba6602e 100644 --- a/app/models/comment.rb +++ b/app/models/comment.rb @@ -4,6 +4,7 @@ class Comment < ActiveRecord::Base validates :body, :user_id, :commentable_id, :commentable_type, :presence => true + after_create :subscribe_on_reply after_create :deliver_new_comment_notification protected @@ -12,7 +13,17 @@ class Comment < ActiveRecord::Base subscribes = self.commentable.subscribes subscribes.each do |subscribe| recipient = subscribe.user - UserMailer.delay.new_comment_notification(self, recipient) unless self.user_id == subscribe.user_id + if self.user_id != subscribe.user_id && User.find(recipient).notifier.new_comment_reply && User.find(recipient).notifier.can_notify + if self.commentable.comments.exists?(:user_id => recipient.id) + UserMailer.delay.new_comment_reply_notification(self, recipient) + else + UserMailer.delay.new_comment_notification(self, recipient) + end + end end end + + def subscribe_on_reply + self.commentable.subscribes.create(:user_id => self.user_id) if !self.commentable.subscribes.exists?(:user_id => self.user_id) + end end diff --git a/app/models/issue.rb b/app/models/issue.rb index 5bdde0246..d7a16af35 100644 --- a/app/models/issue.rb +++ b/app/models/issue.rb @@ -26,6 +26,12 @@ class Issue < ActiveRecord::Base serial_id.to_s end + def subscribe_creator(creator_id) + if !self.subscribes.exists?(:user_id => creator_id) + self.subscribes.create(:user_id => creator_id) + end + end + protected def set_serial_id @@ -37,12 +43,12 @@ class Issue < ActiveRecord::Base recipients = collect_recipient_ids recipients.each do |recipient_id| recipient = User.find(recipient_id) - UserMailer.delay.new_issue_notification(self, recipient)#.deliver + UserMailer.delay.new_issue_notification(self, recipient) if User.find(recipient).notifier.can_notify && User.find(recipient).notifier.new_issue end end def deliver_issue_assign_notification - UserMailer.delay.issue_assign_notification(self, self.user) if self.user_id_was != self.user_id && self.user.notifier.issue_assign + UserMailer.delay.issue_assign_notification(self, self.user) if self.user_id_was != self.user_id && self.user.notifier.issue_assign && self.user.notifier.can_notify end def subscribe_users @@ -60,7 +66,7 @@ class Issue < ActiveRecord::Base # filter by notification settings recipients = recipients.select do |recipient| - User.find(recipient).notifier.new_issue + User.find(recipient).notifier.new_issue && User.find(recipient).notifier.can_notify end recipients @@ -68,9 +74,9 @@ class Issue < ActiveRecord::Base def subscribe_issue_assigned_user if self.user_id_was != self.user_id - self.subscribes.where(:user_id => self.user_id_was).first.destroy + self.subscribes.where(:user_id => self.user_id_was).first.destroy unless self.user_id_was.blank? if self.user.notifier.issue_assign && !self.subscribes.exists?(:user_id => self.user_id) - self.subscribes.create(:user_id => self.user_id) + self.subscribes.create(:user_id => self.user_id) end end end diff --git a/app/views/issues/index.html.haml b/app/views/issues/index.html.haml index ea6a25a13..9f1c6306d 100644 --- a/app/views/issues/index.html.haml +++ b/app/views/issues/index.html.haml @@ -19,4 +19,4 @@ = render :partial => 'issues/list' .actions-bar.wat-cf .actions - = will_paginate @issues, :param_name => :issue_page + = will_paginate @issues#, :param_name => :issue_page diff --git a/app/views/settings/notifiers/_form.html.haml b/app/views/settings/notifiers/_form.html.haml index 140de2655..2631874bc 100644 --- a/app/views/settings/notifiers/_form.html.haml +++ b/app/views/settings/notifiers/_form.html.haml @@ -1,18 +1,22 @@ +.group + = f.label :can_notify, t('activerecord.attributes.settings.notifier.can_notify'), :class => :label + = f.check_box :can_notify#, :class => 'text_field' + .group = f.label :new_comment, t('activerecord.attributes.settings.notifier.new_comment'), :class => :label - = f.check_box :new_comment#, :class => 'text_field' + = f.check_box :new_comment, :class => 'notify_cbx' .group = f.label :new_comment_reply, t('activerecord.attributes.settings.notifier.new_comment_reply'), :class => :label - = f.check_box :new_comment_reply#, :class => 'text_field' + = f.check_box :new_comment_reply, :class => 'notify_cbx' .group = f.label :new_issue, t('activerecord.attributes.settings.notifier.new_issue'), :class => :label - = f.check_box :new_issue#, :class => 'text_field' + = f.check_box :new_issue, :class => 'notify_cbx' .group = f.label :issue_assign, t('activerecord.attributes.settings.notifier.issue_assign'), :class => :label - = f.check_box :issue_assign#, :class => 'text_field' + = f.check_box :issue_assign, :class => 'notify_cbx' .group.navform.wat-cf %button.button{:type => "submit"} @@ -21,3 +25,5 @@ %span.text_button_padding= t("layout.or") = link_to t("layout.cancel"), user_settings_notifier_path(@user), :class => "text_button_padding link_button" +:javascript + disableNotifierCbx($('#settings_notifier_can_notify')); diff --git a/app/views/user_mailer/new_comment_reply_notification.haml b/app/views/user_mailer/new_comment_reply_notification.haml new file mode 100644 index 000000000..48ff0ab4b --- /dev/null +++ b/app/views/user_mailer/new_comment_reply_notification.haml @@ -0,0 +1,9 @@ +%p== Здравствуйте, #{@user.name}. + + +%p На Ваш комментарий в задаче #{ link_to @comment.commentable.title, [@comment.commentable.project, @comment.commentable] } был дан ответ. + +%p "#{ @comment.body }" + + +%p== Команда поддержки «ROSA Build System» diff --git a/config/locales/ru.yml b/config/locales/ru.yml index a9bffa4a5..b0e848110 100644 --- a/config/locales/ru.yml +++ b/config/locales/ru.yml @@ -493,6 +493,7 @@ ru: attributes: settings: notifier: + can_notify: Включить оповещения по электронной почте new_comment: Оповещать о новом комментарии в задаче new_comment_reply: Оповещать о новом ответе на мой комментарий new_issue: Оповещать о новых задачах в моих проектах diff --git a/db/migrate/20120111072106_create_settings_notifiers.rb b/db/migrate/20120111072106_create_settings_notifiers.rb index ab8da3aaf..b8517a9e9 100644 --- a/db/migrate/20120111072106_create_settings_notifiers.rb +++ b/db/migrate/20120111072106_create_settings_notifiers.rb @@ -2,6 +2,8 @@ class CreateSettingsNotifiers < ActiveRecord::Migration def self.up create_table :settings_notifiers do |t| t.integer :user_id, :null => false + + t.boolean :can_notify, :default => true t.boolean :new_comment, :default => true t.boolean :new_comment_reply, :default => true t.boolean :new_issue, :default => true diff --git a/db/migrate/20120113121748_add_issue_status_default_value.rb b/db/migrate/20120113121748_add_issue_status_default_value.rb new file mode 100644 index 000000000..bbc58f3cc --- /dev/null +++ b/db/migrate/20120113121748_add_issue_status_default_value.rb @@ -0,0 +1,9 @@ +class AddIssueStatusDefaultValue < ActiveRecord::Migration + def self.up + change_column :issues, :status, :string, :default => 'open' + end + + def self.down + change_column :issues, :status, :string, :null => true + end +end diff --git a/db/schema.rb b/db/schema.rb index b91476bc7..d1c2da240 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended to check this file into your version control system. -ActiveRecord::Schema.define(:version => 20120111135443) do +ActiveRecord::Schema.define(:version => 20120113121748) do create_table "arches", :force => true do |t| t.string "name", :null => false @@ -158,7 +158,7 @@ ActiveRecord::Schema.define(:version => 20120111135443) do t.integer "user_id" t.string "title" t.text "body" - t.string "status" + t.string "status", :default => "open" t.datetime "created_at" t.datetime "updated_at" end @@ -274,6 +274,7 @@ ActiveRecord::Schema.define(:version => 20120111135443) do create_table "settings_notifiers", :force => true do |t| t.integer "user_id", :null => false + t.boolean "can_notify", :default => true t.boolean "new_comment", :default => true t.boolean "new_comment_reply", :default => true t.boolean "new_issue", :default => true diff --git a/public/javascripts/application.js b/public/javascripts/application.js index b2617a1c7..2ab692666 100644 --- a/public/javascripts/application.js +++ b/public/javascripts/application.js @@ -1,3 +1,13 @@ +function disableNotifierCbx(global_cbx) { + if ($(global_cbx).attr('checked')) { + $('.notify_cbx').removeAttr('disabled'); + $('.notify_cbx').each(function(i,el) { $(el).prev().removeAttr('disabled'); }) + } else { + $('.notify_cbx').attr('disabled', 'disabled'); + $('.notify_cbx').each(function(i,el) { $(el).prev().attr('disabled', 'disabled'); }) + } +} + $(document).ready(function() { $('select#build_list_pl_id').change(function() { var platform_id = $(this).val(); @@ -29,4 +39,8 @@ $(document).ready(function() { } }); }); + + $('#settings_notifier_can_notify').click(function() { + disableNotifierCbx($(this)); + }); }); From 825236753720164e5ba1df7da877ebc909281552 Mon Sep 17 00:00:00 2001 From: Alexander Machehin Date: Fri, 13 Jan 2012 21:58:48 +0600 Subject: [PATCH 16/67] some fix --- app/controllers/comments_controller.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/controllers/comments_controller.rb b/app/controllers/comments_controller.rb index da4bfc127..d280e0ea6 100644 --- a/app/controllers/comments_controller.rb +++ b/app/controllers/comments_controller.rb @@ -1,8 +1,8 @@ class CommentsController < ApplicationController before_filter :authenticate_user! - before_filter :find_comment, :only => [:edit, :update, :destroy] before_filter :set_commentable, :only => [:index, :edit, :create, :update] #before_filter :find_project, :only => [:index, :edit] + before_filter :find_comment, :only => [:edit, :update, :destroy] authorize_resource :only => [:show, :edit, :update, :destroy] authorize_resource :project, :only => [:index] @@ -75,6 +75,7 @@ class CommentsController < ApplicationController def find_comment @comment = Comment.find(params[:id]) + @comment.project = @project if @comment.commentable_type == 'Grit::Commit' end def find_project From 2b1fe79adc12869913b66cee0582946b1174d913 Mon Sep 17 00:00:00 2001 From: Alexander Machehin Date: Fri, 13 Jan 2012 22:00:28 +0600 Subject: [PATCH 17/67] [refs #18] controller tests --- .../comments_controller_for_commit_spec.rb | 149 +++++++++++++++ spec/tests.git/HEAD | 1 + spec/tests.git/config | 11 ++ spec/tests.git/description | 1 + spec/tests.git/hooks/applypatch-msg.sample | 15 ++ spec/tests.git/hooks/commit-msg.sample | 24 +++ spec/tests.git/hooks/post-commit.sample | 8 + spec/tests.git/hooks/post-receive.sample | 15 ++ spec/tests.git/hooks/post-update.sample | 8 + spec/tests.git/hooks/pre-applypatch.sample | 14 ++ spec/tests.git/hooks/pre-commit.sample | 46 +++++ spec/tests.git/hooks/pre-rebase.sample | 172 ++++++++++++++++++ .../tests.git/hooks/prepare-commit-msg.sample | 36 ++++ spec/tests.git/hooks/update.sample | 128 +++++++++++++ spec/tests.git/index | Bin 0 -> 192 bytes spec/tests.git/info/exclude | 6 + spec/tests.git/logs/HEAD | 2 + spec/tests.git/logs/refs/heads/master | 1 + ...85f74f028bf49d2611c9fea56570138a196143.idx | Bin 0 -> 3844 bytes ...5f74f028bf49d2611c9fea56570138a196143.pack | Bin 0 -> 24472 bytes spec/tests.git/packed-refs | 5 + spec/tests.git/refs/heads/master | 1 + spec/tests.git/refs/remotes/origin/HEAD | 1 + 23 files changed, 644 insertions(+) create mode 100644 spec/controllers/comments_controller_for_commit_spec.rb create mode 100644 spec/tests.git/HEAD create mode 100644 spec/tests.git/config create mode 100644 spec/tests.git/description create mode 100755 spec/tests.git/hooks/applypatch-msg.sample create mode 100755 spec/tests.git/hooks/commit-msg.sample create mode 100755 spec/tests.git/hooks/post-commit.sample create mode 100755 spec/tests.git/hooks/post-receive.sample create mode 100755 spec/tests.git/hooks/post-update.sample create mode 100755 spec/tests.git/hooks/pre-applypatch.sample create mode 100755 spec/tests.git/hooks/pre-commit.sample create mode 100755 spec/tests.git/hooks/pre-rebase.sample create mode 100755 spec/tests.git/hooks/prepare-commit-msg.sample create mode 100755 spec/tests.git/hooks/update.sample create mode 100644 spec/tests.git/index create mode 100644 spec/tests.git/info/exclude create mode 100644 spec/tests.git/logs/HEAD create mode 100644 spec/tests.git/logs/refs/heads/master create mode 100644 spec/tests.git/objects/pack/pack-5185f74f028bf49d2611c9fea56570138a196143.idx create mode 100644 spec/tests.git/objects/pack/pack-5185f74f028bf49d2611c9fea56570138a196143.pack create mode 100644 spec/tests.git/packed-refs create mode 100644 spec/tests.git/refs/heads/master create mode 100644 spec/tests.git/refs/remotes/origin/HEAD diff --git a/spec/controllers/comments_controller_for_commit_spec.rb b/spec/controllers/comments_controller_for_commit_spec.rb new file mode 100644 index 000000000..fccd9c57b --- /dev/null +++ b/spec/controllers/comments_controller_for_commit_spec.rb @@ -0,0 +1,149 @@ +require 'spec_helper' + +shared_examples_for 'user with create comment rights' do + it 'should be able to perform create action' do + post :create, @create_params + response.should redirect_to(commit_path(@project, @commit.id)) + end + + it 'should create subscribe object into db' do + lambda{ post :create, @create_params }.should change{ Comment.count }.by(1) + end +end + +shared_examples_for 'user with update own comment rights' do + it 'should be able to perform update action' do + put :update, {:id => @own_comment.id}.merge(@update_params) + response.should redirect_to(commit_path(@project, @commit.id)) + end + + it 'should update subscribe body' do + put :update, {:id => @own_comment.id}.merge(@update_params) + @own_comment.reload.body.should == 'updated' + end +end + +shared_examples_for 'user with update stranger comment rights' do + it 'should be able to perform update action' do + put :update, {:id => @comment.id}.merge(@update_params) + response.should redirect_to(commit_path(@project, @commit.id)) + end + + it 'should update comment title' do + put :update, {:id => @comment.id}.merge(@update_params) + @comment.reload.body.should == 'updated' + end +end + +shared_examples_for 'user without update stranger comment rights' do + it 'should not be able to perform update action' do + put :update, {:id => @comment.id}.merge(@update_params) + response.should redirect_to(forbidden_path) + end + + it 'should not update comment title' do + put :update, {:id => @comment.id}.merge(@update_params) + @comment.reload.body.should_not == 'updated' + end +end + +shared_examples_for 'user without destroy comment rights' do + it 'should not be able to perform destroy action' do + delete :destroy, :id => @comment.id, :commit_id => @commit.id, :project_id => @project.id + response.should redirect_to(forbidden_path) + end +end + +#shared_examples_for 'user with destroy rights' do +# it 'should be able to perform destroy action' do +# delete :destroy, :id => @comment.id, :issue_id => @issue.id, :project_id => @project.id +# response.should redirect_to([@project, @issue]) +# end +# +# it 'should reduce comments count' do +# lambda{ delete :destroy, :id => @comment.id, :issue_id => @issue.id, :project_id => @project.id }.should change{ Comment.count }.by(-1) +# end +#end + +describe CommentsController do + before(:each) do + stub_rsync_methods + + @project = Factory(:project) + %x(cp -Rf #{Rails.root}/spec/tests.git/* #{@project.git_repository.path}) # maybe FIXME ? + @commit = @project.git_repository.commits.first + + @comment = Factory(:comment) + @comment.update_attributes(:commentable_type => @commit.class.name, :commentable_id => @commit.id) + @create_params = {:comment => {:body => 'I am a comment!'}, :project_id => @project.id, :commit_id => @commit.id} + @update_params = {:comment => {:body => 'updated'}, :project_id => @project.id, :commit_id => @commit.id} + + any_instance_of(Project, :versions => ['v1.0', 'v2.0']) + + @request.env['HTTP_REFERER'] = commit_path(@project, @commit.id) + end + + context 'for project admin user' do + before(:each) do + @user = Factory(:user) + set_session_for(@user) + @project.relations.create!(:object_type => 'User', :object_id => @user.id, :role => 'admin') + @own_comment = Factory(:comment, :user => @user) + @own_comment.update_attributes(:commentable_type => @commit.class.name, :commentable_id => @commit.id) + end + + it_should_behave_like 'user with create comment rights' + it_should_behave_like 'user with update stranger comment rights' + it_should_behave_like 'user with update own comment rights' + it_should_behave_like 'user without destroy comment rights' + end + + #~ context 'for project owner user' do + #~ before(:each) do + #~ @user = Factory(:user) + #~ set_session_for(@user) + #~ @project.update_attribute(:owner, @user) + #~ @project.relations.create!(:object_type => 'User', :object_id => @user.id, :role => 'admin') + + #~ @own_comment = Factory(:comment, :user => @user) + #~ @own_comment.update_attributes(:commentable_type => @commit.class.name, :commentable_id => @commit.id) + #~ end + + #~ it_should_behave_like 'user with create comment rights' + #~ it_should_behave_like 'user with update stranger comment rights' + #~ it_should_behave_like 'user with update own comment rights' + #~ it_should_behave_like 'user without destroy comment rights' + #~ end + + context 'for project reader user' do + before(:each) do + @user = Factory(:user) + set_session_for(@user) + @project.relations.create!(:object_type => 'User', :object_id => @user.id, :role => 'reader') + + @own_comment = Factory(:comment, :user => @user) + @own_comment.update_attributes(:commentable_type => @commit.class.name, :commentable_id => @commit.id) + end + + it_should_behave_like 'user with create comment rights' + it_should_behave_like 'user without update stranger comment rights' + it_should_behave_like 'user with update own comment rights' + it_should_behave_like 'user without destroy comment rights' + end + + context 'for project writer user' do + before(:each) do + @user = Factory(:user) + set_session_for(@user) + @project.relations.create!(:object_type => 'User', :object_id => @user.id, :role => 'writer') + + @own_comment = Factory(:comment, :user => @user) + @own_comment.update_attributes(:commentable_type => @commit.class.name, :commentable_id => @commit.id) + end + + it_should_behave_like 'user with create comment rights' + it_should_behave_like 'user without update stranger comment rights' + it_should_behave_like 'user with update own comment rights' + it_should_behave_like 'user without destroy comment rights' + end +end \ No newline at end of file diff --git a/spec/tests.git/HEAD b/spec/tests.git/HEAD new file mode 100644 index 000000000..df9ee5473 --- /dev/null +++ b/spec/tests.git/HEAD @@ -0,0 +1 @@ +bdc8b580b5b583aeb43efb19aac2ab8ce5566dff diff --git a/spec/tests.git/config b/spec/tests.git/config new file mode 100644 index 000000000..d38f8c6fe --- /dev/null +++ b/spec/tests.git/config @@ -0,0 +1,11 @@ +[core] + repositoryformatversion = 0 + filemode = true + bare = false + logallrefupdates = true +[remote "origin"] + fetch = +refs/heads/*:refs/remotes/origin/* + url = git://github.com/tpope/vim-ragtag.git +[branch "master"] + remote = origin + merge = refs/heads/master diff --git a/spec/tests.git/description b/spec/tests.git/description new file mode 100644 index 000000000..498b267a8 --- /dev/null +++ b/spec/tests.git/description @@ -0,0 +1 @@ +Unnamed repository; edit this file 'description' to name the repository. diff --git a/spec/tests.git/hooks/applypatch-msg.sample b/spec/tests.git/hooks/applypatch-msg.sample new file mode 100755 index 000000000..8b2a2fe84 --- /dev/null +++ b/spec/tests.git/hooks/applypatch-msg.sample @@ -0,0 +1,15 @@ +#!/bin/sh +# +# An example hook script to check the commit log message taken by +# applypatch from an e-mail message. +# +# The hook should exit with non-zero status after issuing an +# appropriate message if it wants to stop the commit. The hook is +# allowed to edit the commit message file. +# +# To enable this hook, rename this file to "applypatch-msg". + +. git-sh-setup +test -x "$GIT_DIR/hooks/commit-msg" && + exec "$GIT_DIR/hooks/commit-msg" ${1+"$@"} +: diff --git a/spec/tests.git/hooks/commit-msg.sample b/spec/tests.git/hooks/commit-msg.sample new file mode 100755 index 000000000..b58d1184a --- /dev/null +++ b/spec/tests.git/hooks/commit-msg.sample @@ -0,0 +1,24 @@ +#!/bin/sh +# +# An example hook script to check the commit log message. +# Called by "git commit" with one argument, the name of the file +# that has the commit message. The hook should exit with non-zero +# status after issuing an appropriate message if it wants to stop the +# commit. The hook is allowed to edit the commit message file. +# +# To enable this hook, rename this file to "commit-msg". + +# Uncomment the below to add a Signed-off-by line to the message. +# Doing this in a hook is a bad idea in general, but the prepare-commit-msg +# hook is more suited to it. +# +# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') +# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1" + +# This example catches duplicate Signed-off-by lines. + +test "" = "$(grep '^Signed-off-by: ' "$1" | + sort | uniq -c | sed -e '/^[ ]*1[ ]/d')" || { + echo >&2 Duplicate Signed-off-by lines. + exit 1 +} diff --git a/spec/tests.git/hooks/post-commit.sample b/spec/tests.git/hooks/post-commit.sample new file mode 100755 index 000000000..22668216a --- /dev/null +++ b/spec/tests.git/hooks/post-commit.sample @@ -0,0 +1,8 @@ +#!/bin/sh +# +# An example hook script that is called after a successful +# commit is made. +# +# To enable this hook, rename this file to "post-commit". + +: Nothing diff --git a/spec/tests.git/hooks/post-receive.sample b/spec/tests.git/hooks/post-receive.sample new file mode 100755 index 000000000..7a83e17ab --- /dev/null +++ b/spec/tests.git/hooks/post-receive.sample @@ -0,0 +1,15 @@ +#!/bin/sh +# +# An example hook script for the "post-receive" event. +# +# The "post-receive" script is run after receive-pack has accepted a pack +# and the repository has been updated. It is passed arguments in through +# stdin in the form +# +# For example: +# aa453216d1b3e49e7f6f98441fa56946ddcd6a20 68f7abf4e6f922807889f52bc043ecd31b79f814 refs/heads/master +# +# see contrib/hooks/ for a sample, or uncomment the next line and +# rename the file to "post-receive". + +#. /usr/share/doc/git-core/contrib/hooks/post-receive-email diff --git a/spec/tests.git/hooks/post-update.sample b/spec/tests.git/hooks/post-update.sample new file mode 100755 index 000000000..ec17ec193 --- /dev/null +++ b/spec/tests.git/hooks/post-update.sample @@ -0,0 +1,8 @@ +#!/bin/sh +# +# An example hook script to prepare a packed repository for use over +# dumb transports. +# +# To enable this hook, rename this file to "post-update". + +exec git update-server-info diff --git a/spec/tests.git/hooks/pre-applypatch.sample b/spec/tests.git/hooks/pre-applypatch.sample new file mode 100755 index 000000000..b1f187c2e --- /dev/null +++ b/spec/tests.git/hooks/pre-applypatch.sample @@ -0,0 +1,14 @@ +#!/bin/sh +# +# An example hook script to verify what is about to be committed +# by applypatch from an e-mail message. +# +# The hook should exit with non-zero status after issuing an +# appropriate message if it wants to stop the commit. +# +# To enable this hook, rename this file to "pre-applypatch". + +. git-sh-setup +test -x "$GIT_DIR/hooks/pre-commit" && + exec "$GIT_DIR/hooks/pre-commit" ${1+"$@"} +: diff --git a/spec/tests.git/hooks/pre-commit.sample b/spec/tests.git/hooks/pre-commit.sample new file mode 100755 index 000000000..b187c4bb1 --- /dev/null +++ b/spec/tests.git/hooks/pre-commit.sample @@ -0,0 +1,46 @@ +#!/bin/sh +# +# An example hook script to verify what is about to be committed. +# Called by "git commit" with no arguments. The hook should +# exit with non-zero status after issuing an appropriate message if +# it wants to stop the commit. +# +# To enable this hook, rename this file to "pre-commit". + +if git rev-parse --verify HEAD >/dev/null 2>&1 +then + against=HEAD +else + # Initial commit: diff against an empty tree object + against=4b825dc642cb6eb9a060e54bf8d69288fbee4904 +fi + +# If you want to allow non-ascii filenames set this variable to true. +allownonascii=$(git config hooks.allownonascii) + +# Cross platform projects tend to avoid non-ascii filenames; prevent +# them from being added to the repository. We exploit the fact that the +# printable range starts at the space character and ends with tilde. +if [ "$allownonascii" != "true" ] && + # Note that the use of brackets around a tr range is ok here, (it's + # even required, for portability to Solaris 10's /usr/bin/tr), since + # the square bracket bytes happen to fall in the designated range. + test "$(git diff --cached --name-only --diff-filter=A -z $against | + LC_ALL=C tr -d '[ -~]\0')" +then + echo "Error: Attempt to add a non-ascii file name." + echo + echo "This can cause problems if you want to work" + echo "with people on other platforms." + echo + echo "To be portable it is advisable to rename the file ..." + echo + echo "If you know what you are doing you can disable this" + echo "check using:" + echo + echo " git config hooks.allownonascii true" + echo + exit 1 +fi + +exec git diff-index --check --cached $against -- diff --git a/spec/tests.git/hooks/pre-rebase.sample b/spec/tests.git/hooks/pre-rebase.sample new file mode 100755 index 000000000..f0f6da314 --- /dev/null +++ b/spec/tests.git/hooks/pre-rebase.sample @@ -0,0 +1,172 @@ +#!/bin/sh +# +# Copyright (c) 2006, 2008 Junio C Hamano +# +# The "pre-rebase" hook is run just before "git rebase" starts doing +# its job, and can prevent the command from running by exiting with +# non-zero status. +# +# The hook is called with the following parameters: +# +# $1 -- the upstream the series was forked from. +# $2 -- the branch being rebased (or empty when rebasing the current branch). +# +# This sample shows how to prevent topic branches that are already +# merged to 'next' branch from getting rebased, because allowing it +# would result in rebasing already published history. + +publish=next +basebranch="$1" +if test "$#" = 2 +then + topic="refs/heads/$2" +else + topic=`git symbolic-ref HEAD` || + exit 0 ;# we do not interrupt rebasing detached HEAD +fi + +case "$topic" in +refs/heads/??/*) + ;; +*) + exit 0 ;# we do not interrupt others. + ;; +esac + +# Now we are dealing with a topic branch being rebased +# on top of master. Is it OK to rebase it? + +# Does the topic really exist? +git show-ref -q "$topic" || { + echo >&2 "No such branch $topic" + exit 1 +} + +# Is topic fully merged to master? +not_in_master=`git rev-list --pretty=oneline ^master "$topic"` +if test -z "$not_in_master" +then + echo >&2 "$topic is fully merged to master; better remove it." + exit 1 ;# we could allow it, but there is no point. +fi + +# Is topic ever merged to next? If so you should not be rebasing it. +only_next_1=`git rev-list ^master "^$topic" ${publish} | sort` +only_next_2=`git rev-list ^master ${publish} | sort` +if test "$only_next_1" = "$only_next_2" +then + not_in_topic=`git rev-list "^$topic" master` + if test -z "$not_in_topic" + then + echo >&2 "$topic is already up-to-date with master" + exit 1 ;# we could allow it, but there is no point. + else + exit 0 + fi +else + not_in_next=`git rev-list --pretty=oneline ^${publish} "$topic"` + /usr/bin/perl -e ' + my $topic = $ARGV[0]; + my $msg = "* $topic has commits already merged to public branch:\n"; + my (%not_in_next) = map { + /^([0-9a-f]+) /; + ($1 => 1); + } split(/\n/, $ARGV[1]); + for my $elem (map { + /^([0-9a-f]+) (.*)$/; + [$1 => $2]; + } split(/\n/, $ARGV[2])) { + if (!exists $not_in_next{$elem->[0]}) { + if ($msg) { + print STDERR $msg; + undef $msg; + } + print STDERR " $elem->[1]\n"; + } + } + ' "$topic" "$not_in_next" "$not_in_master" + exit 1 +fi + +exit 0 + +<<\DOC_END +################################################################ + +This sample hook safeguards topic branches that have been +published from being rewound. + +The workflow assumed here is: + + * Once a topic branch forks from "master", "master" is never + merged into it again (either directly or indirectly). + + * Once a topic branch is fully cooked and merged into "master", + it is deleted. If you need to build on top of it to correct + earlier mistakes, a new topic branch is created by forking at + the tip of the "master". This is not strictly necessary, but + it makes it easier to keep your history simple. + + * Whenever you need to test or publish your changes to topic + branches, merge them into "next" branch. + +The script, being an example, hardcodes the publish branch name +to be "next", but it is trivial to make it configurable via +$GIT_DIR/config mechanism. + +With this workflow, you would want to know: + +(1) ... if a topic branch has ever been merged to "next". Young + topic branches can have stupid mistakes you would rather + clean up before publishing, and things that have not been + merged into other branches can be easily rebased without + affecting other people. But once it is published, you would + not want to rewind it. + +(2) ... if a topic branch has been fully merged to "master". + Then you can delete it. More importantly, you should not + build on top of it -- other people may already want to + change things related to the topic as patches against your + "master", so if you need further changes, it is better to + fork the topic (perhaps with the same name) afresh from the + tip of "master". + +Let's look at this example: + + o---o---o---o---o---o---o---o---o---o "next" + / / / / + / a---a---b A / / + / / / / + / / c---c---c---c B / + / / / \ / + / / / b---b C \ / + / / / / \ / + ---o---o---o---o---o---o---o---o---o---o---o "master" + + +A, B and C are topic branches. + + * A has one fix since it was merged up to "next". + + * B has finished. It has been fully merged up to "master" and "next", + and is ready to be deleted. + + * C has not merged to "next" at all. + +We would want to allow C to be rebased, refuse A, and encourage +B to be deleted. + +To compute (1): + + git rev-list ^master ^topic next + git rev-list ^master next + + if these match, topic has not merged in next at all. + +To compute (2): + + git rev-list master..topic + + if this is empty, it is fully merged to "master". + +DOC_END diff --git a/spec/tests.git/hooks/prepare-commit-msg.sample b/spec/tests.git/hooks/prepare-commit-msg.sample new file mode 100755 index 000000000..f093a02ec --- /dev/null +++ b/spec/tests.git/hooks/prepare-commit-msg.sample @@ -0,0 +1,36 @@ +#!/bin/sh +# +# An example hook script to prepare the commit log message. +# Called by "git commit" with the name of the file that has the +# commit message, followed by the description of the commit +# message's source. The hook's purpose is to edit the commit +# message file. If the hook fails with a non-zero status, +# the commit is aborted. +# +# To enable this hook, rename this file to "prepare-commit-msg". + +# This hook includes three examples. The first comments out the +# "Conflicts:" part of a merge commit. +# +# The second includes the output of "git diff --name-status -r" +# into the message, just before the "git status" output. It is +# commented because it doesn't cope with --amend or with squashed +# commits. +# +# The third example adds a Signed-off-by line to the message, that can +# still be edited. This is rarely a good idea. + +case "$2,$3" in + merge,) + /usr/bin/perl -i.bak -ne 's/^/# /, s/^# #/#/ if /^Conflicts/ .. /#/; print' "$1" ;; + +# ,|template,) +# /usr/bin/perl -i.bak -pe ' +# print "\n" . `git diff --cached --name-status -r` +# if /^#/ && $first++ == 0' "$1" ;; + + *) ;; +esac + +# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') +# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1" diff --git a/spec/tests.git/hooks/update.sample b/spec/tests.git/hooks/update.sample new file mode 100755 index 000000000..71ab04edc --- /dev/null +++ b/spec/tests.git/hooks/update.sample @@ -0,0 +1,128 @@ +#!/bin/sh +# +# An example hook script to blocks unannotated tags from entering. +# Called by "git receive-pack" with arguments: refname sha1-old sha1-new +# +# To enable this hook, rename this file to "update". +# +# Config +# ------ +# hooks.allowunannotated +# This boolean sets whether unannotated tags will be allowed into the +# repository. By default they won't be. +# hooks.allowdeletetag +# This boolean sets whether deleting tags will be allowed in the +# repository. By default they won't be. +# hooks.allowmodifytag +# This boolean sets whether a tag may be modified after creation. By default +# it won't be. +# hooks.allowdeletebranch +# This boolean sets whether deleting branches will be allowed in the +# repository. By default they won't be. +# hooks.denycreatebranch +# This boolean sets whether remotely creating branches will be denied +# in the repository. By default this is allowed. +# + +# --- Command line +refname="$1" +oldrev="$2" +newrev="$3" + +# --- Safety check +if [ -z "$GIT_DIR" ]; then + echo "Don't run this script from the command line." >&2 + echo " (if you want, you could supply GIT_DIR then run" >&2 + echo " $0 )" >&2 + exit 1 +fi + +if [ -z "$refname" -o -z "$oldrev" -o -z "$newrev" ]; then + echo "Usage: $0 " >&2 + exit 1 +fi + +# --- Config +allowunannotated=$(git config --bool hooks.allowunannotated) +allowdeletebranch=$(git config --bool hooks.allowdeletebranch) +denycreatebranch=$(git config --bool hooks.denycreatebranch) +allowdeletetag=$(git config --bool hooks.allowdeletetag) +allowmodifytag=$(git config --bool hooks.allowmodifytag) + +# check for no description +projectdesc=$(sed -e '1q' "$GIT_DIR/description") +case "$projectdesc" in +"Unnamed repository"* | "") + echo "*** Project description file hasn't been set" >&2 + exit 1 + ;; +esac + +# --- Check types +# if $newrev is 0000...0000, it's a commit to delete a ref. +zero="0000000000000000000000000000000000000000" +if [ "$newrev" = "$zero" ]; then + newrev_type=delete +else + newrev_type=$(git cat-file -t $newrev) +fi + +case "$refname","$newrev_type" in + refs/tags/*,commit) + # un-annotated tag + short_refname=${refname##refs/tags/} + if [ "$allowunannotated" != "true" ]; then + echo "*** The un-annotated tag, $short_refname, is not allowed in this repository" >&2 + echo "*** Use 'git tag [ -a | -s ]' for tags you want to propagate." >&2 + exit 1 + fi + ;; + refs/tags/*,delete) + # delete tag + if [ "$allowdeletetag" != "true" ]; then + echo "*** Deleting a tag is not allowed in this repository" >&2 + exit 1 + fi + ;; + refs/tags/*,tag) + # annotated tag + if [ "$allowmodifytag" != "true" ] && git rev-parse $refname > /dev/null 2>&1 + then + echo "*** Tag '$refname' already exists." >&2 + echo "*** Modifying a tag is not allowed in this repository." >&2 + exit 1 + fi + ;; + refs/heads/*,commit) + # branch + if [ "$oldrev" = "$zero" -a "$denycreatebranch" = "true" ]; then + echo "*** Creating a branch is not allowed in this repository" >&2 + exit 1 + fi + ;; + refs/heads/*,delete) + # delete branch + if [ "$allowdeletebranch" != "true" ]; then + echo "*** Deleting a branch is not allowed in this repository" >&2 + exit 1 + fi + ;; + refs/remotes/*,commit) + # tracking branch + ;; + refs/remotes/*,delete) + # delete tracking branch + if [ "$allowdeletebranch" != "true" ]; then + echo "*** Deleting a tracking branch is not allowed in this repository" >&2 + exit 1 + fi + ;; + *) + # Anything else (is there anything else?) + echo "*** Update hook: unknown type of update to ref $refname of type $newrev_type" >&2 + exit 1 + ;; +esac + +# --- Finished +exit 0 diff --git a/spec/tests.git/index b/spec/tests.git/index new file mode 100644 index 0000000000000000000000000000000000000000..29cca27d49d6f2554fc33e2e5e1a79a665961080 GIT binary patch literal 192 zcmZ?q402{*U|<4af0l-MK$-zYGca&4GvqkvGcYtRVPIf>0l|Ds5ug6KrR<(*ZXfz= z&fKOt!(Y)gYz%xU`N{f4iRmSY>3Ss 1325695134 +0600 clone: from git://github.com/tpope/vim-ragtag.git +bdc8b580b5b583aeb43efb19aac2ab8ce5566dff bdc8b580b5b583aeb43efb19aac2ab8ce5566dff Alexander 1325695134 +0600 checkout: moving from master to bdc8b580b5b583aeb43efb19aac2ab8ce5566dff diff --git a/spec/tests.git/logs/refs/heads/master b/spec/tests.git/logs/refs/heads/master new file mode 100644 index 000000000..9219de536 --- /dev/null +++ b/spec/tests.git/logs/refs/heads/master @@ -0,0 +1 @@ +0000000000000000000000000000000000000000 bdc8b580b5b583aeb43efb19aac2ab8ce5566dff Alexander 1325695134 +0600 clone: from git://github.com/tpope/vim-ragtag.git diff --git a/spec/tests.git/objects/pack/pack-5185f74f028bf49d2611c9fea56570138a196143.idx b/spec/tests.git/objects/pack/pack-5185f74f028bf49d2611c9fea56570138a196143.idx new file mode 100644 index 0000000000000000000000000000000000000000..46bd6036da21943b3ae5a3be1b6c0de1b3c0973f GIT binary patch literal 3844 zcmbuCc`(&~7soGIQnD{sq13g;MadqQYbWAbZq_U%)X&yMwya4=gc6cU*|YCkvhNWs zWZx-SBjPz`m@&WUY37;d&b;P*KIgNX@40`y&-P6%O9TQz4D9@N^ly;B{@);l{r!-^ z`hS5O&hKz=7Yfil4ns`&UpNAJDuCt>&_a$LVAzEbbU#e6-h&z9KY@h&epq0AbeChG ze}WbAY`d_79^c0ai2no!M%(;M?Ui=nnk*5P%r{F9cz| zhY-X&2=8(RbceIRxm`p-#deVZ-9ZXCzl#j$4zd8|FUY~3{2#zVZVv^B6#=DPltFh; z-9;Vr!Y-PiT7TdodADC3`qV$75LsRkD&VB-={B{dUEQTm{={41y1G^%T@oOV9YSBR&A_Mh75M>1AIkNhnY zsyL&vXOpM}8O5cf81Vry^%j2f+vfbf(sEwg9A_O@uYPvsiaqD-8#^63z-JIjf67$B zn&zhURz@8uuIyWqY213E0q1FMs$;I!MJV9|HRqT&sU8#>>hb6)jt<5+c)ROSeWtxr zNl?T@_3)T{44!4b>L@+8l)vVhAtB&7{SU9O%h_d3=KeEg7sqC5Z8y~$Qbq-p1ixP= zE)=z3l29*~Gh4**Ts|w5wUvPo$eTO3%^mX5;(?W}jXAq8i%y)hUs!5UiKWNWNLd0! zS$2W&Dp`ZlF)i_!ku}j%!Td9wB{VCd@2X^&+gI-!yvI8Jmi3hGq;PT*Lp{B*p`i7M zA9H@#4Tp*_3DaW~3-PAo=civn)4Z=H5o+!7OzK(`$F@aeUP~M9Oiw`Zyc+p|VLfdn zIWxPYkQz2lt>C4ya)p=y!|E?6b8;@#7-LFX^yccR*Ata)xVz!P-qz-6|~iahdaQUr6V=MzrN_H&WDV9gb>daT|&WKA-**`!&XC95q_t)7(lr;g0=o zYP?)CtKps9u*zlMsZ^Z7?p3-?H9u33(LS4|z_z3*6KEc*?JZ$;@TyYvVcrWZrQiJt zo{HwoPJS!Lhp~R#SW+W&lH0khZ+E*>nge5lqz~XZ2L@8V_42;Y>i(^G=TOiK_Ya%% zcT-m9^#`+cx3dY))s%zP5$G-kd7127(#jLfJlX1RRv1Hy@vP1yDDobP(9Q>Ri%Jga z^>LwMQ|@I|nR15w_?tQg+vc3| z=vR72Ki!uQE8@uT^%7wbm5?=|mJbnD=ba}%5o{$R^eQU(z9_Oc*;#h5`ru5-KPg#7 zm^?!S9Yy|@O{I&TwQ<)~Bsy^U;b|4J+9-Ch<|vPtZnN`<3%rxxA9m-HIMyEz$*>`- z6vW3LeN>CniK5&1W@*!MBZK62$*U#?YX`+iNFeuA^37&2g!PeCzWqkQxg=4o1i5;g$Oqrqf~*bA<|&o;^Le6s)gfSB_;}eX~*T+-F(c+zoWI=QA35$Vb|= zn1p7zCcQsr%6pv3ljuIt%bnBAZxK$`(aY{@N)b*-%3#l6TMBsp!czYX0M#@n1;kgacdXEff(9%!{;d?W90<9L$?yD)2an3l2$`r=3$XVYvwEc z+Nhct#d@NM$+fBsHeA}!N)N^LfUc9Tsf#B}^fs95Y;oeZObNey(JSg@?M56uv69iDm?-$PV`^y7wU|4i{y1Qk@)oR zEL6-`2Rk;Yzj$8D8bx1k=70-EBxkoH1!t~{u()w(`!ML#Lt2L*rVi!k3AGKT>s1w@@-Ce+pL3QDt-xng zkFAr6ToKL8mApveMO8Ubvcbz!ab#st6}>idJ`#<+{(e4x)^44gRq_VDBV@U57hua5o+9 z!Hi%CeKEtE)T0Q*0r1~)P0$lHjB~!w3;1+-IA;L=iNP<}gIUfr5PBsb5F#{CBMf@Y z0Z$5fij&X-^i0DG>ugY{g@gaq2y%D~yuAuN%)_^UUpHKaxBQ`Z=n;P!t}nq`j8Ln; t)taI4gVd$h#Zjdmv9^eU6yXMB(#h@n4CR$h%!^MvCV~$sXECMJ{09@dM(_Xt literal 0 HcmV?d00001 diff --git a/spec/tests.git/objects/pack/pack-5185f74f028bf49d2611c9fea56570138a196143.pack b/spec/tests.git/objects/pack/pack-5185f74f028bf49d2611c9fea56570138a196143.pack new file mode 100644 index 0000000000000000000000000000000000000000..59398297275807cd2dc4c0a68892e2a03581f68b GIT binary patch literal 24472 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 Date: Fri, 13 Jan 2012 20:07:46 +0400 Subject: [PATCH 18/67] [refs #54] Fix comments serial_id routing and some logic --- app/controllers/comments_controller.rb | 2 +- app/models/comment.rb | 9 ++++----- app/views/comments/edit.html.haml | 2 +- app/views/issues/show.html.haml | 8 ++++---- 4 files changed, 10 insertions(+), 11 deletions(-) diff --git a/app/controllers/comments_controller.rb b/app/controllers/comments_controller.rb index 4b70d8127..599b4200a 100644 --- a/app/controllers/comments_controller.rb +++ b/app/controllers/comments_controller.rb @@ -55,7 +55,7 @@ class CommentsController < ApplicationController # end #end #nil - return Issue.find(params[:issue_id]) + return Issue.find_by_serial_id_and_project_id(params[:issue_id], params[:project_id]) end def set_commentable diff --git a/app/models/comment.rb b/app/models/comment.rb index 41ba6602e..4881f739a 100644 --- a/app/models/comment.rb +++ b/app/models/comment.rb @@ -12,12 +12,11 @@ class Comment < ActiveRecord::Base def deliver_new_comment_notification subscribes = self.commentable.subscribes subscribes.each do |subscribe| - recipient = subscribe.user - if self.user_id != subscribe.user_id && User.find(recipient).notifier.new_comment_reply && User.find(recipient).notifier.can_notify - if self.commentable.comments.exists?(:user_id => recipient.id) - UserMailer.delay.new_comment_reply_notification(self, recipient) + if self.user_id != subscribe.user_id && User.find(subscribe.user).notifier.new_comment_reply && User.find(subscribe.user).notifier.can_notify + if self.commentable.comments.exists?(:user_id => subscribe.user.id) + UserMailer.delay.new_comment_reply_notification(self, subscribe.user) else - UserMailer.delay.new_comment_notification(self, recipient) + UserMailer.delay.new_comment_notification(self, subscribe.user) end end end diff --git a/app/views/comments/edit.html.haml b/app/views/comments/edit.html.haml index 5f2dc3ffd..516ddd476 100644 --- a/app/views/comments/edit.html.haml +++ b/app/views/comments/edit.html.haml @@ -6,5 +6,5 @@ %h2.title = t("layout.issues.edit_header") .inner - = form_for @comment, :url => project_issue_comment_path(@project, @issue.id, @comment), :html => { :class => :form } do |f| + = form_for @comment, :url => project_issue_comment_path(@project, @issue, @comment), :html => { :class => :form } do |f| = render :partial => "form", :locals => {:f => f} diff --git a/app/views/issues/show.html.haml b/app/views/issues/show.html.haml index 2a79e66a3..df7de8452 100644 --- a/app/views/issues/show.html.haml +++ b/app/views/issues/show.html.haml @@ -36,7 +36,7 @@ = t("layout.issues.comments_header") .inner %ul.list - - @issue.comments.each do |comment| + - @issue.comments.order(:created_at).each do |comment| %li .left = link_to comment.user.uname, user_path(comment.user.uname) @@ -44,13 +44,13 @@ = comment.body %br %br - = link_to t("layout.edit"), edit_project_issue_comment_path(@project, @issue.id, comment) if can? :update, comment - = link_to image_tag("web-app-theme/icons/cross.png", :alt => t("layout.delete")) + " " + t("layout.delete"), project_issue_comment_path(@project, @issue.id, comment), :method => "delete", :class => "button", :confirm => t("layout.comments.confirm_delete") if can? :delete, comment + = link_to t("layout.edit"), edit_project_issue_comment_path(@project, @issue, comment) if can? :update, comment + = link_to image_tag("web-app-theme/icons/cross.png", :alt => t("layout.delete")) + " " + t("layout.delete"), project_issue_comment_path(@project, @issue, comment), :method => "delete", :class => "button", :confirm => t("layout.comments.confirm_delete") if can? :delete, comment .block .content %h2.title = t("layout.comments.new_header") .inner - = form_for :comment, :url => project_issue_comments_path(@project, @issue.id), :method => :post, :html => { :class => :form } do |f| + = form_for :comment, :url => project_issue_comments_path(@project, @issue), :method => :post, :html => { :class => :form } do |f| = render :partial => "comments/form", :locals => {:f => f} From 712ca8d95ace3227c19370359577d2d57f013816 Mon Sep 17 00:00:00 2001 From: Pavel Chipiga Date: Fri, 13 Jan 2012 18:45:13 +0200 Subject: [PATCH 19/67] Save package_version during success build_list publish. Add specs. Refs #103 --- app/controllers/build_lists_controller.rb | 7 ++++++- .../20120113151305_add_package_version_to_build_lists.rb | 9 +++++++++ db/schema.rb | 3 ++- spec/controllers/build_lists_controller_spec.rb | 4 +++- 4 files changed, 20 insertions(+), 3 deletions(-) create mode 100644 db/migrate/20120113151305_add_package_version_to_build_lists.rb diff --git a/app/controllers/build_lists_controller.rb b/app/controllers/build_lists_controller.rb index fc650a4b3..86d2b9064 100644 --- a/app/controllers/build_lists_controller.rb +++ b/app/controllers/build_lists_controller.rb @@ -80,7 +80,12 @@ class BuildListsController < ApplicationController end def publish_build - @build_list.status = (params[:status].to_i == 0 ? BuildList::BUILD_PUBLISHED : BuildList::FAILED_PUBLISH) + if params[:status].to_i == 0 # ok + @build_list.status = BuildList::BUILD_PUBLISHED + @build_list.package_version = "#{params[:version]}-#{params[:release]}" + else + @build_list.status = BuildList::FAILED_PUBLISH + end @build_list.notified_at = Time.current @build_list.save diff --git a/db/migrate/20120113151305_add_package_version_to_build_lists.rb b/db/migrate/20120113151305_add_package_version_to_build_lists.rb new file mode 100644 index 000000000..d416e3fa5 --- /dev/null +++ b/db/migrate/20120113151305_add_package_version_to_build_lists.rb @@ -0,0 +1,9 @@ +class AddPackageVersionToBuildLists < ActiveRecord::Migration + def self.up + add_column :build_lists, :package_version, :string + end + + def self.down + remove_column :build_lists, :package_version + end +end diff --git a/db/schema.rb b/db/schema.rb index e80b0c134..83b6e610d 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended to check this file into your version control system. -ActiveRecord::Schema.define(:version => 20111228182425) do +ActiveRecord::Schema.define(:version => 20120113151305) do create_table "arches", :force => true do |t| t.string "name", :null => false @@ -72,6 +72,7 @@ ActiveRecord::Schema.define(:version => 20111228182425) do t.text "include_repos" t.integer "user_id" t.boolean "auto_publish", :default => true + t.string "package_version" end add_index "build_lists", ["arch_id"], :name => "index_build_lists_on_arch_id" diff --git a/spec/controllers/build_lists_controller_spec.rb b/spec/controllers/build_lists_controller_spec.rb index a3e088c63..e337c1fd6 100644 --- a/spec/controllers/build_lists_controller_spec.rb +++ b/spec/controllers/build_lists_controller_spec.rb @@ -300,13 +300,15 @@ describe BuildListsController do describe 'publish_build' do def do_get(status) - get :publish_build, :id => build_list.bs_id, :status => status + get :publish_build, :id => build_list.bs_id, :status => status, :version => '4.7.5.3', :release => '1' build_list.reload end it { do_get(BuildServer::SUCCESS); response.should be_ok } it { lambda{ do_get(BuildServer::SUCCESS) }.should change(build_list, :status).to(BuildList::BUILD_PUBLISHED) } + it { lambda{ do_get(BuildServer::SUCCESS) }.should change(build_list, :package_version).to('4.7.5.3-1') } it { lambda{ do_get(BuildServer::ERROR) }.should change(build_list, :status).to(BuildList::FAILED_PUBLISH) } + it { lambda{ do_get(BuildServer::ERROR) }.should_not change(build_list, :package_version) } it { lambda{ do_get(BuildServer::ERROR) }.should change(build_list, :notified_at) } end From bdc3b3a3d18818d1ed7e6559bc68e25ac8132ef0 Mon Sep 17 00:00:00 2001 From: Alexander Machehin Date: Sat, 14 Jan 2012 18:16:42 +0600 Subject: [PATCH 20/67] [refs #18] controller tests --- app/controllers/comments_controller.rb | 2 +- app/models/ability.rb | 2 +- .../comments_controller_for_commit_spec.rb | 31 ++++++++++--------- 3 files changed, 19 insertions(+), 16 deletions(-) diff --git a/app/controllers/comments_controller.rb b/app/controllers/comments_controller.rb index d280e0ea6..8d950b18a 100644 --- a/app/controllers/comments_controller.rb +++ b/app/controllers/comments_controller.rb @@ -1,6 +1,6 @@ class CommentsController < ApplicationController before_filter :authenticate_user! - before_filter :set_commentable, :only => [:index, :edit, :create, :update] + before_filter :set_commentable, :only => [:index, :edit, :create, :update, :destroy] #before_filter :find_project, :only => [:index, :edit] before_filter :find_comment, :only => [:edit, :update, :destroy] diff --git a/app/models/ability.rb b/app/models/ability.rb index 0c1684db0..611697588 100644 --- a/app/models/ability.rb +++ b/app/models/ability.rb @@ -90,7 +90,7 @@ class Ability cannot :manage, Issue, :project => {:has_issues => false} # switch off issues can(:create, Comment) {|comment| can? :read, comment.project || comment.commentable.project} - can([:update, :delete], Comment) {|comment| comment.user_id == user.id or local_admin?(comment.project || comment.commentable.project)} + can(:update, Comment) {|comment| comment.user_id == user.id or local_admin?(comment.project || comment.commentable.project)} #cannot :manage, Comment, :commentable => {:project => {:has_issues => false}} # switch off issues cannot(:manage, Comment) {|comment| comment.commentable_type == 'Issue' && !comment.commentable.project.has_issues} # switch off issues end diff --git a/spec/controllers/comments_controller_for_commit_spec.rb b/spec/controllers/comments_controller_for_commit_spec.rb index fccd9c57b..07bdea33c 100644 --- a/spec/controllers/comments_controller_for_commit_spec.rb +++ b/spec/controllers/comments_controller_for_commit_spec.rb @@ -52,6 +52,10 @@ shared_examples_for 'user without destroy comment rights' do delete :destroy, :id => @comment.id, :commit_id => @commit.id, :project_id => @project.id response.should redirect_to(forbidden_path) end + + it 'should not reduce comments count' do + lambda{ delete :destroy, :id => @comment.id, :commit_id => @commit.id, :project_id => @project.id }.should change{ Comment.count }.by(0) + end end #shared_examples_for 'user with destroy rights' do @@ -98,22 +102,21 @@ describe CommentsController do it_should_behave_like 'user without destroy comment rights' end - #~ context 'for project owner user' do - #~ before(:each) do - #~ @user = Factory(:user) - #~ set_session_for(@user) - #~ @project.update_attribute(:owner, @user) - #~ @project.relations.create!(:object_type => 'User', :object_id => @user.id, :role => 'admin') + context 'for project owner user' do + before(:each) do + @user = @project.owner + set_session_for(@user) + @project.relations.create!(:object_type => 'User', :object_id => @user.id, :role => 'admin') - #~ @own_comment = Factory(:comment, :user => @user) - #~ @own_comment.update_attributes(:commentable_type => @commit.class.name, :commentable_id => @commit.id) - #~ end + @own_comment = Factory(:comment, :user => @user) + @own_comment.update_attributes(:commentable_type => @commit.class.name, :commentable_id => @commit.id) + end - #~ it_should_behave_like 'user with create comment rights' - #~ it_should_behave_like 'user with update stranger comment rights' - #~ it_should_behave_like 'user with update own comment rights' - #~ it_should_behave_like 'user without destroy comment rights' - #~ end + it_should_behave_like 'user with create comment rights' + it_should_behave_like 'user with update stranger comment rights' + it_should_behave_like 'user with update own comment rights' + it_should_behave_like 'user without destroy comment rights' + end context 'for project reader user' do before(:each) do From 674d5f8e5689a051e6f90e29ddb596c1083bdf27 Mon Sep 17 00:00:00 2001 From: Alexander Machehin Date: Sat, 14 Jan 2012 18:36:00 +0600 Subject: [PATCH 21/67] [refs #18] model tests --- spec/models/comment_for_commit_spec.rb | 135 +++++++++++++++++++++++++ 1 file changed, 135 insertions(+) create mode 100644 spec/models/comment_for_commit_spec.rb diff --git a/spec/models/comment_for_commit_spec.rb b/spec/models/comment_for_commit_spec.rb new file mode 100644 index 000000000..adcc70967 --- /dev/null +++ b/spec/models/comment_for_commit_spec.rb @@ -0,0 +1,135 @@ +require 'spec_helper' +require "cancan/matchers" + +def set_comments_data + @ability = Ability.new(@user) + + @project = Factory(:project) + %x(cp -Rf #{Rails.root}/spec/tests.git/* #{@project.git_repository.path}) # maybe FIXME ? + @commit = @project.git_repository.commits.first + + @comment = Factory(:comment, :user => @user) + @comment.update_attributes(:commentable_type => @commit.class.name, :commentable_id => @commit.id) + + @stranger_comment = Factory(:comment, :user => @stranger) + @stranger_comment.update_attributes(:commentable_type => @commit.class.name, :commentable_id => @commit.id, :project => @project) + + @create_params = {:commentable_type => @commit.class.name, :commentable_id => @commit.id, :user => @user, :project => @project} + + any_instance_of(Project, :versions => ['v1.0', 'v2.0']) +end + +describe Comment do + context 'for global admin user' do + before(:each) do + @user = Factory(:admin) + @stranger = Factory(:user) + + set_comments_data + end + + it 'should create comment' do + @ability.should be_able_to(:create, Comment.new(@create_params)) + end + + pending "sends an e-mail" do + ActionMailer::Base.deliveries.last.to.include?(@stranger.email).should == true + end + + it 'should update comment' do + @ability.should be_able_to(:update, @comment) + end + + it 'should update stranger comment' do + @ability.should be_able_to(:update, @stranger_comment) + end + + it 'should destroy own comment' do + @ability.should be_able_to(:destroy, @comment) + end + + it 'should destroy stranger comment' do + @ability.should be_able_to(:destroy, @stranger_comment) + end + end + + context 'for project admin user' do + before(:each) do + @user = Factory(:user) + @stranger = Factory(:user) + + set_comments_data + + @project.relations.create!(:object_type => 'User', :object_id => @user.id, :role => 'admin') + end + + it 'should create comment' do + @ability.should be_able_to(:create, Comment.new(@create_params)) + end + + it 'should update comment' do + @ability.should be_able_to(:update, @comment) + end + + it 'should update stranger comment' do + @ability.should be_able_to(:update, @stranger_comment) + end + + it 'should not destroy comment' do + @ability.should_not be_able_to(:destroy, @comment) + end + end + + context 'for project owner user' do + before(:each) do + @user = Factory(:user) + @stranger = Factory(:user) + + set_comments_data + + @project.update_attribute(:owner, @user) + @project.relations.create!(:object_type => 'User', :object_id => @user.id, :role => 'admin') + end + + it 'should create comment' do + @ability.should be_able_to(:create, Comment.new(@create_params)) + end + + it 'should update comment' do + @ability.should be_able_to(:update, @comment) + end + + it 'should update stranger comment' do + @ability.should be_able_to(:update, @stranger_comment) + end + + it 'should not destroy comment' do + @ability.should_not be_able_to(:destroy, @comment) + end + end + + context 'for simple user' do + before(:each) do + @user = Factory(:user) + @stranger = Factory(:user) + + set_comments_data + end + + it 'should create comment' do + @ability.should be_able_to(:create, Comment.new(@create_params)) + end + + it 'should update comment' do + @ability.should be_able_to(:update, @comment) + end + + it 'should not update stranger comment' do + @ability.should_not be_able_to(:update, @stranger_comment) + end + + it 'should not destroy comment' do + @ability.should_not be_able_to(:destroy, @comment) + end + end +end From e10dd56dffc3a8aca504f30f05a9945d05cc963a Mon Sep 17 00:00:00 2001 From: Alexander Machehin Date: Mon, 16 Jan 2012 00:10:50 +0600 Subject: [PATCH 22/67] [refs #18] refactoring --- app/views/comments/_list.html.haml | 33 ++++++++++++++++++++++++++++ app/views/git/commits/show.html.haml | 26 +--------------------- app/views/issues/show.html.haml | 26 +--------------------- 3 files changed, 35 insertions(+), 50 deletions(-) create mode 100644 app/views/comments/_list.html.haml diff --git a/app/views/comments/_list.html.haml b/app/views/comments/_list.html.haml new file mode 100644 index 000000000..0457e4c34 --- /dev/null +++ b/app/views/comments/_list.html.haml @@ -0,0 +1,33 @@ +%a{ :name => "comments" } +.block#block-list + .content + %h2.title + = t("layout.issues.comments_header") + .inner + %ul.list + - list.each do |comment| + %li + .left + = link_to comment.user.uname, user_path(comment.user.uname) + .item + = comment.body + %br + %br + - if commentable.class == Issue + - edit_path = edit_project_issue_comment_path(project, commentable.id, comment) + - delete_path = project_issue_comment_path(project, commentable.id, comment) + - elsif commentable.class == Grit::Commit + - edit_path = edit_project_commit_comment_path(project, commentable.id, comment) + - delete_path = project_commit_comment_path(project, commentable.id, comment) + = link_to t("layout.edit"), edit_path if can? :update, comment + = link_to image_tag("web-app-theme/icons/cross.png", :alt => t("layout.delete")) + " " + t("layout.delete"), delete_path, :method => "delete", :class => "button", :confirm => t("layout.comments.confirm_delete") if can? :delete, comment + +.block + .content + %h2.title + = t("layout.comments.new_header") + .inner + - new_path = project_issue_comments_path(project, commentable.id) if commentable.class == Issue + - new_path = project_commit_comments_path(project, commentable.id) if commentable.class == Grit::Commit + = form_for :comment, :url => new_path, :method => :post, :html => { :class => :form } do |f| + = render :partial => "comments/form", :locals => {:f => f} diff --git a/app/views/git/commits/show.html.haml b/app/views/git/commits/show.html.haml index 421c5d2e2..8f3ec67f8 100644 --- a/app/views/git/commits/show.html.haml +++ b/app/views/git/commits/show.html.haml @@ -27,28 +27,4 @@ - content_for :sidebar, render(:partial => 'git/shared/sidebar') -%a{ :name => "comments" } -.block#block-list - .content - %h2.title - = t("layout.issues.comments_header") - .inner - %ul.list - - Project.commit_comments(@commit, @project).each do |comment| - %li - .left - = link_to comment.user.uname, user_path(comment.user.uname) - .item - = comment.body - %br - %br - = link_to t("layout.edit"), edit_project_commit_comment_path(@project, @commit.id, comment) if can? :update, comment - = link_to image_tag("web-app-theme/icons/cross.png", :alt => t("layout.delete")) + " " + t("layout.delete"), project_commit_comment_path(@project, @commit.id, comment), :method => "delete", :class => "button", :confirm => t("layout.comments.confirm_delete") if can? :delete, comment - -.block - .content - %h2.title - = t("layout.comments.new_header") - .inner - = form_for :comment, :url => project_commit_comments_path(@project, @commit.id), :method => :post, :html => { :class => :form } do |f| - = render :partial => "comments/form", :locals => {:f => f} += render :partial => "comments/list", :locals => {:list => Project.commit_comments(@commit, @project), :project => @project, :commentable => @commit} diff --git a/app/views/issues/show.html.haml b/app/views/issues/show.html.haml index 2a79e66a3..f246dbfda 100644 --- a/app/views/issues/show.html.haml +++ b/app/views/issues/show.html.haml @@ -29,28 +29,4 @@ - else = link_to t('layout.issues.subscribe_btn'), project_issue_subscribes_path(@project, @issue), :method => :post -%a{ :name => "comments" } -.block#block-list - .content - %h2.title - = t("layout.issues.comments_header") - .inner - %ul.list - - @issue.comments.each do |comment| - %li - .left - = link_to comment.user.uname, user_path(comment.user.uname) - .item - = comment.body - %br - %br - = link_to t("layout.edit"), edit_project_issue_comment_path(@project, @issue.id, comment) if can? :update, comment - = link_to image_tag("web-app-theme/icons/cross.png", :alt => t("layout.delete")) + " " + t("layout.delete"), project_issue_comment_path(@project, @issue.id, comment), :method => "delete", :class => "button", :confirm => t("layout.comments.confirm_delete") if can? :delete, comment - -.block - .content - %h2.title - = t("layout.comments.new_header") - .inner - = form_for :comment, :url => project_issue_comments_path(@project, @issue.id), :method => :post, :html => { :class => :form } do |f| - = render :partial => "comments/form", :locals => {:f => f} += render :partial => "comments/list", :locals => {:list => @issue.comments, :project => @project, :commentable => @issue} From 69debdd83e6facd7dace9549db4a84912c1eca32 Mon Sep 17 00:00:00 2001 From: Alexander Machehin Date: Mon, 16 Jan 2012 19:43:23 +0600 Subject: [PATCH 23/67] fix tests for shared elements --- .../comments_controller_for_commit_spec.rb | 44 +++++++++---------- spec/models/comment_for_commit_spec.rb | 10 ++--- 2 files changed, 27 insertions(+), 27 deletions(-) diff --git a/spec/controllers/comments_controller_for_commit_spec.rb b/spec/controllers/comments_controller_for_commit_spec.rb index 07bdea33c..a8e82283b 100644 --- a/spec/controllers/comments_controller_for_commit_spec.rb +++ b/spec/controllers/comments_controller_for_commit_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -shared_examples_for 'user with create comment rights' do +shared_examples_for 'user with create comment rights for commits' do it 'should be able to perform create action' do post :create, @create_params response.should redirect_to(commit_path(@project, @commit.id)) @@ -11,7 +11,7 @@ shared_examples_for 'user with create comment rights' do end end -shared_examples_for 'user with update own comment rights' do +shared_examples_for 'user with update own comment rights for commits' do it 'should be able to perform update action' do put :update, {:id => @own_comment.id}.merge(@update_params) response.should redirect_to(commit_path(@project, @commit.id)) @@ -23,7 +23,7 @@ shared_examples_for 'user with update own comment rights' do end end -shared_examples_for 'user with update stranger comment rights' do +shared_examples_for 'user with update stranger comment rights for commits' do it 'should be able to perform update action' do put :update, {:id => @comment.id}.merge(@update_params) response.should redirect_to(commit_path(@project, @commit.id)) @@ -35,7 +35,7 @@ shared_examples_for 'user with update stranger comment rights' do end end -shared_examples_for 'user without update stranger comment rights' do +shared_examples_for 'user without update stranger comment rights for commits' do it 'should not be able to perform update action' do put :update, {:id => @comment.id}.merge(@update_params) response.should redirect_to(forbidden_path) @@ -47,7 +47,7 @@ shared_examples_for 'user without update stranger comment rights' do end end -shared_examples_for 'user without destroy comment rights' do +shared_examples_for 'user without destroy comment rights for commits' do it 'should not be able to perform destroy action' do delete :destroy, :id => @comment.id, :commit_id => @commit.id, :project_id => @project.id response.should redirect_to(forbidden_path) @@ -96,10 +96,10 @@ describe CommentsController do @own_comment.update_attributes(:commentable_type => @commit.class.name, :commentable_id => @commit.id) end - it_should_behave_like 'user with create comment rights' - it_should_behave_like 'user with update stranger comment rights' - it_should_behave_like 'user with update own comment rights' - it_should_behave_like 'user without destroy comment rights' + it_should_behave_like 'user with create comment rights for commits' + it_should_behave_like 'user with update stranger comment rights for commits' + it_should_behave_like 'user with update own comment rights for commits' + it_should_behave_like 'user without destroy comment rights for commits' end context 'for project owner user' do @@ -112,10 +112,10 @@ describe CommentsController do @own_comment.update_attributes(:commentable_type => @commit.class.name, :commentable_id => @commit.id) end - it_should_behave_like 'user with create comment rights' - it_should_behave_like 'user with update stranger comment rights' - it_should_behave_like 'user with update own comment rights' - it_should_behave_like 'user without destroy comment rights' + it_should_behave_like 'user with create comment rights for commits' + it_should_behave_like 'user with update stranger comment rights for commits' + it_should_behave_like 'user with update own comment rights for commits' + it_should_behave_like 'user without destroy comment rights for commits' end context 'for project reader user' do @@ -128,10 +128,10 @@ describe CommentsController do @own_comment.update_attributes(:commentable_type => @commit.class.name, :commentable_id => @commit.id) end - it_should_behave_like 'user with create comment rights' - it_should_behave_like 'user without update stranger comment rights' - it_should_behave_like 'user with update own comment rights' - it_should_behave_like 'user without destroy comment rights' + it_should_behave_like 'user with create comment rights for commits' + it_should_behave_like 'user without update stranger comment rights for commits' + it_should_behave_like 'user with update own comment rights for commits' + it_should_behave_like 'user without destroy comment rights for commits' end context 'for project writer user' do @@ -144,9 +144,9 @@ describe CommentsController do @own_comment.update_attributes(:commentable_type => @commit.class.name, :commentable_id => @commit.id) end - it_should_behave_like 'user with create comment rights' - it_should_behave_like 'user without update stranger comment rights' - it_should_behave_like 'user with update own comment rights' - it_should_behave_like 'user without destroy comment rights' + it_should_behave_like 'user with create comment rights for commits' + it_should_behave_like 'user without update stranger comment rights for commits' + it_should_behave_like 'user with update own comment rights for commits' + it_should_behave_like 'user without destroy comment rights for commits' end -end \ No newline at end of file +end diff --git a/spec/models/comment_for_commit_spec.rb b/spec/models/comment_for_commit_spec.rb index adcc70967..938c4db7e 100644 --- a/spec/models/comment_for_commit_spec.rb +++ b/spec/models/comment_for_commit_spec.rb @@ -1,7 +1,7 @@ require 'spec_helper' require "cancan/matchers" -def set_comments_data +def set_comments_data_for_commit @ability = Ability.new(@user) @project = Factory(:project) @@ -25,7 +25,7 @@ describe Comment do @user = Factory(:admin) @stranger = Factory(:user) - set_comments_data + set_comments_data_for_commit end it 'should create comment' do @@ -58,7 +58,7 @@ describe Comment do @user = Factory(:user) @stranger = Factory(:user) - set_comments_data + set_comments_data_for_commit @project.relations.create!(:object_type => 'User', :object_id => @user.id, :role => 'admin') end @@ -85,7 +85,7 @@ describe Comment do @user = Factory(:user) @stranger = Factory(:user) - set_comments_data + set_comments_data_for_commit @project.update_attribute(:owner, @user) @project.relations.create!(:object_type => 'User', :object_id => @user.id, :role => 'admin') @@ -113,7 +113,7 @@ describe Comment do @user = Factory(:user) @stranger = Factory(:user) - set_comments_data + set_comments_data_for_commit end it 'should create comment' do From 68744b16763102eef86ceef47a989a316c4b12bb Mon Sep 17 00:00:00 2001 From: Vladimir Sharshov Date: Tue, 17 Jan 2012 01:07:48 +0400 Subject: [PATCH 24/67] Fix broken tests in #94 from pull request #92 --- spec/controllers/comments_controller_spec.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/controllers/comments_controller_spec.rb b/spec/controllers/comments_controller_spec.rb index c93ac57f0..03d2813a5 100644 --- a/spec/controllers/comments_controller_spec.rb +++ b/spec/controllers/comments_controller_spec.rb @@ -77,8 +77,8 @@ describe CommentsController do @issue = Factory(:issue, :project_id => @project.id) @comment = Factory(:comment, :commentable => @issue) - @create_params = {:comment => {:body => 'I am a comment!'}, :project_id => @project.id, :issue_id => @issue.id} - @update_params = {:comment => {:body => 'updated'}, :project_id => @project.id, :issue_id => @issue.id} + @create_params = {:comment => {:body => 'I am a comment!'}, :project_id => @project.id, :issue_id => @issue.serial_id} + @update_params = {:comment => {:body => 'updated'}, :project_id => @project.id, :issue_id => @issue.serial_id} any_instance_of(Project, :versions => ['v1.0', 'v2.0']) From a687a6601b789e67cad77335cd393cb3393092f1 Mon Sep 17 00:00:00 2001 From: Pavel Chipiga Date: Mon, 16 Jan 2012 23:51:20 +0200 Subject: [PATCH 25/67] Save commit_hash during build_list create. Tag git repo during build_list publish. Write and fix specs. Refs #103 --- app/controllers/build_lists_controller.rb | 3 +++ .../20120113212924_add_commit_hash_to_build_lists.rb | 9 +++++++++ db/schema.rb | 3 ++- spec/controllers/build_lists_controller_spec.rb | 9 +++++++-- spec/factories/build_list_factory.rb | 1 + spec/spec_helper.rb | 5 +++++ 6 files changed, 27 insertions(+), 3 deletions(-) create mode 100644 db/migrate/20120113212924_add_commit_hash_to_build_lists.rb diff --git a/app/controllers/build_lists_controller.rb b/app/controllers/build_lists_controller.rb index 86d2b9064..63494911f 100644 --- a/app/controllers/build_lists_controller.rb +++ b/app/controllers/build_lists_controller.rb @@ -39,6 +39,7 @@ class BuildListsController < ApplicationController Arch.where(:id => params[:arches]).each do |arch| Platform.main.where(:id => params[:bpls]).each do |bpl| @build_list = @project.build_lists.build(params[:build_list]) + @build_list.commit_hash = @project.git_repository.commits(@build_list.project_version.match(/(.+)_latest$/).to_a.last || @build_list.project_version).first.id @build_list.bpl = bpl; @build_list.arch = arch; @build_list.user = current_user flash_options = {:project_version => @build_list.project_version, :arch => arch.name, :bpl => bpl.name, :pl => @build_list.pl} if @build_list.save @@ -83,6 +84,8 @@ class BuildListsController < ApplicationController if params[:status].to_i == 0 # ok @build_list.status = BuildList::BUILD_PUBLISHED @build_list.package_version = "#{params[:version]}-#{params[:release]}" + system("cd #{@build_list.project.git_repository.path} && + git tag -a -m '#{@build_list.package_version}' #{@build_list.package_version} #{@build_list.commit_hash}") # TODO REDO through grit else @build_list.status = BuildList::FAILED_PUBLISH end diff --git a/db/migrate/20120113212924_add_commit_hash_to_build_lists.rb b/db/migrate/20120113212924_add_commit_hash_to_build_lists.rb new file mode 100644 index 000000000..504d49f9a --- /dev/null +++ b/db/migrate/20120113212924_add_commit_hash_to_build_lists.rb @@ -0,0 +1,9 @@ +class AddCommitHashToBuildLists < ActiveRecord::Migration + def self.up + add_column :build_lists, :commit_hash, :string + end + + def self.down + remove_column :build_lists, :commit_hash + end +end diff --git a/db/schema.rb b/db/schema.rb index 83b6e610d..fd6715f37 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended to check this file into your version control system. -ActiveRecord::Schema.define(:version => 20120113151305) do +ActiveRecord::Schema.define(:version => 20120113212924) do create_table "arches", :force => true do |t| t.string "name", :null => false @@ -73,6 +73,7 @@ ActiveRecord::Schema.define(:version => 20120113151305) do t.integer "user_id" t.boolean "auto_publish", :default => true t.string "package_version" + t.string "commit_hash" end add_index "build_lists", ["arch_id"], :name => "index_build_lists_on_arch_id" diff --git a/spec/controllers/build_lists_controller_spec.rb b/spec/controllers/build_lists_controller_spec.rb index e337c1fd6..6566a7f93 100644 --- a/spec/controllers/build_lists_controller_spec.rb +++ b/spec/controllers/build_lists_controller_spec.rb @@ -27,6 +27,8 @@ describe BuildListsController do end shared_examples_for 'create build list' do + before {test_git_commit(@project)} + it 'should be able to perform new action' do get :new, :project_id => @project.id response.should render_template(:new) @@ -34,6 +36,7 @@ describe BuildListsController do it 'should be able to perform create action' do post :create, {:project_id => @project.id}.merge(@create_params) + @project.build_lists.last.commit_hash.should == @project.git_repository.commits.last.id response.should redirect_to(@project) end end @@ -57,7 +60,7 @@ describe BuildListsController do platform = Factory(:platform_with_repos) @create_params = { :build_list => { - :project_version => 'v1.0', + :project_version => 'master_latest', :pl_id => platform.id, :update_type => 'security', :include_repos => [platform.repositories.first.id] @@ -299,12 +302,14 @@ describe BuildListsController do let(:build_list) { Factory(:build_list_core) } describe 'publish_build' do + before {test_git_commit(build_list.project); build_list.update_attribute :commit_hash, build_list.project.git_repository.commits.last.id} + def do_get(status) get :publish_build, :id => build_list.bs_id, :status => status, :version => '4.7.5.3', :release => '1' build_list.reload end - it { do_get(BuildServer::SUCCESS); response.should be_ok } + it { do_get(BuildServer::SUCCESS); build_list.project.git_repository.tags.last.name.should == build_list.package_version; response.should be_ok } it { lambda{ do_get(BuildServer::SUCCESS) }.should change(build_list, :status).to(BuildList::BUILD_PUBLISHED) } it { lambda{ do_get(BuildServer::SUCCESS) }.should change(build_list, :package_version).to('4.7.5.3-1') } it { lambda{ do_get(BuildServer::ERROR) }.should change(build_list, :status).to(BuildList::FAILED_PUBLISH) } diff --git a/spec/factories/build_list_factory.rb b/spec/factories/build_list_factory.rb index 10c4fc3b5..608c48a50 100644 --- a/spec/factories/build_list_factory.rb +++ b/spec/factories/build_list_factory.rb @@ -8,6 +8,7 @@ Factory.define(:build_list) do |p| p.build_requires true p.update_type 'security' p.include_repos {|bl| bl.pl.repositories.map(&:id)} + p.commit_hash 'e681644ed702fae285483d2ca73d85ee2930b8de' end Factory.define(:build_list_core, :parent => :build_list) do |p| diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index a79b3ce74..095a7030f 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -37,6 +37,11 @@ def stub_rsync_methods any_instance_of(Platform, :umount_directory_for_rsync => true) end +def test_git_commit(project) + project.git_repository.repo.index.add('test', 'TEST') + project.git_repository.repo.index.commit('Test commit') +end + Delayed::Worker.delay_jobs = false # Execute all jobs realtime # Add testing root_path From ee58a8e7898ec427eb2341fd3d498f2a2bb11df2 Mon Sep 17 00:00:00 2001 From: "konstantin.grabar" Date: Tue, 17 Jan 2012 12:17:12 +0400 Subject: [PATCH 26/67] [refs #54] Fix comments failed specs --- spec/models/comment_spec.rb | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/spec/models/comment_spec.rb b/spec/models/comment_spec.rb index f7d43cb14..a8b8b41dc 100644 --- a/spec/models/comment_spec.rb +++ b/spec/models/comment_spec.rb @@ -1,7 +1,7 @@ require 'spec_helper' require "cancan/matchers" -def set_comments_data +def set_commentable_data @ability = Ability.new(@user) @project = Factory(:project) @@ -19,7 +19,7 @@ describe Comment do @user = Factory(:admin) @stranger = Factory(:user) - set_comments_data + set_commentable_data end it 'should create comment' do @@ -52,7 +52,7 @@ describe Comment do @user = Factory(:user) @stranger = Factory(:user) - set_comments_data + set_commentable_data @project.relations.create!(:object_type => 'User', :object_id => @user.id, :role => 'admin') end @@ -79,7 +79,7 @@ describe Comment do @user = Factory(:user) @stranger = Factory(:user) - set_comments_data + set_commentable_data @project.update_attribute(:owner, @user) @project.relations.create!(:object_type => 'User', :object_id => @user.id, :role => 'admin') @@ -107,7 +107,7 @@ describe Comment do @user = Factory(:user) @stranger = Factory(:user) - set_comments_data + set_commentable_data end it 'should create comment' do From 95b4e2557ce74653253574822a617e5cbdc3456c Mon Sep 17 00:00:00 2001 From: Alexander Machehin Date: Tue, 17 Jan 2012 16:30:11 +0600 Subject: [PATCH 27/67] [refs #18] forgot comments order --- app/views/git/commits/show.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/git/commits/show.html.haml b/app/views/git/commits/show.html.haml index 8f3ec67f8..7f7cc2d58 100644 --- a/app/views/git/commits/show.html.haml +++ b/app/views/git/commits/show.html.haml @@ -27,4 +27,4 @@ - content_for :sidebar, render(:partial => 'git/shared/sidebar') -= render :partial => "comments/list", :locals => {:list => Project.commit_comments(@commit, @project), :project => @project, :commentable => @commit} += render :partial => "comments/list", :locals => {:list => Project.commit_comments(@commit, @project).order(:created_at), :project => @project, :commentable => @commit} From fab62c548f219f72625b46899c6ddf08f8b5ac6f Mon Sep 17 00:00:00 2001 From: Pavel Chipiga Date: Tue, 17 Jan 2012 13:04:50 +0200 Subject: [PATCH 28/67] Hide container_path if build_list published. Cleanup translations. Refs #100 --- app/views/build_lists/show.html.haml | 4 +++- config/locales/ru.yml | 13 +------------ 2 files changed, 4 insertions(+), 13 deletions(-) diff --git a/app/views/build_lists/show.html.haml b/app/views/build_lists/show.html.haml index 9c7e779c5..1cd64f1e8 100644 --- a/app/views/build_lists/show.html.haml +++ b/app/views/build_lists/show.html.haml @@ -21,7 +21,9 @@ %b = t("activerecord.attributes.build_list.container_path") \: - - if @build_list.container_path.present? + - if @build_list.status == BuildList::BUILD_PUBLISHED + = t("layout.build_lists.container_published") + - elsif @build_list.container_path.present? - container_url = "http://#{request.host_with_port}/downloads#{@build_list.container_path}" = link_to container_url, container_url %p diff --git a/config/locales/ru.yml b/config/locales/ru.yml index f5187e225..595d872b8 100644 --- a/config/locales/ru.yml +++ b/config/locales/ru.yml @@ -165,18 +165,6 @@ ru: confirm_clone: Клонировать? clone: Клонировать - roles: - confirm_delete: Вы уверены, что хотите удалить эту роль? - list_header: Роли - list: Список - new: Создать - get_dump: Скачать в YML - from_file: Загрузить из файлa - wrong_file_type: Неверный тип файла - wrong_file_format: Неверный формат файла - successful_load: Все роли успешно загружены - seeding_fail: Ошибка при записи в базу - event_logs: list: Список list_header: Лог событий @@ -334,6 +322,7 @@ ru: cancel_fail: 'При отмене сборки произошла ошибка!' publish_success: 'Сборка поставлена в очередь на публикацию.' publish_fail: 'При публикации сборки произошла ошибка!' + container_published: 'Контейнер размещен в репозитории' build_server_status: header: Статус сборочного сервера From a0aad7103e5c699e9f9f9fd864a5d0b2362b95e1 Mon Sep 17 00:00:00 2001 From: Alexander Machehin Date: Tue, 17 Jan 2012 17:17:27 +0600 Subject: [PATCH 29/67] some fixes --- app/models/project.rb | 2 +- app/views/git/blobs/show.html.haml | 17 ----------------- app/views/git/commits/show.html.haml | 2 +- 3 files changed, 2 insertions(+), 19 deletions(-) diff --git a/app/models/project.rb b/app/models/project.rb index 4cc5c143c..5763fc071 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -136,7 +136,7 @@ class Project < ActiveRecord::Base class << self def commit_comments(commit, project) - comments = Comment.where(:commentable_id => commit.id, :commentable_type => 'Grit::Commit') + comments = Comment.where(:commentable_id => commit.id, :commentable_type => 'Grit::Commit').order(:created_at) comments.each {|x| x.project = project} end end diff --git a/app/views/git/blobs/show.html.haml b/app/views/git/blobs/show.html.haml index b9c8e79a8..a02bcd20c 100644 --- a/app/views/git/blobs/show.html.haml +++ b/app/views/git/blobs/show.html.haml @@ -32,20 +32,3 @@
#{render_blob(@blob)}
- content_for :sidebar, render(:partial => 'git/shared/sidebar') - -%a{ :name => "comments" } -.block#block-list - .content - %h2.title - = t("layout.issues.comments_header") - .inner - %ul.list - - @project.commit_comments(@commit).each do |comment| - %li - .left - = link_to comment.user.uname, user_path(comment.user.uname) - .item - = comment.body - %br - %br - diff --git a/app/views/git/commits/show.html.haml b/app/views/git/commits/show.html.haml index 7f7cc2d58..8f3ec67f8 100644 --- a/app/views/git/commits/show.html.haml +++ b/app/views/git/commits/show.html.haml @@ -27,4 +27,4 @@ - content_for :sidebar, render(:partial => 'git/shared/sidebar') -= render :partial => "comments/list", :locals => {:list => Project.commit_comments(@commit, @project).order(:created_at), :project => @project, :commentable => @commit} += render :partial => "comments/list", :locals => {:list => Project.commit_comments(@commit, @project), :project => @project, :commentable => @commit} From 726eddc40e85a73072895fa2ce336e50f3aa472a Mon Sep 17 00:00:00 2001 From: "konstantin.grabar" Date: Tue, 17 Jan 2012 15:48:40 +0400 Subject: [PATCH 30/67] [refs #105] Add internationalization support to project --- app/controllers/application_controller.rb | 45 ++++++++++++------- app/models/user.rb | 3 +- app/views/devise/registrations/edit.html.haml | 6 +++ app/views/devise/registrations/new.html.haml | 6 +++ config/locales/ru.yml | 1 + .../20120117110723_add_language_to_users.rb | 9 ++++ db/schema.rb | 9 ++-- 7 files changed, 59 insertions(+), 20 deletions(-) create mode 100644 db/migrate/20120117110723_add_language_to_users.rb diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 4a64259cd..ebd709918 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -1,8 +1,10 @@ # coding: UTF-8 class ApplicationController < ActionController::Base protect_from_forgery + layout :layout_by_resource + before_filter :set_locale before_filter lambda { EventLog.current_controller = self }, :only => [:create, :destroy, :open_id, :auto_build, :cancel, :publish, :change_visibility] # :update after_filter lambda { EventLog.current_controller = nil } @@ -14,26 +16,39 @@ class ApplicationController < ActionController::Base end protected - def get_owner + + def set_locale + I18n.locale = extract_locale_from_request + end + + def extract_locale_from_request + get_user_locale || request.env['HTTP_ACCEPT_LANGUAGE'].to_sym || :en + end + + def get_user_locale + user_signed_in? ? current_user.language : nil + end + + def get_owner # params['user_id'] && User.find_by_id(params['user_id']) || # params['group_id'] && Group.find_by_id(params['group_id']) || current_user - if self.class.method_defined? :parent - if parent and (parent.is_a? User or parent.is_a? Group) - return parent - else - return current_user - end + if self.class.method_defined? :parent + if parent and (parent.is_a? User or parent.is_a? Group) + return parent else - params['user_id'] && User.find_by_id(params['user_id']) || - params['group_id'] && Group.find_by_id(params['group_id']) || current_user + return current_user end + else + params['user_id'] && User.find_by_id(params['user_id']) || + params['group_id'] && Group.find_by_id(params['group_id']) || current_user end + end - def layout_by_resource - if devise_controller? - "sessions" - else - "application" - end + def layout_by_resource + if devise_controller? + "sessions" + else + "application" end + end end diff --git a/app/models/user.rb b/app/models/user.rb index c246dd6f9..e0de8317a 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -1,5 +1,6 @@ class User < ActiveRecord::Base ROLES = ['admin'] + LANGUAGES = [['Russian', 'ru'], ['English', 'en']] devise :database_authenticatable, :registerable, :omniauthable, # :token_authenticatable, :encryptable, :timeoutable :recoverable, :rememberable, :validatable #, :trackable, :confirmable, :lockable @@ -29,7 +30,7 @@ class User < ActiveRecord::Base validates :ssh_key, :uniqueness => true, :allow_blank => true validates :role, :inclusion => {:in => ROLES}, :allow_blank => true - attr_accessible :email, :password, :password_confirmation, :remember_me, :login, :name, :ssh_key, :uname + attr_accessible :email, :password, :password_confirmation, :remember_me, :login, :name, :ssh_key, :uname, :language attr_readonly :uname attr_accessor :login diff --git a/app/views/devise/registrations/edit.html.haml b/app/views/devise/registrations/edit.html.haml index c4b6052ab..fc441a6c5 100644 --- a/app/views/devise/registrations/edit.html.haml +++ b/app/views/devise/registrations/edit.html.haml @@ -39,6 +39,12 @@ - else = resource.role + .group.wat-cf + .left + = f.label :language, :class => "label" + .right + = f.select :language, User::LANGUAGES + / .group.wat-cf / .left / = f.label :current_password, :class => "label" diff --git a/app/views/devise/registrations/new.html.haml b/app/views/devise/registrations/new.html.haml index aeddc6958..5cc31a6c8 100644 --- a/app/views/devise/registrations/new.html.haml +++ b/app/views/devise/registrations/new.html.haml @@ -37,6 +37,12 @@ .right = f.password_field :password_confirmation, :class => "text_field" + .group.wat-cf + .left + = f.label :language, :class => "label" + .right + = f.select :language, User::LANGUAGES + .group.navform.wat-cf %button.button{ :type => "submit" } #{image_tag("web-app-theme/icons/tick.png", :alt => t("devise.registrations.sign_up_header"))} #{t("devise.registrations.sign_up_header")} diff --git a/config/locales/ru.yml b/config/locales/ru.yml index f5187e225..8ee23a3e1 100644 --- a/config/locales/ru.yml +++ b/config/locales/ru.yml @@ -648,6 +648,7 @@ ru: created_at: Создан updated_at: Обновлен role: Роль в системе + language: Язык product_build_list: id: Id diff --git a/db/migrate/20120117110723_add_language_to_users.rb b/db/migrate/20120117110723_add_language_to_users.rb new file mode 100644 index 000000000..4bf0cec48 --- /dev/null +++ b/db/migrate/20120117110723_add_language_to_users.rb @@ -0,0 +1,9 @@ +class AddLanguageToUsers < ActiveRecord::Migration + def self.up + add_column :users, :language, :string, :default => 'en' + end + + def self.down + remove_column :users, :language + end +end diff --git a/db/schema.rb b/db/schema.rb index 37e09fcc4..55bf19f7e 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended to check this file into your version control system. -ActiveRecord::Schema.define(:version => 20120113151305) do +ActiveRecord::Schema.define(:version => 20120117110723) do create_table "arches", :force => true do |t| t.string "name", :null => false @@ -294,9 +294,9 @@ ActiveRecord::Schema.define(:version => 20120113151305) do create_table "users", :force => true do |t| t.string "name" - t.string "email", :default => "", :null => false - t.string "encrypted_password", :limit => 128, :default => "", :null => false - t.string "password_salt", :default => "", :null => false + t.string "email", :default => "", :null => false + t.string "encrypted_password", :limit => 128, :default => "", :null => false + t.string "password_salt", :default => "", :null => false t.string "reset_password_token" t.string "remember_token" t.datetime "remember_created_at" @@ -305,6 +305,7 @@ ActiveRecord::Schema.define(:version => 20120113151305) do t.text "ssh_key" t.string "uname" t.string "role" + t.string "language", :default => "en" end add_index "users", ["email"], :name => "index_users_on_email", :unique => true From d205eb2dd9ac5122c949225d53423a2a2e219bfc Mon Sep 17 00:00:00 2001 From: "konstantin.grabar" Date: Tue, 17 Jan 2012 15:57:46 +0400 Subject: [PATCH 31/67] [refs #105] Add language check on user save --- app/controllers/application_controller.rb | 10 +++++----- app/models/user.rb | 4 +++- app/views/devise/registrations/edit.html.haml | 2 +- app/views/devise/registrations/new.html.haml | 2 +- 4 files changed, 10 insertions(+), 8 deletions(-) diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index ebd709918..b304e8821 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -18,17 +18,17 @@ class ApplicationController < ActionController::Base protected def set_locale - I18n.locale = extract_locale_from_request - end - - def extract_locale_from_request - get_user_locale || request.env['HTTP_ACCEPT_LANGUAGE'].to_sym || :en + I18n.locale = check_locale( get_user_locale || request.env['HTTP_ACCEPT_LANGUAGE'].to_sym ) end def get_user_locale user_signed_in? ? current_user.language : nil end + def check_locale(locale) + User::LANGUAGES.include?(locale.to_s) ? locale : :en + end + def get_owner # params['user_id'] && User.find_by_id(params['user_id']) || # params['group_id'] && Group.find_by_id(params['group_id']) || current_user diff --git a/app/models/user.rb b/app/models/user.rb index e0de8317a..fbd14bdb4 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -1,6 +1,7 @@ class User < ActiveRecord::Base ROLES = ['admin'] - LANGUAGES = [['Russian', 'ru'], ['English', 'en']] + LANGUAGES = ['ru', 'en'] + LANGUAGES_FOR_SELECT = [['Russian', 'ru'], ['English', 'en']] devise :database_authenticatable, :registerable, :omniauthable, # :token_authenticatable, :encryptable, :timeoutable :recoverable, :rememberable, :validatable #, :trackable, :confirmable, :lockable @@ -29,6 +30,7 @@ class User < ActiveRecord::Base validate { errors.add(:uname, :taken) if Group.where('uname LIKE ?', uname).present? } validates :ssh_key, :uniqueness => true, :allow_blank => true validates :role, :inclusion => {:in => ROLES}, :allow_blank => true + validates :language, :inclusion => {:in => LANGUAGES}, :allow_blank => true attr_accessible :email, :password, :password_confirmation, :remember_me, :login, :name, :ssh_key, :uname, :language attr_readonly :uname diff --git a/app/views/devise/registrations/edit.html.haml b/app/views/devise/registrations/edit.html.haml index fc441a6c5..b983f1836 100644 --- a/app/views/devise/registrations/edit.html.haml +++ b/app/views/devise/registrations/edit.html.haml @@ -43,7 +43,7 @@ .left = f.label :language, :class => "label" .right - = f.select :language, User::LANGUAGES + = f.select :language, User::LANGUAGES_FOR_SELECT / .group.wat-cf / .left diff --git a/app/views/devise/registrations/new.html.haml b/app/views/devise/registrations/new.html.haml index 5cc31a6c8..5c9d0de5d 100644 --- a/app/views/devise/registrations/new.html.haml +++ b/app/views/devise/registrations/new.html.haml @@ -41,7 +41,7 @@ .left = f.label :language, :class => "label" .right - = f.select :language, User::LANGUAGES + = f.select :language, User::LANGUAGES_FOR_SELECT .group.navform.wat-cf %button.button{ :type => "submit" } From b5170e2f2a151a71e4582b7ee4662be25af6f585 Mon Sep 17 00:00:00 2001 From: Pavel Chipiga Date: Tue, 17 Jan 2012 14:25:54 +0200 Subject: [PATCH 32/67] Write specs for tag based build. Refs #103 --- spec/controllers/build_lists_controller_spec.rb | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/spec/controllers/build_lists_controller_spec.rb b/spec/controllers/build_lists_controller_spec.rb index 6566a7f93..3dbba5397 100644 --- a/spec/controllers/build_lists_controller_spec.rb +++ b/spec/controllers/build_lists_controller_spec.rb @@ -36,9 +36,19 @@ describe BuildListsController do it 'should be able to perform create action' do post :create, {:project_id => @project.id}.merge(@create_params) - @project.build_lists.last.commit_hash.should == @project.git_repository.commits.last.id response.should redirect_to(@project) end + + it 'should save correct commit_hash for branch based build' do + post :create, {:project_id => @project.id}.merge(@create_params).deep_merge(:build_list => {:project_version => "master_latest"}) + @project.build_lists.last.commit_hash.should == @project.git_repository.commits('master').last.id + end + + it 'should save correct commit_hash for tag based build' do + system("cd #{@project.git_repository.path} && git tag -a -m '4.7.5.3' 4.7.5.3") # TODO REDO through grit + post :create, {:project_id => @project.id}.merge(@create_params).deep_merge(:build_list => {:project_version => "4.7.5.3"}) + @project.build_lists.last.commit_hash.should == @project.git_repository.commits('4.7.5.3').last.id + end end shared_examples_for 'not create build list' do From f8be867aaf7bbf277c9f0064f604f3e4fc26b847 Mon Sep 17 00:00:00 2001 From: Pavel Chipiga Date: Tue, 17 Jan 2012 19:37:41 +0200 Subject: [PATCH 33/67] Replace annotated tags to lightweight. Improve specs. Restore lost migrations. Refs #103 --- app/controllers/build_lists_controller.rb | 3 +-- db/migrate/20111012223306_create_roles.rb | 14 ++++++++++++++ db/migrate/20111019173246_create_role_lines.rb | 13 +++++++++++++ spec/controllers/build_lists_controller_spec.rb | 11 ++++++++--- spec/factories/build_list_factory.rb | 2 +- 5 files changed, 37 insertions(+), 6 deletions(-) create mode 100644 db/migrate/20111012223306_create_roles.rb create mode 100644 db/migrate/20111019173246_create_role_lines.rb diff --git a/app/controllers/build_lists_controller.rb b/app/controllers/build_lists_controller.rb index 63494911f..e0ce08136 100644 --- a/app/controllers/build_lists_controller.rb +++ b/app/controllers/build_lists_controller.rb @@ -84,8 +84,7 @@ class BuildListsController < ApplicationController if params[:status].to_i == 0 # ok @build_list.status = BuildList::BUILD_PUBLISHED @build_list.package_version = "#{params[:version]}-#{params[:release]}" - system("cd #{@build_list.project.git_repository.path} && - git tag -a -m '#{@build_list.package_version}' #{@build_list.package_version} #{@build_list.commit_hash}") # TODO REDO through grit + system("cd #{@build_list.project.git_repository.path} && git tag #{@build_list.package_version} #{@build_list.commit_hash}") # TODO REDO through grit else @build_list.status = BuildList::FAILED_PUBLISH end diff --git a/db/migrate/20111012223306_create_roles.rb b/db/migrate/20111012223306_create_roles.rb new file mode 100644 index 000000000..b5693219d --- /dev/null +++ b/db/migrate/20111012223306_create_roles.rb @@ -0,0 +1,14 @@ +class CreateRoles < ActiveRecord::Migration + def self.up + create_table :roles do |t| + t.integer :id + t.string :name + + t.timestamps + end + end + + def self.down + drop_table :roles + end +end diff --git a/db/migrate/20111019173246_create_role_lines.rb b/db/migrate/20111019173246_create_role_lines.rb new file mode 100644 index 000000000..84aa4e3de --- /dev/null +++ b/db/migrate/20111019173246_create_role_lines.rb @@ -0,0 +1,13 @@ +class CreateRoleLines < ActiveRecord::Migration + def self.up + create_table :role_lines do |t| + t.integer :role_id + t.integer :relation_id + t.timestamps + end + end + + def self.down + drop_table :role_lines + end +end diff --git a/spec/controllers/build_lists_controller_spec.rb b/spec/controllers/build_lists_controller_spec.rb index 3dbba5397..79035ac97 100644 --- a/spec/controllers/build_lists_controller_spec.rb +++ b/spec/controllers/build_lists_controller_spec.rb @@ -45,7 +45,7 @@ describe BuildListsController do end it 'should save correct commit_hash for tag based build' do - system("cd #{@project.git_repository.path} && git tag -a -m '4.7.5.3' 4.7.5.3") # TODO REDO through grit + system("cd #{@project.git_repository.path} && git tag 4.7.5.3") # TODO REDO through grit post :create, {:project_id => @project.id}.merge(@create_params).deep_merge(:build_list => {:project_version => "4.7.5.3"}) @project.build_lists.last.commit_hash.should == @project.git_repository.commits('4.7.5.3').last.id end @@ -312,14 +312,19 @@ describe BuildListsController do let(:build_list) { Factory(:build_list_core) } describe 'publish_build' do - before {test_git_commit(build_list.project); build_list.update_attribute :commit_hash, build_list.project.git_repository.commits.last.id} + before { test_git_commit(build_list.project); build_list.update_attribute :commit_hash, build_list.project.git_repository.commits('master').last.id } def do_get(status) get :publish_build, :id => build_list.bs_id, :status => status, :version => '4.7.5.3', :release => '1' build_list.reload end - it { do_get(BuildServer::SUCCESS); build_list.project.git_repository.tags.last.name.should == build_list.package_version; response.should be_ok } + it { do_get(BuildServer::SUCCESS); response.should be_ok } + it 'should create correct git tag for correct commit' do + do_get(BuildServer::SUCCESS) + build_list.project.git_repository.tags.last.name.should == build_list.package_version + build_list.project.git_repository.commits(build_list.package_version).last.id.should == build_list.commit_hash + end it { lambda{ do_get(BuildServer::SUCCESS) }.should change(build_list, :status).to(BuildList::BUILD_PUBLISHED) } it { lambda{ do_get(BuildServer::SUCCESS) }.should change(build_list, :package_version).to('4.7.5.3-1') } it { lambda{ do_get(BuildServer::ERROR) }.should change(build_list, :status).to(BuildList::FAILED_PUBLISH) } diff --git a/spec/factories/build_list_factory.rb b/spec/factories/build_list_factory.rb index 608c48a50..751a6ea09 100644 --- a/spec/factories/build_list_factory.rb +++ b/spec/factories/build_list_factory.rb @@ -8,7 +8,7 @@ Factory.define(:build_list) do |p| p.build_requires true p.update_type 'security' p.include_repos {|bl| bl.pl.repositories.map(&:id)} - p.commit_hash 'e681644ed702fae285483d2ca73d85ee2930b8de' + p.commit_hash '1234567890abcdef1234567890abcdef12345678' end Factory.define(:build_list_core, :parent => :build_list) do |p| From 310e11b666558ebac9273a51e03d047f0e2085bd Mon Sep 17 00:00:00 2001 From: Alexander Machehin Date: Wed, 18 Jan 2012 00:33:42 +0600 Subject: [PATCH 34/67] [refs #18] Fix if blocking referer --- app/controllers/comments_controller.rb | 15 +++++++++++---- app/views/comments/_form.html.haml | 2 +- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/app/controllers/comments_controller.rb b/app/controllers/comments_controller.rb index efceb8033..6f699a602 100644 --- a/app/controllers/comments_controller.rb +++ b/app/controllers/comments_controller.rb @@ -17,7 +17,7 @@ class CommentsController < ApplicationController @comment.user = current_user if @comment.save flash[:notice] = I18n.t("flash.comment.saved") - redirect_to :back + redirect_to commentable_path else flash[:error] = I18n.t("flash.comment.save_error") render :action => 'new' @@ -31,13 +31,13 @@ class CommentsController < ApplicationController when "Grit::Commit" project_commit_comment_path(@project, @commentable, @comment) end + @commentable_path = commentable_path end def update if @comment.update_attributes(params[:comment]) flash[:notice] = I18n.t("flash.comment.saved") - redirect_to :back - #redirect_to @commentable.class == Issue ? project_issue_path(@project, @commentable) : commit_path(@project.id, @commentable.id) + redirect_to commentable_path else flash[:error] = I18n.t("flash.comment.save_error") render :action => 'new' @@ -48,7 +48,7 @@ class CommentsController < ApplicationController @comment.destroy flash[:notice] = t("flash.comment.destroyed") - redirect_to :back + redirect_to commentable_path end private @@ -80,4 +80,11 @@ class CommentsController < ApplicationController def find_project @project = Project.find(params[:project_id]) end + + protected + + def commentable_path + @commentable.class == Issue ? [@project, @commentable] : commit_path(@project, @commentable.id) + end + end diff --git a/app/views/comments/_form.html.haml b/app/views/comments/_form.html.haml index 462aca983..3600e8d2b 100644 --- a/app/views/comments/_form.html.haml +++ b/app/views/comments/_form.html.haml @@ -7,4 +7,4 @@ = image_tag("web-app-theme/icons/tick.png", :alt => t("layout.save")) = t("layout.save") %span.text_button_padding= t("layout.or") - = link_to t("layout.cancel"), :back , :class => "text_button_padding link_button" + = link_to t("layout.cancel"), @commentable_path , :class => "text_button_padding link_button" From 01d8cd8dcc3a006c69506beb0620ac8612efa7a2 Mon Sep 17 00:00:00 2001 From: "konstantin.grabar" Date: Wed, 18 Jan 2012 17:06:18 +0400 Subject: [PATCH 35/67] [refs #105] Change LANGUAGE constant into User --- app/models/user.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/user.rb b/app/models/user.rb index fbd14bdb4..16a399caa 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -1,7 +1,7 @@ class User < ActiveRecord::Base ROLES = ['admin'] - LANGUAGES = ['ru', 'en'] LANGUAGES_FOR_SELECT = [['Russian', 'ru'], ['English', 'en']] + LANGUAGES = LANGUAGES_FOR_SELECT.map(&:last) devise :database_authenticatable, :registerable, :omniauthable, # :token_authenticatable, :encryptable, :timeoutable :recoverable, :rememberable, :validatable #, :trackable, :confirmable, :lockable From bd6abf2681dc26fad6a4974b4f2b3f45692e131b Mon Sep 17 00:00:00 2001 From: "konstantin.grabar" Date: Thu, 19 Jan 2012 00:58:38 +0400 Subject: [PATCH 36/67] [refs #105] Add locale fixes --- app/controllers/application_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index b304e8821..494f54ae1 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -18,7 +18,7 @@ class ApplicationController < ActionController::Base protected def set_locale - I18n.locale = check_locale( get_user_locale || request.env['HTTP_ACCEPT_LANGUAGE'].to_sym ) + I18n.locale = check_locale( get_user_locale || request.env['HTTP_ACCEPT_LANGUAGE'] ) end def get_user_locale From 14fdc35eb95e77d9583fe0721ac9bba4a663f162 Mon Sep 17 00:00:00 2001 From: Vladimir Sharshov Date: Thu, 19 Jan 2012 13:34:05 +0400 Subject: [PATCH 37/67] Add english localization. Refs #105 --- config/locales/en.yml | 693 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 688 insertions(+), 5 deletions(-) diff --git a/config/locales/en.yml b/config/locales/en.yml index a747bfa69..989f93873 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -1,5 +1,688 @@ -# Sample localization file for English. Add more files in this directory for other locales. -# See http://github.com/svenfuchs/rails-i18n/tree/master/rails%2Flocale for starting points. - -en: - hello: "Hello world" +en: + will_paginate: + previous_label: ‹ Previous + next_label: Next › + page_gap: ... + + datatables: + previous_label: ‹ Prev. + next_label: Next › + first_label: « First + last_label: Last » + empty_label: No data accessible + info_label: Records displayed from _START_ to _END_ total _TOTAL_ + info_empty_label: Records displayed from 0 to 0 total 0 + filtered_label: (filtered of _MAX_) + + layout: + logged_in_as: You logged as + logout: Logout + user_list: User list + edit: Edit + show: View + cancel: Cancel + create: Create + delete: Erase + save: Save + search: Search + clone: Clone + search_by_name: Filter by name + are_you_sure: "Sure?" + login: Login + or: or + yes_: Yes + no_: No + true_: True + false_: False + publish: Publish + add: Add + upload: Upload + not_access: Access denied! + owner: Owner + confirm: Sure? + settings: + notifier: Notifier setting + notifiers: + edit_header: Notifier setting + processing: working ... + + downloads: + title: Downloads statistic + message: Automatically updated every 5 minutes + refresh_btn: Refresh + + auto_build_lists: + header: Automated build projects + message: All projects build under user repository and architecture i586 + project: Project + action: Action + automate_btn: Automate + cancel_btn: Cancel + not_automated: Not automated + already_automated: Automated + + weekdays: + Monday: Monday + Tuesday: Tuesday + Wednesday: Wednesday + Thursday: Thursday + Friday: Friday + Saturday: Saturday + Sunday: Sunday + + menu: + categories: Catalogue + containers: Containers + downloads: Statistics + event_logs: Event log + build_lists: Task monitoring + groups: Groups + platforms: Platforms + products: Products + projects: Projects + repositories: Repositories + rights: Rights + roles: Roles + users: Users + personal_repository: My repository + auto_build_lists: Automated build + + sessions: + sign_in_header: Sign in + + private_users: + list: List + new: New pair + list_header: Pair login/password + confirm_delete: Are you sure to delete this pair login/password? + confirm_regenerate: Are you sure to regenerate this pair login/password? + regenerate_btn: Regenerate + warning_message: Warning - Old data set as invalid when new data obtaining + categories: + list: List + new: Create + edit: Edit + platforms: By platform + list_header: Catalogue + new_header: New category + edit_header: Edit category + confirm_delete: Are you sure to delete this category? + + issues: + list: List + edit: Edit + comments_header: Comments + new: New task + list_header: List + confirm_delete: Are you sure to delete this task? + edit_header: Task edit + new_header: New task + open: Opened + closed: Closed + any: Any + subscribe: Subscribe + subscribe_btn: Subscribe + unsubscribe_btn: Unsubscribe + + comments: + confirm_delete: Are you sure to delete the comment? + new_header: New comment + + platforms: + admin_id: Owner + build_all: Build all + list: List + new: Create + edit: Edit + new_header: New platform + edit_header: Edit + list_header: Platforms + list_header_main: General + list_header_personal: Personal + list_header_all: All + clone_header: Platform clone + show: Platform + projects: Projects + products: Products + location: Location + repositories: Repositories + back_to_the_list: ⇐To platform list + freeze: Freeze + unfreeze: Unfeeze + confirm_freeze: Are you sure to freeze this platform? + confirm_freeze: Are you sure to clone this platform? + confirm_unfreeze: Are you sure to defrost this platform? + released_suffix: (released) + confirm_delete: Are you sure to delete this platform? + current_platform_header: Current platform + owner: Owner + visibility: Visibility + platform_type: Platform type + distrib_type: Distribution kit type + private_users: Access data + confirm_clone: To clone? + clone: To clone + + event_logs: + list:List + list_header: Event log + + repositories: + list: List + list_header: Repositories + new: New repository + new_header: New repository + show: Repository + location: Location + projects: Projects + new_header: New repository + back_to_the_list: ⇐ List of repositories + confirm_delete: Are you sure to delete this repository? + current_repository_header: Current repository + + personal_repositories: + settings_header: Settings + change_visibility_from_hidden: Replace the status to "Opened" + change_visibility_from_open: Replace the status to "Private" + settings: Settings + show: My repository + private_users: Private repository users + + products: + list: List + new:New product + list_header: Products + clone: Clone + build: Build + new_header: New product + edit_header: Product editing + confirm_delete: Are you sure to delete this product? + invalid_content_type: incorrect type + + cron_tab_generator: + show: Show cron tab the generator + hide: Hide cron tab the generator + choose: Choose + every_minute: Every minute + every_hour: Every hour + every_day: Every day + every_month: Every month + every_weekday: Every weekdays + minutes: Minutes + hours: Hours + days: Days + months: Months + weekdays: weekdays + + projects: + add: Add + edit: Edit + list: List + list_header: Projects + edit_header: Edit the project + show: Project + build: Build + new_build: New build %{project_name} + confirm_delete: Are you sure to delete this project? + new: New project + new_header: New project + new_header: New project + location: Location + git_repo_location: Path to git repo + current_project_header: Current project + current_build_lists: Current builds + build_button: Start build + add_collaborators: Add collaborators + members: Members + collaborators: Collaborators + groups: Groups + edit_collaborators: Edit collaborators + issues: Issues + + collaborators: + back_to_proj: Back to project + edit: Edit list + add: Add/Remove + list: List + edit_roles: Edit roles + roles_header: Roles to + add_role: Add/Remove a role + input_username: Enter an username + input_groupname: Enter a groupname + + members: + back_to_group: Back to group + edit: Edit list + roles: Roles + add_member: Add member + input_username: Username + + groups: + list: List + new: Create + edit: Edit + members: Members + new_header: New group + edit_header: Edit + list_header: Groups + show: Group + back_to_the_list: ⇐ List of groups + confirm_delete: Are you sure to remove this group? + edit_members: Edit members + + users: + list: List + new: Create + edit: Edit + new_header: New user + edit_header: Edit + list_header: Users + groups: Groups + show: User + back_to_the_list: ⇐ List of users + confirm_delete: Are you sure to remove this user? + own_projects: My projects + part_projects: Participate projects + filter_header: Filter + + git: + repositories: + empty: Empty repository + source: Source + commits: Commits + commit_diff_too_big: Sorry, commit too big! + tags: Tags + branches: Branches + project_versions: Versions + + product_build_lists: + statuses: + '0': 'build' + '1': 'build error' + '2': 'build in progress' + + build_lists: + filter_header: Filter + current: Curent + created_at_start: "Build start from:" + created_at_end: "Build start to:" + notified_at_start: "Last update time by BS from:" + notified_at_end: " Last update time by BS to:" + bs_id_search: 'Id search' + project_name_search: Project name search + bs_id_not_set: Id isn’t set + items_header: Build items + no_items_data: No data + show: Show + cancel_button_header: Action + cancel_button: Cancel + cancel_success: 'Build canceled' + cancel_fail: 'Errors on build cancelling!' + publish_success: 'Build on publish queue' + publish_fail: 'Errors on publish queue!' + container_published: 'Container in a repository' + + build_server_status: + header: Build server status + client_count: Clients count + count_new_task: New task count + count_build_task: Build task count + + items: + statuses: + build_started: Build started + build_error: Build error + dependencies_error: Dependences not found + success: Build complete + unknown: Build waiting + + statuses: + build_error: Build error + build_published: Build published + build_publish: Build publishing + failed_publish: Publishing error + dependencies_fail: Dependences not found + waiting_for_response: Waiting for response + build_pending: Build pending + dependency_test_failed: Dependency test failed + binary_test_failed: Binary test failed + build_canceled: Build canceled + success: Build complete + build_started: Build started + platform_not_found: Platform not found + platform_pending: Platforn pending + project_not_found: Project not found + project_version_not_found: Project version not found + + flash: + settings: + saved: Settings saved success + save_error: Setting update error + + + subscribe: + saved: Subscription on notifications for this task is created + destroyed: Subscription on notifications for this task is cleaned + + exception_message: Access violation to this page! + + downloads: + statistics_refreshed: Statistics refreshed + + collaborators: + successfully_changed: Collaborators list successfully changed + error_in_changing: Collaborators list changing error + member_already_added: Member %s already added + group_already_added: Group already added + successfully_added: Member %s successfully added + error_in_adding: Member %s adding error + + members: + successfully_changed: Members list successfully changed + error_in_changing: Members list changing error + successfully_added: Member successfully added + error_in_adding: Member adding error + already_added: User already added + + auto_build_list: + success: Automated build success! + failed: Automated build failed! + cancel: Automated build canceled! + cancel_failed: Automated build canceling failed! + + category: + saved: Category saved + save_error: Category saves error + destroyed: Category deleted + + comment: + saved: Comment saved + save_error: Comment saves error + destroyed: Comment deleted + + issue: + saved: Task saved + save_error: Task saves error + destroyed: Task deleted + + project: + saved: Project saved + save_error: Project saves error + save_warning_ssh_key: Owner of the project must specify in profile a SSH key + destroyed: Project deleted + forked: Project forked + fork_error: Project fork error + + user: + saved: User saved + save_error: User data saves error + destroyed: User account deleted + + group: + saved: Group saved + save_error: Group saves error + destroyed: Group deleted + user_uname_exists: User already exists + + repository: + saved: Repository added + save_error: Repository adding error + destroyed: Repository deleted + project_added: Project added on repository + project_not_added: Project adding error. In this repository already is a project with such name. First remove the old project + project_removed: Project deleted + project_not_removed: Project deleting failed + + product: + saved: Product saved + save_error: Product saves error + build_started: Product build started + destroyed: Product deleted + + platform: + saved: Platform saved + save_error: Platform saves error + freezed: Platform freezed + freeze_error: Platform freezing error, try again + unfreezed: Platform unfreezed + unfreeze_error: Platform unfreezing error, try again + destroyed: Platform deleted + build_all_success: All project build in progress + + build_list: + saved: Project version '%{project_version}' build list, platform '%{bpl}', architecture '%{arch}' creation success + save_error: Project version '%{project_version}' build list, platform '%{bpl}', architecture '%{arch}' creation error + no_project_version_selected: Select any version of project + no_project_version_found: Project version '%{project_version}' not found + no_arch_or_platform_selected: At least one of architecture of platform must selected + wrong_platform: For the main repository its mail platform can be chosen only! + can_not_published: Build publishing with status "Build" available only + + attributes: + password: Password + password_confirmation: Confirmation + remember_me: Remember + name: Name + parent_platform_id: Parent platform + build_list: Build list + + activerecord: + models: + category: Category + repository: Repository + arch: Arch + container: Container + platform: Platform + group: Group + event_log: Event log + project: Project + rpm: RPM + user: User + private_user: Private user + product: Product + product_build_list: Product build list + build_list: Build list + build_list_item: Build list item + download: Statistics + auto_build_list: Auto rebuild list + settings: + notifier: Notifies setting + + attributes: + settings: + notifier: + can_notify: Notifications by e-mail + new_comment: New task comment notifications + new_comment_reply: New reply of comment notifications + new_issue: New task notifications + issue_assign: New task assignment notifications + + auto_build_list: + project_id: Project + project: Project + bpl_id: Repository for saving + bpl: Repository for saving + pl_id: Platform + pl: Platform + arch_id: Architecture + arch: Architecture + + comment: + body: Content + user: Author + + issue: + title: Title + body: Content + user: Assigned + user_id: Assigned + project: Project + status: Status + + private_user: + login: Login + password: Password + + category: + parent_id: Parent + name: Name + + repository: + name: Name + description: Description + platform_id: Platform + platform: Platform + created_at: Created + updated_at: Updated + owner: Owner + + product: + name: Name + platform_id: Platform + build_status: Build status + build_path: ISO path + created_at: Created + updated_at: Updated + ks: Content .ks.template + counter: Content .counter + build_script: Content build + menu: Content .menu.xml + tar: Tar.bz2 file + is_template: Template + system_wide: System + cron_tab: Cront tab + use_cron: Cron usage + + arch: + name: Name + created_at: Created + updated_at: Updated + + container: + name: Name + project_id: Project + project: Project + owner_id: Owner + owner: Owner + created_at: Created + updated_at: Updated + + platform: + name: Name + description: Description + parent_platform_id: Parent platform + parent: Parent platform + released: Released + created_at: Created + updated_at: Updated + distrib_type: Source type + visibility: Status + visibility_types: + open: Open + hidden: Hidden + + event_log: + kind: Event type + created_at: Event date and time + user: User + ip: User IP + protocol: Access protocol + description: Description + + project: + category_id: Category + name: Name + description: Descripton + owner: Owner + visibility: Visibility + repository_id: Repository + repository: Repository + created_at: Created + updated_at: Updated + has_issues: Tracker on + + rpm: + name: Name + arch_id: Arch + arch: Arch + project_id: Project + project: Project + created_at: Created + updated_at: Updated + + role: + name: Name + on: Slave + to:Master + use_default: By default + use_default_for_owner: Default by owner + + group: + name: Name + uname: Nickname + owner: Owner + created_at: Created + updated_at: Updated + + user: + name: User + login: Nickname or Email + email: Email + uname: Nickname + ssh_key: SSH key + current_password: Current password + role:Role + created_at: Created + updated_at: Updated + role: System role + + product_build_list: + id: Id + product: Product + status: Status + notified_at: Notified at + + build_list: + bs_id: Id + name: Name + container_path: Container path + status: Status + project_id: Project + project: Project + arch_id: Architecture + arch: Architecture + is_circle: Recurrent + notified_at: Notified at + additional_repos: Additional repository + include_repos: Includes repository + updated_at: Updated + created_at: Created + pl: Packet list repository + pl_id: Packet list repository + bpl: Platform + bpl_id: Platform + update_type: Update type + build_requires: Dependable build requires + auto_publish: Automated publising + project_version: Version + user: User + + build_list/item: + name: Name + level: Level + status: Status + version: Version + build_list: Build list + download: + name: Name + version: Version + distro: Source + platform: Platform + counter: Downloads + notifications: + subjects: + new_comment_notification: New comment to your task + new_issue_notification: New task added to project + new_user_notification: Registered on project «%{ project_name }» + issue_assign_notification: New task assigned + From 3994abd6ed0eba47962bc8f84460c07e320b54af Mon Sep 17 00:00:00 2001 From: Alexander Machehin Date: Thu, 19 Jan 2012 15:53:19 +0600 Subject: [PATCH 38/67] [refs #105] fix --- config/locales/en.yml | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/config/locales/en.yml b/config/locales/en.yml index 989f93873..c5b21b795 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -1,15 +1,15 @@ en: will_paginate: previous_label: ‹ Previous - next_label: Next › + next_label: Next › page_gap: ... - + datatables: previous_label: ‹ Prev. - next_label: Next › + next_label: Next › first_label: « First last_label: Last » - empty_label: No data accessible + empty_label: No data accessible info_label: Records displayed from _START_ to _END_ total _TOTAL_ info_empty_label: Records displayed from 0 to 0 total 0 filtered_label: (filtered of _MAX_) @@ -50,7 +50,7 @@ title: Downloads statistic message: Automatically updated every 5 minutes refresh_btn: Refresh - + auto_build_lists: header: Automated build projects message: All projects build under user repository and architecture i586 @@ -62,7 +62,7 @@ already_automated: Automated weekdays: - Monday: Monday + Monday: Monday Tuesday: Tuesday Wednesday: Wednesday Thursday: Thursday @@ -117,9 +117,9 @@ confirm_delete: Are you sure to delete this task? edit_header: Task edit new_header: New task - open: Opened - closed: Closed - any: Any + open: Opened + closed: Closed + any: Any subscribe: Subscribe subscribe_btn: Subscribe unsubscribe_btn: Unsubscribe @@ -179,7 +179,7 @@ back_to_the_list: ⇐ List of repositories confirm_delete: Are you sure to delete this repository? current_repository_header: Current repository - + personal_repositories: settings_header: Settings change_visibility_from_hidden: Replace the status to "Opened" @@ -190,7 +190,7 @@ products: list: List - new:New product + new: New product list_header: Products clone: Clone build: Build @@ -207,7 +207,7 @@ every_hour: Every hour every_day: Every day every_month: Every month - every_weekday: Every weekdays + every_weekday: Every weekdays minutes: Minutes hours: Hours days: Days @@ -309,7 +309,7 @@ notified_at_start: "Last update time by BS from:" notified_at_end: " Last update time by BS to:" bs_id_search: 'Id search' - project_name_search: Project name search + project_name_search: Project name search bs_id_not_set: Id isn’t set items_header: Build items no_items_data: No data @@ -321,13 +321,13 @@ publish_success: 'Build on publish queue' publish_fail: 'Errors on publish queue!' container_published: 'Container in a repository' - + build_server_status: header: Build server status client_count: Clients count count_new_task: New task count count_build_task: Build task count - + items: statuses: build_started: Build started @@ -358,7 +358,7 @@ settings: saved: Settings saved success save_error: Setting update error - + subscribe: saved: Subscription on notifications for this task is created @@ -613,7 +613,7 @@ role: name: Name on: Slave - to:Master + to: Master use_default: By default use_default_for_owner: Default by owner @@ -631,7 +631,7 @@ uname: Nickname ssh_key: SSH key current_password: Current password - role:Role + role: Role created_at: Created updated_at: Updated role: System role From 5a6f5b51c0ae835ee37ab141dcf4c44778470cb5 Mon Sep 17 00:00:00 2001 From: Vladimir Sharshov Date: Thu, 19 Jan 2012 20:20:30 +0400 Subject: [PATCH 39/67] Upgrade capistrano receipts: * add application env files; * remove unused ui deploy; * clear main deploy config. --- config/deploy.rb | 23 ++++++++++++----------- config/deploy/application.production.yml | 15 +++++++++++++++ config/deploy/application.staging.yml | 15 +++++++++++++++ config/deploy/ui.rb | 15 --------------- 4 files changed, 42 insertions(+), 26 deletions(-) create mode 100644 config/deploy/application.production.yml create mode 100644 config/deploy/application.staging.yml delete mode 100644 config/deploy/ui.rb diff --git a/config/deploy.rb b/config/deploy.rb index d8234e321..6d965c667 100644 --- a/config/deploy.rb +++ b/config/deploy.rb @@ -1,15 +1,17 @@ $:.unshift(File.expand_path('./lib', ENV['rvm_path'])) set :rvm_type, :user + require 'rvm/capistrano' require 'bundler/capistrano' require 'delayed/recipes' require 'airbrake/capistrano' + set :whenever_command, "bundle exec whenever" # require "whenever/capistrano" -set :default_stage, "staging" -# set :stages, %w(production staging pingwinsoft ui) # auto readed require 'capistrano/ext/multistage' +set :default_stage, "staging" +# set :stages, %w(production staging pingwinsoft) # auto readed # main details ssh_options[:forward_agent] = true @@ -21,19 +23,14 @@ set :user, "rosa" set :use_sudo, false set :keep_releases, 3 +set :scm, :git set :repository, "git@github.com:warpc/rosa-build.git" -# set :git_shallow_clone, 1 -set :scm, "git" -# set :deploy_via, :copy -# set :copy_cache, true +set :deploy_via, :remote_cache require 'lib/recipes/nginx' require 'lib/recipes/unicorn' require 'lib/recipes/bluepill' namespace :deploy do - # task :restart, :roles => :app, :except => { :no_release => true } do - # run "touch #{current_release}/tmp/restart.txt" - # end task :stub_xml_rpc do path = File.join(release_path, 'config', 'environment.rb') @@ -44,11 +41,16 @@ namespace :deploy do task :symlink_all, :roles => :web do run "mkdir -p #{fetch :shared_path}/config" + + # Setup DB run "cp -n #{fetch :release_path}/config/database.yml.sample #{fetch :shared_path}/config/database.yml" - run "cp -n #{fetch :release_path}/config/application.yml.sample #{fetch :shared_path}/config/application.yml" run "ln -nfs #{fetch :shared_path}/config/database.yml #{fetch :release_path}/config/database.yml" + + # Setup application + run "cp -n #{fetch :release_path}/config/deploy/application.#{fetch :stage}.yml #{fetch :shared_path}/config/application.yml" run "ln -nfs #{fetch :shared_path}/config/application.yml #{fetch :release_path}/config/application.yml" + # It will survive downloads folder between deployments run "mkdir -p #{fetch :shared_path}/downloads" run "ln -nfs #{fetch :shared_path}/downloads/ #{fetch :release_path}/public/downloads" end @@ -60,7 +62,6 @@ after "deploy:restart", "delayed_job:restart", "bluepill:restart", "deploy:clean require 'cape' namespace :rake_tasks do Cape do - # mirror_rake_tasks mirror_rake_tasks 'db:seeds' end end diff --git a/config/deploy/application.production.yml b/config/deploy/application.production.yml new file mode 100644 index 000000000..450faf330 --- /dev/null +++ b/config/deploy/application.production.yml @@ -0,0 +1,15 @@ +production: + root_path: /share + nginx_log: /srv/rosa_build/shared/log/nginx.access.log + do-not-reply-email: do-not-reply@rosalab.ru + project_name: ABF + repo_project_name: ABF + build_server_ip: 127.0.0.1 + build_server_port: 12555 + build_server_path: /xmlrpc + product_builder_ip: + mdv: 192.168.122.19 + nau5: 192.168.122.203 + product_builder_port: 12554 + product_builder_path: /xmlrpc + distr_types: ['mdv'] \ No newline at end of file diff --git a/config/deploy/application.staging.yml b/config/deploy/application.staging.yml new file mode 100644 index 000000000..6e9ae1cac --- /dev/null +++ b/config/deploy/application.staging.yml @@ -0,0 +1,15 @@ +production: + root_path: /share + nginx_log: /srv/rosa_build/shared/log/nginx.access.log + do-not-reply-email: do-not-reply@rosalab.ru + project_name: ABF + repo_project_name: ABF + build_server_ip: 127.0.0.1 + build_server_port: 12555 + build_server_path: /xmlrpc + product_builder_ip: + mdv: 192.168.122.19 + nau5: 192.168.122.203 + product_builder_port: 12554 + product_builder_path: /xmlrpc + distr_types: ['mdv', 'nau5'] diff --git a/config/deploy/ui.rb b/config/deploy/ui.rb deleted file mode 100644 index 824b9075b..000000000 --- a/config/deploy/ui.rb +++ /dev/null @@ -1,15 +0,0 @@ -set :branch, "ui" - -set :domain, "abf.warpc.ru" # "195.19.76.12" -set :port, 1822 - -role :app, domain -role :web, domain -role :db, domain, :primary => true - -set :application, "rosa_build_#{stage}" -set :deploy_to, "/srv/#{application}" - -# set :unicorn_port, 8082 - -before "deploy:restart", "deploy:stub_xml_rpc" From b5f0124f91c79e27964780d091a4f8a2d65ec57f Mon Sep 17 00:00:00 2001 From: Pavel Chipiga Date: Thu, 19 Jan 2012 21:07:47 +0200 Subject: [PATCH 40/67] Add pids symlink generation task. Refs #110 --- config/deploy.rb | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/config/deploy.rb b/config/deploy.rb index 6d965c667..76df1cd51 100644 --- a/config/deploy.rb +++ b/config/deploy.rb @@ -30,8 +30,8 @@ set :deploy_via, :remote_cache require 'lib/recipes/nginx' require 'lib/recipes/unicorn' require 'lib/recipes/bluepill' -namespace :deploy do +namespace :deploy do task :stub_xml_rpc do path = File.join(release_path, 'config', 'environment.rb') code = %Q{\nrequire 'stub_xml_rpc'\n} @@ -39,7 +39,7 @@ namespace :deploy do run %Q{echo "#{code}" >> #{path}} end - task :symlink_all, :roles => :web do + task :symlink_all, :roles => :app do run "mkdir -p #{fetch :shared_path}/config" # Setup DB @@ -54,10 +54,15 @@ namespace :deploy do run "mkdir -p #{fetch :shared_path}/downloads" run "ln -nfs #{fetch :shared_path}/downloads/ #{fetch :release_path}/public/downloads" end + + task :symlink_pids, :roles => :app do + run "cd #{fetch :shared_path}/tmp && ln -nfs ../pids pids" + end end after "deploy:update_code", "deploy:symlink_all", "deploy:migrate" after "deploy:restart", "delayed_job:restart", "bluepill:restart", "deploy:cleanup" +after "deploy:setup", "deploy:symlink_pids" require 'cape' namespace :rake_tasks do From a5c2bcdd85084fe8ce38e1e42335f087156fa73d Mon Sep 17 00:00:00 2001 From: Vladimir Sharshov Date: Fri, 20 Jan 2012 00:06:09 +0400 Subject: [PATCH 41/67] Fix email host address --- config/environments/production.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/environments/production.rb b/config/environments/production.rb index f29b78fce..0d9247b3a 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -36,7 +36,7 @@ Rosa::Application.configure do # Disable delivery errors, bad email addresses will be ignored # config.action_mailer.raise_delivery_errors = false - config.action_mailer.default_url_options = { :host => 'npp-build.rosalab.ru' } + config.action_mailer.default_url_options = { :host => 'rosa-build.rosalab.ru' } # Enable threaded mode # config.threadsafe! From 3206258f7b764a35474cdaeafcb6965a4ae1d2cf Mon Sep 17 00:00:00 2001 From: Vladimir Sharshov Date: Fri, 20 Jan 2012 00:06:43 +0400 Subject: [PATCH 42/67] Change default locale to English --- config/application.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/application.rb b/config/application.rb index 090e206c5..901d86784 100644 --- a/config/application.rb +++ b/config/application.rb @@ -32,7 +32,7 @@ module Rosa # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded. # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s] - config.i18n.default_locale = :ru + config.i18n.default_locale = :en config.action_view.javascript_expansions[:defaults] = %w() From 25bd2cd13d7f606d355b00d23e1c382ba0d4450c Mon Sep 17 00:00:00 2001 From: Vladimir Sharshov Date: Fri, 20 Jan 2012 00:33:28 +0400 Subject: [PATCH 43/67] Fix for localization files --- config/locales/en.yml | 12 +++++++++--- config/locales/ru.yml | 4 +++- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/config/locales/en.yml b/config/locales/en.yml index c5b21b795..34921f77a 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -98,6 +98,7 @@ confirm_regenerate: Are you sure to regenerate this pair login/password? regenerate_btn: Regenerate warning_message: Warning - Old data set as invalid when new data obtaining + categories: list: List new: Create @@ -117,9 +118,10 @@ confirm_delete: Are you sure to delete this task? edit_header: Task edit new_header: New task - open: Opened - closed: Closed - any: Any + statuses: + open: Opened + closed: Closed + any: Any subscribe: Subscribe subscribe_btn: Subscribe unsubscribe_btn: Unsubscribe @@ -127,6 +129,7 @@ comments: confirm_delete: Are you sure to delete the comment? new_header: New comment + edit_header: Editing a comment platforms: admin_id: Owner @@ -635,6 +638,7 @@ created_at: Created updated_at: Updated role: System role + language: Language product_build_list: id: Id @@ -673,12 +677,14 @@ status: Status version: Version build_list: Build list + download: name: Name version: Version distro: Source platform: Platform counter: Downloads + notifications: subjects: new_comment_notification: New comment to your task diff --git a/config/locales/ru.yml b/config/locales/ru.yml index 9086b8375..a6c7c7229 100644 --- a/config/locales/ru.yml +++ b/config/locales/ru.yml @@ -355,7 +355,7 @@ ru: platform_not_found: платформа не найдена platform_pending: платформа в процессе создания project_not_found: проект не найден - project_version_not_found: версия не найден + project_version_not_found: версия не найдена flash: settings: @@ -677,12 +677,14 @@ ru: status: Статус version: Версия build_list: Сборочный лист + download: name: Название version: Версия distro: Дистрибутив platform: Архитектура counter: Закачки + notifications: subjects: new_comment_notification: Новый комментарий к Вашей задаче From 59c7faf5c159fbc15b38391d56d7a74b1173e4a1 Mon Sep 17 00:00:00 2001 From: Vladimir Sharshov Date: Fri, 20 Jan 2012 02:07:42 +0400 Subject: [PATCH 44/67] Fix localization file (here was dragons!) --- config/locales/en.yml | 1387 ++++++++++++++++++++--------------------- 1 file changed, 693 insertions(+), 694 deletions(-) diff --git a/config/locales/en.yml b/config/locales/en.yml index 34921f77a..4fa4edbc8 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -1,694 +1,693 @@ -en: - will_paginate: - previous_label: ‹ Previous - next_label: Next › - page_gap: ... - - datatables: - previous_label: ‹ Prev. - next_label: Next › - first_label: « First - last_label: Last » - empty_label: No data accessible - info_label: Records displayed from _START_ to _END_ total _TOTAL_ - info_empty_label: Records displayed from 0 to 0 total 0 - filtered_label: (filtered of _MAX_) - - layout: - logged_in_as: You logged as - logout: Logout - user_list: User list - edit: Edit - show: View - cancel: Cancel - create: Create - delete: Erase - save: Save - search: Search - clone: Clone - search_by_name: Filter by name - are_you_sure: "Sure?" - login: Login - or: or - yes_: Yes - no_: No - true_: True - false_: False - publish: Publish - add: Add - upload: Upload - not_access: Access denied! - owner: Owner - confirm: Sure? - settings: - notifier: Notifier setting - notifiers: - edit_header: Notifier setting - processing: working ... - - downloads: - title: Downloads statistic - message: Automatically updated every 5 minutes - refresh_btn: Refresh - - auto_build_lists: - header: Automated build projects - message: All projects build under user repository and architecture i586 - project: Project - action: Action - automate_btn: Automate - cancel_btn: Cancel - not_automated: Not automated - already_automated: Automated - - weekdays: - Monday: Monday - Tuesday: Tuesday - Wednesday: Wednesday - Thursday: Thursday - Friday: Friday - Saturday: Saturday - Sunday: Sunday - - menu: - categories: Catalogue - containers: Containers - downloads: Statistics - event_logs: Event log - build_lists: Task monitoring - groups: Groups - platforms: Platforms - products: Products - projects: Projects - repositories: Repositories - rights: Rights - roles: Roles - users: Users - personal_repository: My repository - auto_build_lists: Automated build - - sessions: - sign_in_header: Sign in - - private_users: - list: List - new: New pair - list_header: Pair login/password - confirm_delete: Are you sure to delete this pair login/password? - confirm_regenerate: Are you sure to regenerate this pair login/password? - regenerate_btn: Regenerate - warning_message: Warning - Old data set as invalid when new data obtaining - - categories: - list: List - new: Create - edit: Edit - platforms: By platform - list_header: Catalogue - new_header: New category - edit_header: Edit category - confirm_delete: Are you sure to delete this category? - - issues: - list: List - edit: Edit - comments_header: Comments - new: New task - list_header: List - confirm_delete: Are you sure to delete this task? - edit_header: Task edit - new_header: New task - statuses: - open: Opened - closed: Closed - any: Any - subscribe: Subscribe - subscribe_btn: Subscribe - unsubscribe_btn: Unsubscribe - - comments: - confirm_delete: Are you sure to delete the comment? - new_header: New comment - edit_header: Editing a comment - - platforms: - admin_id: Owner - build_all: Build all - list: List - new: Create - edit: Edit - new_header: New platform - edit_header: Edit - list_header: Platforms - list_header_main: General - list_header_personal: Personal - list_header_all: All - clone_header: Platform clone - show: Platform - projects: Projects - products: Products - location: Location - repositories: Repositories - back_to_the_list: ⇐To platform list - freeze: Freeze - unfreeze: Unfeeze - confirm_freeze: Are you sure to freeze this platform? - confirm_freeze: Are you sure to clone this platform? - confirm_unfreeze: Are you sure to defrost this platform? - released_suffix: (released) - confirm_delete: Are you sure to delete this platform? - current_platform_header: Current platform - owner: Owner - visibility: Visibility - platform_type: Platform type - distrib_type: Distribution kit type - private_users: Access data - confirm_clone: To clone? - clone: To clone - - event_logs: - list:List - list_header: Event log - - repositories: - list: List - list_header: Repositories - new: New repository - new_header: New repository - show: Repository - location: Location - projects: Projects - new_header: New repository - back_to_the_list: ⇐ List of repositories - confirm_delete: Are you sure to delete this repository? - current_repository_header: Current repository - - personal_repositories: - settings_header: Settings - change_visibility_from_hidden: Replace the status to "Opened" - change_visibility_from_open: Replace the status to "Private" - settings: Settings - show: My repository - private_users: Private repository users - - products: - list: List - new: New product - list_header: Products - clone: Clone - build: Build - new_header: New product - edit_header: Product editing - confirm_delete: Are you sure to delete this product? - invalid_content_type: incorrect type - - cron_tab_generator: - show: Show cron tab the generator - hide: Hide cron tab the generator - choose: Choose - every_minute: Every minute - every_hour: Every hour - every_day: Every day - every_month: Every month - every_weekday: Every weekdays - minutes: Minutes - hours: Hours - days: Days - months: Months - weekdays: weekdays - - projects: - add: Add - edit: Edit - list: List - list_header: Projects - edit_header: Edit the project - show: Project - build: Build - new_build: New build %{project_name} - confirm_delete: Are you sure to delete this project? - new: New project - new_header: New project - new_header: New project - location: Location - git_repo_location: Path to git repo - current_project_header: Current project - current_build_lists: Current builds - build_button: Start build - add_collaborators: Add collaborators - members: Members - collaborators: Collaborators - groups: Groups - edit_collaborators: Edit collaborators - issues: Issues - - collaborators: - back_to_proj: Back to project - edit: Edit list - add: Add/Remove - list: List - edit_roles: Edit roles - roles_header: Roles to - add_role: Add/Remove a role - input_username: Enter an username - input_groupname: Enter a groupname - - members: - back_to_group: Back to group - edit: Edit list - roles: Roles - add_member: Add member - input_username: Username - - groups: - list: List - new: Create - edit: Edit - members: Members - new_header: New group - edit_header: Edit - list_header: Groups - show: Group - back_to_the_list: ⇐ List of groups - confirm_delete: Are you sure to remove this group? - edit_members: Edit members - - users: - list: List - new: Create - edit: Edit - new_header: New user - edit_header: Edit - list_header: Users - groups: Groups - show: User - back_to_the_list: ⇐ List of users - confirm_delete: Are you sure to remove this user? - own_projects: My projects - part_projects: Participate projects - filter_header: Filter - - git: - repositories: - empty: Empty repository - source: Source - commits: Commits - commit_diff_too_big: Sorry, commit too big! - tags: Tags - branches: Branches - project_versions: Versions - - product_build_lists: - statuses: - '0': 'build' - '1': 'build error' - '2': 'build in progress' - - build_lists: - filter_header: Filter - current: Curent - created_at_start: "Build start from:" - created_at_end: "Build start to:" - notified_at_start: "Last update time by BS from:" - notified_at_end: " Last update time by BS to:" - bs_id_search: 'Id search' - project_name_search: Project name search - bs_id_not_set: Id isn’t set - items_header: Build items - no_items_data: No data - show: Show - cancel_button_header: Action - cancel_button: Cancel - cancel_success: 'Build canceled' - cancel_fail: 'Errors on build cancelling!' - publish_success: 'Build on publish queue' - publish_fail: 'Errors on publish queue!' - container_published: 'Container in a repository' - - build_server_status: - header: Build server status - client_count: Clients count - count_new_task: New task count - count_build_task: Build task count - - items: - statuses: - build_started: Build started - build_error: Build error - dependencies_error: Dependences not found - success: Build complete - unknown: Build waiting - - statuses: - build_error: Build error - build_published: Build published - build_publish: Build publishing - failed_publish: Publishing error - dependencies_fail: Dependences not found - waiting_for_response: Waiting for response - build_pending: Build pending - dependency_test_failed: Dependency test failed - binary_test_failed: Binary test failed - build_canceled: Build canceled - success: Build complete - build_started: Build started - platform_not_found: Platform not found - platform_pending: Platforn pending - project_not_found: Project not found - project_version_not_found: Project version not found - - flash: - settings: - saved: Settings saved success - save_error: Setting update error - - - subscribe: - saved: Subscription on notifications for this task is created - destroyed: Subscription on notifications for this task is cleaned - - exception_message: Access violation to this page! - - downloads: - statistics_refreshed: Statistics refreshed - - collaborators: - successfully_changed: Collaborators list successfully changed - error_in_changing: Collaborators list changing error - member_already_added: Member %s already added - group_already_added: Group already added - successfully_added: Member %s successfully added - error_in_adding: Member %s adding error - - members: - successfully_changed: Members list successfully changed - error_in_changing: Members list changing error - successfully_added: Member successfully added - error_in_adding: Member adding error - already_added: User already added - - auto_build_list: - success: Automated build success! - failed: Automated build failed! - cancel: Automated build canceled! - cancel_failed: Automated build canceling failed! - - category: - saved: Category saved - save_error: Category saves error - destroyed: Category deleted - - comment: - saved: Comment saved - save_error: Comment saves error - destroyed: Comment deleted - - issue: - saved: Task saved - save_error: Task saves error - destroyed: Task deleted - - project: - saved: Project saved - save_error: Project saves error - save_warning_ssh_key: Owner of the project must specify in profile a SSH key - destroyed: Project deleted - forked: Project forked - fork_error: Project fork error - - user: - saved: User saved - save_error: User data saves error - destroyed: User account deleted - - group: - saved: Group saved - save_error: Group saves error - destroyed: Group deleted - user_uname_exists: User already exists - - repository: - saved: Repository added - save_error: Repository adding error - destroyed: Repository deleted - project_added: Project added on repository - project_not_added: Project adding error. In this repository already is a project with such name. First remove the old project - project_removed: Project deleted - project_not_removed: Project deleting failed - - product: - saved: Product saved - save_error: Product saves error - build_started: Product build started - destroyed: Product deleted - - platform: - saved: Platform saved - save_error: Platform saves error - freezed: Platform freezed - freeze_error: Platform freezing error, try again - unfreezed: Platform unfreezed - unfreeze_error: Platform unfreezing error, try again - destroyed: Platform deleted - build_all_success: All project build in progress - - build_list: - saved: Project version '%{project_version}' build list, platform '%{bpl}', architecture '%{arch}' creation success - save_error: Project version '%{project_version}' build list, platform '%{bpl}', architecture '%{arch}' creation error - no_project_version_selected: Select any version of project - no_project_version_found: Project version '%{project_version}' not found - no_arch_or_platform_selected: At least one of architecture of platform must selected - wrong_platform: For the main repository its mail platform can be chosen only! - can_not_published: Build publishing with status "Build" available only - - attributes: - password: Password - password_confirmation: Confirmation - remember_me: Remember - name: Name - parent_platform_id: Parent platform - build_list: Build list - - activerecord: - models: - category: Category - repository: Repository - arch: Arch - container: Container - platform: Platform - group: Group - event_log: Event log - project: Project - rpm: RPM - user: User - private_user: Private user - product: Product - product_build_list: Product build list - build_list: Build list - build_list_item: Build list item - download: Statistics - auto_build_list: Auto rebuild list - settings: - notifier: Notifies setting - - attributes: - settings: - notifier: - can_notify: Notifications by e-mail - new_comment: New task comment notifications - new_comment_reply: New reply of comment notifications - new_issue: New task notifications - issue_assign: New task assignment notifications - - auto_build_list: - project_id: Project - project: Project - bpl_id: Repository for saving - bpl: Repository for saving - pl_id: Platform - pl: Platform - arch_id: Architecture - arch: Architecture - - comment: - body: Content - user: Author - - issue: - title: Title - body: Content - user: Assigned - user_id: Assigned - project: Project - status: Status - - private_user: - login: Login - password: Password - - category: - parent_id: Parent - name: Name - - repository: - name: Name - description: Description - platform_id: Platform - platform: Platform - created_at: Created - updated_at: Updated - owner: Owner - - product: - name: Name - platform_id: Platform - build_status: Build status - build_path: ISO path - created_at: Created - updated_at: Updated - ks: Content .ks.template - counter: Content .counter - build_script: Content build - menu: Content .menu.xml - tar: Tar.bz2 file - is_template: Template - system_wide: System - cron_tab: Cront tab - use_cron: Cron usage - - arch: - name: Name - created_at: Created - updated_at: Updated - - container: - name: Name - project_id: Project - project: Project - owner_id: Owner - owner: Owner - created_at: Created - updated_at: Updated - - platform: - name: Name - description: Description - parent_platform_id: Parent platform - parent: Parent platform - released: Released - created_at: Created - updated_at: Updated - distrib_type: Source type - visibility: Status - visibility_types: - open: Open - hidden: Hidden - - event_log: - kind: Event type - created_at: Event date and time - user: User - ip: User IP - protocol: Access protocol - description: Description - - project: - category_id: Category - name: Name - description: Descripton - owner: Owner - visibility: Visibility - repository_id: Repository - repository: Repository - created_at: Created - updated_at: Updated - has_issues: Tracker on - - rpm: - name: Name - arch_id: Arch - arch: Arch - project_id: Project - project: Project - created_at: Created - updated_at: Updated - - role: - name: Name - on: Slave - to: Master - use_default: By default - use_default_for_owner: Default by owner - - group: - name: Name - uname: Nickname - owner: Owner - created_at: Created - updated_at: Updated - - user: - name: User - login: Nickname or Email - email: Email - uname: Nickname - ssh_key: SSH key - current_password: Current password - role: Role - created_at: Created - updated_at: Updated - role: System role - language: Language - - product_build_list: - id: Id - product: Product - status: Status - notified_at: Notified at - - build_list: - bs_id: Id - name: Name - container_path: Container path - status: Status - project_id: Project - project: Project - arch_id: Architecture - arch: Architecture - is_circle: Recurrent - notified_at: Notified at - additional_repos: Additional repository - include_repos: Includes repository - updated_at: Updated - created_at: Created - pl: Packet list repository - pl_id: Packet list repository - bpl: Platform - bpl_id: Platform - update_type: Update type - build_requires: Dependable build requires - auto_publish: Automated publising - project_version: Version - user: User - - build_list/item: - name: Name - level: Level - status: Status - version: Version - build_list: Build list - - download: - name: Name - version: Version - distro: Source - platform: Platform - counter: Downloads - - notifications: - subjects: - new_comment_notification: New comment to your task - new_issue_notification: New task added to project - new_user_notification: Registered on project «%{ project_name }» - issue_assign_notification: New task assigned - +en: + will_paginate: + previous_label: ‹ Previous!!! + next_label: Next › + page_gap: ... + + datatables: + previous_label: ‹ Prev. + next_label: Next ›b r + first_label: « First + last_label: Last » + empty_label: No data accessible + info_label: Records displayed from _START_ to _END_ total _TOTAL_ + info_empty_label: Records displayed from 0 to 0 total 0 + filtered_label: (filtered of _MAX_) + + layout: + logged_in_as: You logged as + logout: Logout + user_list: User list + edit: Edit + show: View + cancel: Cancel + create: Create + delete: Erase + save: Save + search: Search + clone: Clone + search_by_name: Filter by name + are_you_sure: "Sure?" + login: Login + or: or + yes_: Yes + no_: No + true_: True + false_: False + publish: Publish + add: Add + upload: Upload + not_access: Access denied! + owner: Owner + confirm: Sure? + settings: + notifier: Notifier setting + notifiers: + edit_header: Notifier setting + processing: working ... + + downloads: + title: Downloads statistic + message: Automatically updated every 5 minutes + refresh_btn: Refresh + + auto_build_lists: + header: Automated build projects + message: All projects build under user repository and architecture i586 + project: Project + action: Action + automate_btn: Automate + cancel_btn: Cancel + not_automated: Not automated + already_automated: Automated + + weekdays: + Monday: Monday + Tuesday: Tuesday + Wednesday: Wednesday + Thursday: Thursday + Friday: Friday + Saturday: Saturday + Sunday: Sunday + + menu: + categories: Catalogue + containers: Containers + downloads: Statistics + event_logs: Event log + build_lists: Task monitoring + groups: Groups + platforms: Platforms + products: Products + projects: Projects + repositories: Repositories + rights: Rights + roles: Roles + users: Users + personal_repository: My repository + auto_build_lists: Automated build + + sessions: + sign_in_header: Sign in + + private_users: + list: List + new: New pair + list_header: Pair login/password + confirm_delete: Are you sure to delete this pair login/password? + confirm_regenerate: Are you sure to regenerate this pair login/password? + regenerate_btn: Regenerate + warning_message: Warning - Old data set as invalid when new data obtaining + + categories: + list: List + new: Create + edit: Edit + platforms: By platform + list_header: Catalogue + new_header: New category + edit_header: Edit category + confirm_delete: Are you sure to delete this category? + + issues: + list: List + edit: Edit + comments_header: Comments + new: New task + list_header: List + confirm_delete: Are you sure to delete this task? + edit_header: Task edit + new_header: New task + statuses: + open: Opened + closed: Closed + any: Any + subscribe: Subscribe + subscribe_btn: Subscribe + unsubscribe_btn: Unsubscribe + + comments: + confirm_delete: Are you sure to delete the comment? + new_header: New comment + edit_header: Editing a comment + + platforms: + admin_id: Owner + build_all: Build all + list: List + new: Create + edit: Edit + new_header: New platform + edit_header: Edit + list_header: Platforms + list_header_main: General + list_header_personal: Personal + list_header_all: All + clone_header: Platform clone + show: Platform + projects: Projects + products: Products + location: Location + repositories: Repositories + back_to_the_list: ⇐To platform list + freeze: Freeze + unfreeze: Unfeeze + confirm_freeze: Are you sure to freeze this platform? + confirm_freeze: Are you sure to clone this platform? + confirm_unfreeze: Are you sure to defrost this platform? + released_suffix: (released) + confirm_delete: Are you sure to delete this platform? + current_platform_header: Current platform + owner: Owner + visibility: Visibility + platform_type: Platform type + distrib_type: Distribution kit type + private_users: Access data + confirm_clone: To clone? + clone: To clone + + event_logs: + list:List + list_header: Event log + + repositories: + list: List + list_header: Repositories + new: New repository + new_header: New repository + show: Repository + location: Location + projects: Projects + new_header: New repository + back_to_the_list: ⇐ List of repositories + confirm_delete: Are you sure to delete this repository? + current_repository_header: Current repository + + personal_repositories: + settings_header: Settings + change_visibility_from_hidden: Replace the status to "Opened" + change_visibility_from_open: Replace the status to "Private" + settings: Settings + show: My repository + private_users: Private repository users + + products: + list: List + new: New product + list_header: Products + clone: Clone + build: Build + new_header: New product + edit_header: Product editing + confirm_delete: Are you sure to delete this product? + invalid_content_type: incorrect type + + cron_tab_generator: + show: Show cron tab the generator + hide: Hide cron tab the generator + choose: Choose + every_minute: Every minute + every_hour: Every hour + every_day: Every day + every_month: Every month + every_weekday: Every weekdays + minutes: Minutes + hours: Hours + days: Days + months: Months + weekdays: weekdays + + projects: + add: Add + edit: Edit + list: List + list_header: Projects + edit_header: Edit the project + show: Project + build: Build + new_build: New build %{project_name} + confirm_delete: Are you sure to delete this project? + new: New project + new_header: New project + new_header: New project + location: Location + git_repo_location: Path to git repo + current_project_header: Current project + current_build_lists: Current builds + build_button: Start build + add_collaborators: Add collaborators + members: Members + collaborators: Collaborators + groups: Groups + edit_collaborators: Edit collaborators + issues: Issues + + collaborators: + back_to_proj: Back to project + edit: Edit list + add: Add/Remove + list: List + edit_roles: Edit roles + roles_header: Roles to + add_role: Add/Remove a role + input_username: Enter an username + input_groupname: Enter a groupname + + members: + back_to_group: Back to group + edit: Edit list + roles: Roles + add_member: Add member + input_username: Username + + groups: + list: List + new: Create + edit: Edit + members: Members + new_header: New group + edit_header: Edit + list_header: Groups + show: Group + back_to_the_list: ⇐ List of groups + confirm_delete: Are you sure to remove this group? + edit_members: Edit members + + users: + list: List + new: Create + edit: Edit + new_header: New user + edit_header: Edit + list_header: Users + groups: Groups + show: User + back_to_the_list: ⇐ List of users + confirm_delete: Are you sure to remove this user? + own_projects: My projects + part_projects: Participate projects + filter_header: Filter + + git: + repositories: + empty: Empty repository + source: Source + commits: Commits + commit_diff_too_big: Sorry, commit too big! + tags: Tags + branches: Branches + project_versions: Versions + + product_build_lists: + statuses: + '0': 'build' + '1': 'build error' + '2': 'build in progress' + + build_lists: + filter_header: Filter + current: Curent + created_at_start: "Build start from:" + created_at_end: "Build start to:" + notified_at_start: "Last update time by BS from:" + notified_at_end: " Last update time by BS to:" + bs_id_search: 'Id search' + project_name_search: Project name search + bs_id_not_set: Id isn’t set + items_header: Build items + no_items_data: No data + show: Show + cancel_button_header: Action + cancel_button: Cancel + cancel_success: 'Build canceled' + cancel_fail: 'Errors on build cancelling!' + publish_success: 'Build on publish queue' + publish_fail: 'Errors on publish queue!' + container_published: 'Container in a repository' + + build_server_status: + header: Build server status + client_count: Clients count + count_new_task: New task count + count_build_task: Build task count + + items: + statuses: + build_started: Build started + build_error: Build error + dependencies_error: Dependences not found + success: Build complete + unknown: Build waiting + + statuses: + build_error: Build error + build_published: Build published + build_publish: Build publishing + failed_publish: Publishing error + dependencies_fail: Dependences not found + waiting_for_response: Waiting for response + build_pending: Build pending + dependency_test_failed: Dependency test failed + binary_test_failed: Binary test failed + build_canceled: Build canceled + success: Build complete + build_started: Build started + platform_not_found: Platform not found + platform_pending: Platforn pending + project_not_found: Project not found + project_version_not_found: Project version not found + + flash: + settings: + saved: Settings saved success + save_error: Setting update error + + + subscribe: + saved: Subscription on notifications for this task is created + destroyed: Subscription on notifications for this task is cleaned + + exception_message: Access violation to this page! + + downloads: + statistics_refreshed: Statistics refreshed + + collaborators: + successfully_changed: Collaborators list successfully changed + error_in_changing: Collaborators list changing error + member_already_added: Member %s already added + group_already_added: Group already added + successfully_added: Member %s successfully added + error_in_adding: Member %s adding error + + members: + successfully_changed: Members list successfully changed + error_in_changing: Members list changing error + successfully_added: Member successfully added + error_in_adding: Member adding error + already_added: User already added + + auto_build_list: + success: Automated build success! + failed: Automated build failed! + cancel: Automated build canceled! + cancel_failed: Automated build canceling failed! + + category: + saved: Category saved + save_error: Category saves error + destroyed: Category deleted + + comment: + saved: Comment saved + save_error: Comment saves error + destroyed: Comment deleted + + issue: + saved: Task saved + save_error: Task saves error + destroyed: Task deleted + + project: + saved: Project saved + save_error: Project saves error + save_warning_ssh_key: Owner of the project must specify in profile a SSH key + destroyed: Project deleted + forked: Project forked + fork_error: Project fork error + + user: + saved: User saved + save_error: User data saves error + destroyed: User account deleted + + group: + saved: Group saved + save_error: Group saves error + destroyed: Group deleted + user_uname_exists: User already exists + + repository: + saved: Repository added + save_error: Repository adding error + destroyed: Repository deleted + project_added: Project added on repository + project_not_added: Project adding error. In this repository already is a project with such name. First remove the old project + project_removed: Project deleted + project_not_removed: Project deleting failed + + product: + saved: Product saved + save_error: Product saves error + build_started: Product build started + destroyed: Product deleted + + platform: + saved: Platform saved + save_error: Platform saves error + freezed: Platform freezed + freeze_error: Platform freezing error, try again + unfreezed: Platform unfreezed + unfreeze_error: Platform unfreezing error, try again + destroyed: Platform deleted + build_all_success: All project build in progress + + build_list: + saved: Project version '%{project_version}' build list, platform '%{bpl}', architecture '%{arch}' creation success + save_error: Project version '%{project_version}' build list, platform '%{bpl}', architecture '%{arch}' creation error + no_project_version_selected: Select any version of project + no_project_version_found: Project version '%{project_version}' not found + no_arch_or_platform_selected: At least one of architecture of platform must selected + wrong_platform: For the main repository its mail platform can be chosen only! + can_not_published: Build publishing with status "Build" available only + + attributes: + password: Password + password_confirmation: Confirmation + remember_me: Remember + name: Name + parent_platform_id: Parent platform + build_list: Build list + + activerecord: + models: + category: Category + repository: Repository + arch: Arch + container: Container + platform: Platform + group: Group + event_log: Event log + project: Project + rpm: RPM + user: User + private_user: Private user + product: Product + product_build_list: Product build list + build_list: Build list + build_list_item: Build list item + download: Statistics + auto_build_list: Auto rebuild list + settings: + notifier: Notifies setting + + attributes: + settings: + notifier: + can_notify: Notifications by e-mail + new_comment: New task comment notifications + new_comment_reply: New reply of comment notifications + new_issue: New task notifications + issue_assign: New task assignment notifications + + auto_build_list: + project_id: Project + project: Project + bpl_id: Repository for saving + bpl: Repository for saving + pl_id: Platform + pl: Platform + arch_id: Architecture + arch: Architecture + + comment: + body: Content + user: Author + + issue: + title: Title + body: Content + user: Assigned + user_id: Assigned + project: Project + status: Status + + private_user: + login: Login + password: Password + + category: + parent_id: Parent + name: Name + + repository: + name: Name + description: Description + platform_id: Platform + platform: Platform + created_at: Created + updated_at: Updated + owner: Owner + + product: + name: Name + platform_id: Platform + build_status: Build status + build_path: ISO path + created_at: Created + updated_at: Updated + ks: Content .ks.template + counter: Content .counter + build_script: Content build + menu: Content .menu.xml + tar: Tar.bz2 file + is_template: Template + system_wide: System + cron_tab: Cront tab + use_cron: Cron usage + + arch: + name: Name + created_at: Created + updated_at: Updated + + container: + name: Name + project_id: Project + project: Project + owner_id: Owner + owner: Owner + created_at: Created + updated_at: Updated + + platform: + name: Name + description: Description + parent_platform_id: Parent platform + parent: Parent platform + released: Released + created_at: Created + updated_at: Updated + distrib_type: Source type + visibility: Status + visibility_types: + open: Open + hidden: Hidden + + event_log: + kind: Event type + created_at: Event date and time + user: User + ip: User IP + protocol: Access protocol + description: Description + + project: + category_id: Category + name: Name + description: Descripton + owner: Owner + visibility: Visibility + repository_id: Repository + repository: Repository + created_at: Created + updated_at: Updated + has_issues: Tracker on + + rpm: + name: Name + arch_id: Arch + arch: Arch + project_id: Project + project: Project + created_at: Created + updated_at: Updated + + role: + name: Name + on: Slave + to: Master + use_default: By default + use_default_for_owner: Default by owner + + group: + name: Name + uname: Nickname + owner: Owner + created_at: Created + updated_at: Updated + + user: + name: User + login: Nickname or Email + email: Email + uname: Nickname + ssh_key: SSH key + current_password: Current password + role: Role + created_at: Created + updated_at: Updated + role: System role + language: Language + + product_build_list: + id: Id + product: Product + status: Status + notified_at: Notified at + + build_list: + bs_id: Id + name: Name + container_path: Container path + status: Status + project_id: Project + project: Project + arch_id: Architecture + arch: Architecture + is_circle: Recurrent + notified_at: Notified at + additional_repos: Additional repository + include_repos: Includes repository + updated_at: Updated + created_at: Created + pl: Packet list repository + pl_id: Packet list repository + bpl: Platform + bpl_id: Platform + update_type: Update type + build_requires: Dependable build requires + auto_publish: Automated publising + project_version: Version + user: User + + build_list/item: + name: Name + level: Level + status: Status + version: Version + build_list: Build list + + download: + name: Name + version: Version + distro: Source + platform: Platform + counter: Downloads + + notifications: + subjects: + new_comment_notification: New comment to your task + new_issue_notification: New task added to project + new_user_notification: Registered on project «%{ project_name }» + issue_assign_notification: New task assigned \ No newline at end of file From bae56741d0b575b25ce9a4bb1d3a59cdafa440a8 Mon Sep 17 00:00:00 2001 From: Vladimir Sharshov Date: Fri, 20 Jan 2012 12:24:57 +0400 Subject: [PATCH 45/67] Temporary disable AutoBuild functions for users (not working at now) --- app/models/ability.rb | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/models/ability.rb b/app/models/ability.rb index c2cda4f80..7709990ee 100644 --- a/app/models/ability.rb +++ b/app/models/ability.rb @@ -46,8 +46,9 @@ class Ability can(:fork, Project) {|project| can? :read, project} can(:destroy, Project) {|project| owner? project} - can :create, AutoBuildList - can [:index, :destroy], AutoBuildList, :project_id => user.own_project_ids + # TODO: Turn on AAA when it will be updated + #can :create, AutoBuildList + #can [:index, :destroy], AutoBuildList, :project_id => user.own_project_ids can :read, BuildList, :project => {:visibility => 'open'} can :read, BuildList, :project => {:owner_type => 'User', :owner_id => user.id} From e3a716b7dba22a5f522eb1d7e754cc5bbcdf59b9 Mon Sep 17 00:00:00 2001 From: "konstantin.grabar" Date: Fri, 20 Jan 2012 15:29:32 +0400 Subject: [PATCH 46/67] [refs #105] Fix some translations --- app/controllers/platforms_controller.rb | 2 +- app/views/devise/shared/_links.haml | 12 ++++++------ .../user_mailer/issue_assign_notification.en.haml | 7 +++++++ ...cation.haml => issue_assign_notification.ru.haml} | 0 .../user_mailer/new_comment_notification.en.haml | 9 +++++++++ ...ication.haml => new_comment_notification.ru.haml} | 0 .../new_comment_reply_notification.en.haml | 9 +++++++++ ...n.haml => new_comment_reply_notification.ru.haml} | 0 app/views/user_mailer/new_issue_notification.en.haml | 7 +++++++ ...ification.haml => new_issue_notification.ru.haml} | 0 app/views/user_mailer/new_user_notification.en.haml | 12 ++++++++++++ ...tification.haml => new_user_notification.ru.haml} | 0 config/locales/en.yml | 11 ++++++++++- config/locales/ru.yml | 10 ++++++++++ 14 files changed, 71 insertions(+), 8 deletions(-) create mode 100644 app/views/user_mailer/issue_assign_notification.en.haml rename app/views/user_mailer/{issue_assign_notification.haml => issue_assign_notification.ru.haml} (100%) create mode 100644 app/views/user_mailer/new_comment_notification.en.haml rename app/views/user_mailer/{new_comment_notification.haml => new_comment_notification.ru.haml} (100%) create mode 100644 app/views/user_mailer/new_comment_reply_notification.en.haml rename app/views/user_mailer/{new_comment_reply_notification.haml => new_comment_reply_notification.ru.haml} (100%) create mode 100644 app/views/user_mailer/new_issue_notification.en.haml rename app/views/user_mailer/{new_issue_notification.haml => new_issue_notification.ru.haml} (100%) create mode 100644 app/views/user_mailer/new_user_notification.en.haml rename app/views/user_mailer/{new_user_notification.haml => new_user_notification.ru.haml} (100%) diff --git a/app/controllers/platforms_controller.rb b/app/controllers/platforms_controller.rb index 3ce47f9a7..9c9563e02 100644 --- a/app/controllers/platforms_controller.rb +++ b/app/controllers/platforms_controller.rb @@ -113,7 +113,7 @@ class PlatformsController < ApplicationController @cloned = @platform.make_clone(:name => params[:platform]['name'], :description => params[:platform]['description'], :owner_id => current_user.id, :owner_type => current_user.class.to_s) if @cloned.persisted? - flash[:notice] = 'Клонирование успешно' + flash[:notice] = I18n.t("flash.platform.clone_success") redirect_to @cloned else flash[:error] = @cloned.errors.full_messages.join('. ') diff --git a/app/views/devise/shared/_links.haml b/app/views/devise/shared/_links.haml index f3c6883ac..958f5ec3c 100644 --- a/app/views/devise/shared/_links.haml +++ b/app/views/devise/shared/_links.haml @@ -1,13 +1,13 @@ - if controller_name != 'sessions' - = link_to "Войти", new_session_path(resource_name), :class => "text_button_padding link_button" + = link_to t("layout.devise.shared_links.sign_in"), new_session_path(resource_name), :class => "text_button_padding link_button" - if devise_mapping.registerable? && controller_name != 'registrations' - = link_to "Зарегистрироваться", new_registration_path(resource_name), :class => "text_button_padding link_button" + = link_to t("layout.devise.shared_links.sign_up"), new_registration_path(resource_name), :class => "text_button_padding link_button" - if devise_mapping.recoverable? && controller_name != 'passwords' - = link_to "Забыли пароль?", new_password_path(resource_name), :class => "text_button_padding link_button" + = link_to t("layout.devise.shared_links.forgot_password"), new_password_path(resource_name), :class => "text_button_padding link_button" - if devise_mapping.confirmable? && controller_name != 'confirmations' - = link_to "Не получили инструкции по подтверждению?", new_confirmation_path(resource_name), :class => "text_button_padding link_button" + = link_to t("layout.devise.shared_links.confirm_again"), new_confirmation_path(resource_name), :class => "text_button_padding link_button" - if devise_mapping.lockable? && resource_class.unlock_strategy_enabled?(:email) && controller_name != 'unlocks' - = link_to "Не получили инструкции по разблокировке?", new_unlock_path(resource_name), :class => "text_button_padding link_button" + = link_to t("layout.devise.shared_links.unlock"), new_unlock_path(resource_name), :class => "text_button_padding link_button" - if devise_mapping.omniauthable? - resource_class.omniauth_providers.each do |provider| - = link_to "Войти через #{provider.to_s.classify}", omniauth_authorize_path(resource_name, provider), :class => "text_button_padding link_button" \ No newline at end of file + = link_to t("layout.devise.shared_links.sign_in_through", :provider => provider.to_s.classify), omniauth_authorize_path(resource_name, provider), :class => "text_button_padding link_button" diff --git a/app/views/user_mailer/issue_assign_notification.en.haml b/app/views/user_mailer/issue_assign_notification.en.haml new file mode 100644 index 000000000..83c33e8ac --- /dev/null +++ b/app/views/user_mailer/issue_assign_notification.en.haml @@ -0,0 +1,7 @@ +%p== Hello, #{@user.name}. + + +%p You have been assigned to issue #{ link_to @issue.title, [@issue.project, @issue] } + + +%p== Support team «ROSA Build System» diff --git a/app/views/user_mailer/issue_assign_notification.haml b/app/views/user_mailer/issue_assign_notification.ru.haml similarity index 100% rename from app/views/user_mailer/issue_assign_notification.haml rename to app/views/user_mailer/issue_assign_notification.ru.haml diff --git a/app/views/user_mailer/new_comment_notification.en.haml b/app/views/user_mailer/new_comment_notification.en.haml new file mode 100644 index 000000000..7c02852bc --- /dev/null +++ b/app/views/user_mailer/new_comment_notification.en.haml @@ -0,0 +1,9 @@ +%p== Hello, #{@user.name}. + + +%p To the issue #{ link_to @comment.commentable.title, [@comment.commentable.project, @comment.commentable] } added a comment. + +%p "#{ @comment.body }" + + +%p== Support team «ROSA Build System» diff --git a/app/views/user_mailer/new_comment_notification.haml b/app/views/user_mailer/new_comment_notification.ru.haml similarity index 100% rename from app/views/user_mailer/new_comment_notification.haml rename to app/views/user_mailer/new_comment_notification.ru.haml diff --git a/app/views/user_mailer/new_comment_reply_notification.en.haml b/app/views/user_mailer/new_comment_reply_notification.en.haml new file mode 100644 index 000000000..9324062f2 --- /dev/null +++ b/app/views/user_mailer/new_comment_reply_notification.en.haml @@ -0,0 +1,9 @@ +%p== Hello, #{@user.name}. + + +%p Your comment into issue #{ link_to @comment.commentable.title, [@comment.commentable.project, @comment.commentable] } has been answered. + +%p "#{ @comment.body }" + + +%p== Support team «ROSA Build System» diff --git a/app/views/user_mailer/new_comment_reply_notification.haml b/app/views/user_mailer/new_comment_reply_notification.ru.haml similarity index 100% rename from app/views/user_mailer/new_comment_reply_notification.haml rename to app/views/user_mailer/new_comment_reply_notification.ru.haml diff --git a/app/views/user_mailer/new_issue_notification.en.haml b/app/views/user_mailer/new_issue_notification.en.haml new file mode 100644 index 000000000..f814fa617 --- /dev/null +++ b/app/views/user_mailer/new_issue_notification.en.haml @@ -0,0 +1,7 @@ +%p== Hello, #{@user.name}. + + +%p To project #{ link_to @issue.project.name, project_path(@issue.project) } has been added an issue #{ link_to @issue.title, [@issue.project, @issue] } + + +%p== Support team «ROSA Build System» diff --git a/app/views/user_mailer/new_issue_notification.haml b/app/views/user_mailer/new_issue_notification.ru.haml similarity index 100% rename from app/views/user_mailer/new_issue_notification.haml rename to app/views/user_mailer/new_issue_notification.ru.haml diff --git a/app/views/user_mailer/new_user_notification.en.haml b/app/views/user_mailer/new_user_notification.en.haml new file mode 100644 index 000000000..d1a0722bf --- /dev/null +++ b/app/views/user_mailer/new_user_notification.en.haml @@ -0,0 +1,12 @@ +%p== Hello, #{@user.name}. + + +%p You have been sign up to project «ROSA Build System» and now can sign in. + + +%p + ==Your email : #{@user.email} + %br/ + ==Your password: #{@user.password} + +%p== Support team «ROSA Build System» diff --git a/app/views/user_mailer/new_user_notification.haml b/app/views/user_mailer/new_user_notification.ru.haml similarity index 100% rename from app/views/user_mailer/new_user_notification.haml rename to app/views/user_mailer/new_user_notification.ru.haml diff --git a/config/locales/en.yml b/config/locales/en.yml index 4fa4edbc8..6e3bc7268 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -46,6 +46,15 @@ en: edit_header: Notifier setting processing: working ... + devise: + shared_links: + sign_in: Sign in + sign_up: Sign up + forgot_password: Forgot your password? + confirm_again: Do not receive the confirmation link? + unlock: Do not receive unlock instructions? + sign_in_through: Sign in by %{provider} + downloads: title: Downloads statistic message: Automatically updated every 5 minutes @@ -690,4 +699,4 @@ en: new_comment_notification: New comment to your task new_issue_notification: New task added to project new_user_notification: Registered on project «%{ project_name }» - issue_assign_notification: New task assigned \ No newline at end of file + issue_assign_notification: New task assigned diff --git a/config/locales/ru.yml b/config/locales/ru.yml index a6c7c7229..2e1453965 100644 --- a/config/locales/ru.yml +++ b/config/locales/ru.yml @@ -46,6 +46,15 @@ ru: edit_header: Настройки оповещений processing: Обрабатывается... + devise: + shared_links: + sign_in: Войти + sign_up: Зарегистрироваться + forgot_password: Забыли пароль? + confirm_again: Не получили инструкции по подтверждению? + unlock: Не получили инструкции по разблокировке? + sign_in_through: Войти через %{provider} + downloads: title: Статистика закачек пакетов message: Обновляется автоматически каждые 5 минут @@ -451,6 +460,7 @@ ru: unfreeze_error: Не удалось разморозить платформу, попробуйте еще раз destroyed: Платформа успешно удалена build_all_success: Все проекты успешно отправлены на сборку + clone_success: Клонирование успешно build_list: saved: Билд лист для версии '%{project_version}', платформы '%{bpl}' и архитектуры '%{arch}' создан успешно From 23ace52d90bfdfb2b6b15cc59b5bb1aa7ebb2ae4 Mon Sep 17 00:00:00 2001 From: "konstantin.grabar" Date: Fri, 20 Jan 2012 22:31:01 +0400 Subject: [PATCH 47/67] [refs #113] Images render and download href for binary data into blobs --- app/controllers/git/blobs_controller.rb | 15 +++++++++- app/helpers/git_helper.rb | 7 ++++- app/views/git/blobs/show.html.haml | 37 +++++++++++++++++++------ 3 files changed, 49 insertions(+), 10 deletions(-) diff --git a/app/controllers/git/blobs_controller.rb b/app/controllers/git/blobs_controller.rb index 1182412ea..9a2cf3db0 100644 --- a/app/controllers/git/blobs_controller.rb +++ b/app/controllers/git/blobs_controller.rb @@ -5,6 +5,16 @@ class Git::BlobsController < Git::BaseController def show @blob = @tree / @path + + if params[:raw] + image_url = Rails.root.to_s + "/" + @path + + response.headers['Cache-Control'] = "public, max-age=#{12.hours.to_i}" + response.headers['Content-Type'] = @blob.mime_type + response.headers['Content-Disposition'] = 'inline' + + render(:text => open(image_url).read) and return + end end def blame @@ -20,6 +30,9 @@ class Git::BlobsController < Git::BaseController render :text => @blob.data, :content_type => @blob.mime_type end + def image + end + protected def set_path @path = params[:path] @@ -42,4 +55,4 @@ class Git::BlobsController < Git::BaseController @commit = @git_repository.log(@treeish, @path).first # TODO WTF nil ? end end -end \ No newline at end of file +end diff --git a/app/helpers/git_helper.rb b/app/helpers/git_helper.rb index 8dd3624ad..ffafd2bd5 100644 --- a/app/helpers/git_helper.rb +++ b/app/helpers/git_helper.rb @@ -40,4 +40,9 @@ module GitHelper blob.data.split("\n").collect{|line| "
#{line.present? ? h(line) : "
"}
"}.join end -end \ No newline at end of file + def choose_render_way(blob) + return :image if blob.mime_type.match(/image/) + return :text if blob.mime_type.match(/text|xml/) + :binary + end +end diff --git a/app/views/git/blobs/show.html.haml b/app/views/git/blobs/show.html.haml index a02bcd20c..04b3a19b3 100644 --- a/app/views/git/blobs/show.html.haml +++ b/app/views/git/blobs/show.html.haml @@ -13,6 +13,7 @@ .content .inner %h3= render_path + %h3= @blob.mime_type .blob_header .size #{(@blob.size / 1024.0).round(3)} Kb @@ -22,13 +23,33 @@ - else #{link_to "Raw", raw_path(@project, @treeish, @path)} #{link_to "Blame", blame_path(@project, @treeish, @path)} #{link_to "History", commits_path(@project, @treeish, @path)} .clear - %table.table.blob - %tr - %td.lines - :plain -
#{render_line_numbers(@blob.data.split("\n").length)}
- %td.blob - :plain -
#{render_blob(@blob)}
+ - case choose_render_way(@blob) + - when :image + %table.table.blob + %tr + %td.lines + %td.blob + :plain +
+
+
+ - when :text + %table.table.blob + %tr + %td.lines + :plain +
#{render_line_numbers(@blob.data.split("\n").length)}
+ %td.blob + :plain +
#{render_blob(@blob)}
+ - when :binary + %table.table.blob + %tr + %td.lines + %td.blob + :plain +
+
#{ link_to @blob.basename, raw_path(@project, @treeish, @path) }
+
- content_for :sidebar, render(:partial => 'git/shared/sidebar') From 5d93d40693d1ec73785d19c5b89c4d164feec432 Mon Sep 17 00:00:00 2001 From: "konstantin.grabar" Date: Fri, 20 Jan 2012 22:33:22 +0400 Subject: [PATCH 48/67] [refs #113] Remove unused action from blobs controller --- app/controllers/git/blobs_controller.rb | 3 --- 1 file changed, 3 deletions(-) diff --git a/app/controllers/git/blobs_controller.rb b/app/controllers/git/blobs_controller.rb index 9a2cf3db0..eb788d211 100644 --- a/app/controllers/git/blobs_controller.rb +++ b/app/controllers/git/blobs_controller.rb @@ -30,9 +30,6 @@ class Git::BlobsController < Git::BaseController render :text => @blob.data, :content_type => @blob.mime_type end - def image - end - protected def set_path @path = params[:path] From f46b179486e41623a0809d2c83ace0e0ac99a541 Mon Sep 17 00:00:00 2001 From: "konstantin.grabar" Date: Fri, 20 Jan 2012 22:40:00 +0400 Subject: [PATCH 49/67] [refs #113] Add json to mime types list --- app/helpers/git_helper.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/helpers/git_helper.rb b/app/helpers/git_helper.rb index ffafd2bd5..286fba6f2 100644 --- a/app/helpers/git_helper.rb +++ b/app/helpers/git_helper.rb @@ -42,7 +42,7 @@ module GitHelper def choose_render_way(blob) return :image if blob.mime_type.match(/image/) - return :text if blob.mime_type.match(/text|xml/) + return :text if blob.mime_type.match(/text|xml|json/) :binary end end From 7d2d080af56bbd71ea2a1263a827528b4d52ca0c Mon Sep 17 00:00:00 2001 From: Vladimir Sharshov Date: Mon, 23 Jan 2012 16:11:17 +0400 Subject: [PATCH 50/67] Fix localization [ Refs #105 ] --- config/locales/en.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/locales/en.yml b/config/locales/en.yml index 4fa4edbc8..c071b8bd5 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -1,6 +1,6 @@ en: will_paginate: - previous_label: ‹ Previous!!! + previous_label: ‹ Previous next_label: Next › page_gap: ... From a5570f667c878e2ddb412734b80fa7a3667e7167 Mon Sep 17 00:00:00 2001 From: Vladimir Sharshov Date: Mon, 23 Jan 2012 17:05:55 +0400 Subject: [PATCH 51/67] Update mount for production case --- bin/mount_downloads.sh | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/bin/mount_downloads.sh b/bin/mount_downloads.sh index 6bb68f669..13c7b8d02 100755 --- a/bin/mount_downloads.sh +++ b/bin/mount_downloads.sh @@ -2,9 +2,19 @@ for f in `ls /srv/rosa_build/shared/downloads` do - if [ -d /home/share/platforms/$f ] - then - sudo umount /srv/rosa_build/shared/downloads/$f 2>&1 >> /dev/null - sudo mount --bind /home/share/platforms/$f /srv/rosa_build/shared/downloads/$f - fi -done + if [ -d /home/share ] + # Staging case + if [ -d /home/share/platforms/$f ] + then + sudo umount /srv/rosa_build/shared/downloads/$f 2>&1 >> /dev/null + sudo mount --bind /home/share/platforms/$f /srv/rosa_build/shared/downloads/$f + fi + else + # Production case + if [ -d /share/platforms/$f ] + then + sudo umount /srv/rosa_build/shared/downloads/$f 2>&1 >> /dev/null + sudo mount --bind /share/platforms/$f /srv/rosa_build/shared/downloads/$f + fi + fi +done \ No newline at end of file From c13bd0432f316e71125f432c3cc54ccd2fe22260 Mon Sep 17 00:00:00 2001 From: Vladimir Sharshov Date: Mon, 23 Jan 2012 18:52:42 +0400 Subject: [PATCH 52/67] Emergency fix for imports --- lib/tasks/import.rake | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/tasks/import.rake b/lib/tasks/import.rake index d3c5cce79..88f65117d 100644 --- a/lib/tasks/import.rake +++ b/lib/tasks/import.rake @@ -5,8 +5,9 @@ namespace :import do desc "Load projects" task :projects => :environment do source = ENV['SOURCE'] || 'http://dl.dropbox.com/u/984976/package_list.txt' - owner = User.find_by_uname(ENV['OWNER_UNAME']) || Group.find_by_uname(ENV['OWNER_UNAME']) || User.first - platform = Platform.find_by_name(ENV['PLATFORM_NAME']) # 'mandriva2011' + #owner = User.find_by_uname(ENV['OWNER_UNAME']) || Group.find_by_uname(ENV['OWNER_UNAME']) || User.first + owner = Group.find_by_uname("npp_team") + platform = Platform.find_by_name("RosaNPP") # RosaNPP repo = platform.repositories.first rescue nil say "START import projects from '#{source}' for '#{owner.uname}'.#{repo ? " To repo '#{platform.name}/#{repo.name}'." : ''}" ask 'Press enter to continue' From 733adaf111dac6daa6681d6174d69ac6bda5ed1e Mon Sep 17 00:00:00 2001 From: Vladimir Sharshov Date: Mon, 23 Jan 2012 20:19:10 +0400 Subject: [PATCH 53/67] Update build_for for new requirements --- app/models/project.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/models/project.rb b/app/models/project.rb index 5763fc071..6617694aa 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -58,6 +58,8 @@ class Project < ActiveRecord::Base bl.project_version = "latest_#{platform.name}" bl.build_requires = false # already set as db default bl.user = user + bl.auto_publish = true # already set as db default + bl.include_repos << Platform.find_by_id(platform).repositories.find_by_name('main').id end end From e1a4dd5ab57fbe4258ce2d0d44f3a0fad098d2fb Mon Sep 17 00:00:00 2001 From: Vladimir Sharshov Date: Mon, 23 Jan 2012 21:07:09 +0400 Subject: [PATCH 54/67] Fix branch name for mass rebuild Fix error in include_repos --- app/models/project.rb | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/models/project.rb b/app/models/project.rb index 6617694aa..85c32937d 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -55,11 +55,12 @@ class Project < ActiveRecord::Base bl.bpl = platform bl.update_type = 'recommended' bl.arch = Arch.find_by_name('i586') - bl.project_version = "latest_#{platform.name}" + # FIXME: Need to set "latest_#{platform.name}" + bl.project_version = "latest_mandriva2011" bl.build_requires = false # already set as db default bl.user = user bl.auto_publish = true # already set as db default - bl.include_repos << Platform.find_by_id(platform).repositories.find_by_name('main').id + bl.include_repos = [] << platform.repositories.find_by_name('main').id end end From c3f415e90cddf9856efb34ae0a4a9dc0a36ab5b8 Mon Sep 17 00:00:00 2001 From: Vladimir Sharshov Date: Mon, 23 Jan 2012 22:11:53 +0400 Subject: [PATCH 55/67] Add new build status for Item --- app/models/build_list/item.rb | 6 +++++- config/locales/en.yml | 1 + config/locales/ru.yml | 1 + 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/app/models/build_list/item.rb b/app/models/build_list/item.rb index a06e3b89e..ec49f740c 100644 --- a/app/models/build_list/item.rb +++ b/app/models/build_list/item.rb @@ -1,11 +1,15 @@ class BuildList::Item < ActiveRecord::Base + belongs_to :build_list attr_protected :build_list_id - STATUSES = [BuildServer::SUCCESS, BuildServer::DEPENDENCIES_ERROR, BuildServer::BUILD_ERROR, BuildServer::BUILD_STARTED] + GIT_ERROR = 5 + + STATUSES = [BuildServer::SUCCESS, BuildServer::DEPENDENCIES_ERROR, BuildServer::BUILD_ERROR, BuildServer::BUILD_STARTED, GIT_ERROR] HUMAN_STATUSES = { nil => :unknown, + GIT_ERROR => :git_error, BuildServer::DEPENDENCIES_ERROR => :dependencies_error, BuildServer::SUCCESS => :success, BuildServer::BUILD_STARTED => :build_started, diff --git a/config/locales/en.yml b/config/locales/en.yml index c071b8bd5..cfeb90f79 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -338,6 +338,7 @@ en: dependencies_error: Dependences not found success: Build complete unknown: Build waiting + git_error: Git error statuses: build_error: Build error diff --git a/config/locales/ru.yml b/config/locales/ru.yml index a6c7c7229..469a1293a 100644 --- a/config/locales/ru.yml +++ b/config/locales/ru.yml @@ -338,6 +338,7 @@ ru: dependencies_error: зависимости не найдены success: собран unknown: ожидает сборки + git_error: проблема с гит statuses: build_error: ошибка сборки From 7e1a26000ecb2b84e91a3276340e77f7a41d1a98 Mon Sep 17 00:00:00 2001 From: Vladimir Sharshov Date: Tue, 24 Jan 2012 01:12:42 +0400 Subject: [PATCH 56/67] Fix for "undefined method `<<' for nil:NilClass" --- app/models/project.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/project.rb b/app/models/project.rb index 85c32937d..0935e37ad 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -60,7 +60,7 @@ class Project < ActiveRecord::Base bl.build_requires = false # already set as db default bl.user = user bl.auto_publish = true # already set as db default - bl.include_repos = [] << platform.repositories.find_by_name('main').id + bl.include_repos = [platform.repositories.find_by_name('main').id] end end From 2a20b51c197c31a1f8abf66e76a6b601eecea5f5 Mon Sep 17 00:00:00 2001 From: Vladimir Sharshov Date: Tue, 24 Jan 2012 02:24:12 +0400 Subject: [PATCH 57/67] Fix deploy: "DJ does not restart and create many new instances" --- config/deploy.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/deploy.rb b/config/deploy.rb index 76df1cd51..b03d867e4 100644 --- a/config/deploy.rb +++ b/config/deploy.rb @@ -61,7 +61,7 @@ namespace :deploy do end after "deploy:update_code", "deploy:symlink_all", "deploy:migrate" -after "deploy:restart", "delayed_job:restart", "bluepill:restart", "deploy:cleanup" +after "deploy:restart","bluepill:stop", "delayed_job:restart", "deploy:cleanup", "bluepill:start" after "deploy:setup", "deploy:symlink_pids" require 'cape' From 0f06d4f6271c5e2f63ae2fc897c55d6b3d3d6eb4 Mon Sep 17 00:00:00 2001 From: Alexander Machehin Date: Tue, 24 Jan 2012 23:30:39 +0600 Subject: [PATCH 58/67] [refs #124] Add missing translation --- config/locales/devise.en.yml | 7 +++++++ config/locales/en.yml | 1 + config/locales/ru.yml | 3 ++- 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/config/locales/devise.en.yml b/config/locales/devise.en.yml index 5e4e43321..7f0e522af 100644 --- a/config/locales/devise.en.yml +++ b/config/locales/devise.en.yml @@ -20,6 +20,8 @@ en: passwords: send_instructions: 'You will receive an email with instructions about how to reset your password in a few minutes.' updated: 'Your password was changed successfully. You are now signed in.' + button: 'Submit' + edit_button: 'Change my password' confirmations: send_instructions: 'You will receive an email with instructions about how to confirm your account in a few minutes.' confirmed: 'Your account was successfully confirmed. You are now signed in.' @@ -27,6 +29,11 @@ en: signed_up: 'You have signed up successfully. If enabled, a confirmation was sent to your e-mail.' updated: 'You updated your account successfully.' destroyed: 'Bye! Your account was successfully cancelled. We hope to see you again soon.' + sign_up_header: 'Signup' + edit_password_description: Leave blank if you don't want to change it + current_password_description: 'We need your current password to confirm your changes' + cancel: 'Cancel my account' + cancel_confirmation: 'Are you sure?' unlocks: send_instructions: 'You will receive an email with instructions about how to unlock your account in a few minutes.' unlocked: 'Your account was successfully unlocked. You are now signed in.' diff --git a/config/locales/en.yml b/config/locales/en.yml index 4fa4edbc8..560b524ef 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -40,6 +40,7 @@ en: not_access: Access denied! owner: Owner confirm: Sure? + back: Back settings: notifier: Notifier setting notifiers: diff --git a/config/locales/ru.yml b/config/locales/ru.yml index a6c7c7229..af4d69248 100644 --- a/config/locales/ru.yml +++ b/config/locales/ru.yml @@ -39,7 +39,8 @@ ru: upload: Загрузить not_access: Нет доступа! owner: Владелец - confirm: Уверенны? + confirm: Уверены? + back: Назад settings: notifier: Настройки оповещений notifiers: From 3f4bf658258f8b00c9067debe3f96821653a92df Mon Sep 17 00:00:00 2001 From: Pavel Chipiga Date: Tue, 24 Jan 2012 22:35:16 +0200 Subject: [PATCH 59/67] Upgrade paperclip. Apply srpm_import script and UI. Fix specs. Refs #31 --- Gemfile | 2 +- Gemfile.lock | 6 +-- app/models/product.rb | 2 +- app/models/project.rb | 13 +++++++ app/views/projects/_form.html.haml | 3 ++ app/views/projects/edit.html.haml | 2 +- app/views/projects/new.html.haml | 2 +- bin/import_srpm.sh | 38 +++++++++++++++++++ config/locales/en.yml | 3 +- config/locales/ru.yml | 9 ++--- ...0124101727_add_srpm_columns_to_projects.rb | 11 ++++++ spec/models/cancan_spec.rb | 2 +- 12 files changed, 78 insertions(+), 15 deletions(-) create mode 100755 bin/import_srpm.sh create mode 100644 db/migrate/20120124101727_add_srpm_columns_to_projects.rb diff --git a/Gemfile b/Gemfile index bd75f3d66..f97b6797b 100644 --- a/Gemfile +++ b/Gemfile @@ -18,7 +18,7 @@ gem "yui-compressor", "0.9.5" # Higher versions depends on Platform gem which co gem 'rails3-jquery-autocomplete' gem 'ancestry', '~> 1.2.4' -gem 'paperclip', "~> 2.3" +gem 'paperclip', "~> 2.5" gem "will_paginate", "~> 3.0.2" gem 'meta-tags', '~> 1.2.4', :require => 'meta_tags' gem "russian" diff --git a/Gemfile.lock b/Gemfile.lock index 33a001a38..23cb9ae7d 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -59,7 +59,7 @@ GEM capistrano (>= 1.0.0) capistrano_colors (0.5.5) chronic (0.6.6) - cocaine (0.2.0) + cocaine (0.2.1) columnize (0.3.5) daemons (1.1.4) delayed_job (2.1.4) @@ -120,7 +120,7 @@ GEM omniauth (~> 1.0) rack-openid (~> 1.3.1) orm_adapter (0.0.5) - paperclip (2.4.5) + paperclip (2.5.0) activerecord (>= 2.3.0) activesupport (>= 2.3.2) cocaine (>= 0.0.2) @@ -230,7 +230,7 @@ DEPENDENCIES mysql2 (<= 0.2.9) omniauth (~> 1.0.1) omniauth-openid (~> 1.0.1) - paperclip (~> 2.3) + paperclip (~> 2.5) pg (~> 0.11.0) rails (= 3.0.11) rails-xmlrpc (~> 0.3.6) diff --git a/app/models/product.rb b/app/models/product.rb index 36337f4f9..84afdfb35 100644 --- a/app/models/product.rb +++ b/app/models/product.rb @@ -9,7 +9,7 @@ class Product < ActiveRecord::Base has_attached_file :tar - validates_attachment_content_type :tar, :content_type => ["application/gnutar", "application/x-compressed", "application/x-gzip", "application/x-bzip2", "application/x-tar"], :message => I18n.t('layout.products.invalid_content_type') + validates_attachment_content_type :tar, :content_type => ["application/gnutar", "application/x-compressed", "application/x-gzip", "application/x-bzip2", "application/x-tar"], :message => I18n.t('layout.invalid_content_type') validates :name, :presence => true, :uniqueness => {:scope => :platform_id} scope :recent, order("name ASC") diff --git a/app/models/project.rb b/app/models/project.rb index 0935e37ad..4bc9447d7 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -8,6 +8,7 @@ class Project < ActiveRecord::Base has_many :build_lists, :dependent => :destroy has_many :auto_build_lists, :dependent => :destroy + # has_many :project_imports, :dependent => :destroy has_many :project_to_repositories, :dependent => :destroy has_many :repositories, :through => :project_to_repositories @@ -18,6 +19,8 @@ class Project < ActiveRecord::Base validates :name, :uniqueness => {:scope => [:owner_id, :owner_type]}, :presence => true, :format => { :with => /^[a-zA-Z0-9_\-\+\.]+$/ } validates :owner, :presence => true # validate {errors.add(:base, I18n.t('flash.project.save_warning_ssh_key')) if owner.ssh_key.blank?} + validates_attachment_size :srpm, :less_than => 500.megabytes + validates_attachment_content_type :srpm, :content_type => ['application/octet-stream'], :message => I18n.t('layout.invalid_content_type') # "application/x-rpm", "application/x-redhat-package-manager" ? #attr_accessible :category_id, :name, :description, :visibility attr_readonly :name @@ -31,10 +34,13 @@ class Project < ActiveRecord::Base after_create :attach_to_personal_repository after_create :create_git_repo after_destroy :destroy_git_repo + after_save {|p| p.delay.import_srpm if p.srpm?} # should be after create_git_repo # after_rollback lambda { destroy_git_repo rescue true if new_record? } has_ancestry + has_attached_file :srpm + include Modules::Models::Owner def auto_build @@ -137,6 +143,13 @@ class Project < ActiveRecord::Base @platforms ||= repositories.map(&:platform).uniq end + def import_srpm(branch_name = 'import') + if srpm? + system("#{Rails.root.join('bin', 'import_srpm.sh')} #{srpm.path} #{path} #{branch_name} >> /dev/null 2>&1") + self.srpm = nil; save :validate => false # clear srpm + end + end + class << self def commit_comments(commit, project) comments = Comment.where(:commentable_id => commit.id, :commentable_type => 'Grit::Commit').order(:created_at) diff --git a/app/views/projects/_form.html.haml b/app/views/projects/_form.html.haml index d0cc3e7bf..7699fc987 100644 --- a/app/views/projects/_form.html.haml +++ b/app/views/projects/_form.html.haml @@ -13,6 +13,9 @@ .group = f.label :has_issues, t("activerecord.attributes.project.has_issues"), :class => :label = f.check_box :has_issues +.group + = f.label :srpm, t("activerecord.attributes.project.srpm"), :class => :label + = f.file_field :srpm, :class => 'file_field' .group.navform.wat-cf %button.button{:type => "submit"} diff --git a/app/views/projects/edit.html.haml b/app/views/projects/edit.html.haml index ba3c5c14f..1017c5329 100644 --- a/app/views/projects/edit.html.haml +++ b/app/views/projects/edit.html.haml @@ -8,7 +8,7 @@ .content %h2.title= t("layout.projects.edit_header") .inner - = form_for @project, :html => { :class => :form } do |f| + = form_for @project, :html => { :class => :form, :multipart => true } do |f| = render :partial => "form", :locals => {:f => f} - content_for :sidebar, render('sidebar') diff --git a/app/views/projects/new.html.haml b/app/views/projects/new.html.haml index f9304bdd8..6e5ec7973 100644 --- a/app/views/projects/new.html.haml +++ b/app/views/projects/new.html.haml @@ -9,7 +9,7 @@ .content %h2.title= t("layout.projects.new_header") .inner - = form_for [get_owner, @project], :html => { :class => :form } do |f| + = form_for [get_owner, @project], :html => { :class => :form, :multipart => true } do |f| = render :partial => "form", :locals => {:f => f} -# content_for :sidebar, render('sidebar') diff --git a/bin/import_srpm.sh b/bin/import_srpm.sh new file mode 100755 index 000000000..753f5228b --- /dev/null +++ b/bin/import_srpm.sh @@ -0,0 +1,38 @@ +#!/usr/bin/env bash +# import_srpm.sh: Import SRPM packages to git repo + +# Input data +srpm_path=$1 +git_path=$2 +git_branch=$3 +tmp_dir=/tmp/$RANDOM +version=$(rpm -q --qf '[%{Version}]' -p $srpm_path) + +# Clone destination repo +mkdir -p $tmp_dir +git clone $git_path $tmp_dir + +# Switch to import branch +cd $tmp_dir +git branch --track $git_branch origin/$git_branch # Try track remote +git branch $git_branch # Try create local +git checkout $git_branch + +# Remove all files except .git +rm -rf $tmp_dir/* +mv $tmp_dir/.git $tmp_dir/git +rm -rf $tmp_dir/.* +mv $tmp_dir/git $tmp_dir/.git + +# Unpack srpm +rpm2cpio $srpm_path > srpm.cpio +cpio -idv < srpm.cpio +rm -f srpm.cpio + +# Commit and push changes +git add -A . +git commit -m "Automatic import for version $version" +git push origin HEAD + +# Cleanup +rm -rf $tmp_dir diff --git a/config/locales/en.yml b/config/locales/en.yml index cfeb90f79..a71c0556e 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -45,6 +45,7 @@ en: notifiers: edit_header: Notifier setting processing: working ... + invalid_content_type: incorrect type downloads: title: Downloads statistic @@ -200,7 +201,6 @@ en: new_header: New product edit_header: Product editing confirm_delete: Are you sure to delete this product? - invalid_content_type: incorrect type cron_tab_generator: show: Show cron tab the generator @@ -604,6 +604,7 @@ en: created_at: Created updated_at: Updated has_issues: Tracker on + srpm: Import code from src.rpm rpm: name: Name diff --git a/config/locales/ru.yml b/config/locales/ru.yml index 469a1293a..4726f4217 100644 --- a/config/locales/ru.yml +++ b/config/locales/ru.yml @@ -45,6 +45,7 @@ ru: notifiers: edit_header: Настройки оповещений processing: Обрабатывается... + invalid_content_type: имеет неверный тип downloads: title: Статистика закачек пакетов @@ -129,7 +130,6 @@ ru: comments: confirm_delete: Вы уверены, что хотите удалить комментарий? new_header: Новый комментарий - edit_header: Редактирование комментария platforms: admin_id: Владелец @@ -200,7 +200,6 @@ ru: new_header: Новый продукт edit_header: Редактирование продукта confirm_delete: Вы уверены, что хотите удалить этот продукт? - invalid_content_type: имеет неверный тип cron_tab_generator: show: Показать cron tab генератор @@ -356,7 +355,7 @@ ru: platform_not_found: платформа не найдена platform_pending: платформа в процессе создания project_not_found: проект не найден - project_version_not_found: версия не найдена + project_version_not_found: версия не найден flash: settings: @@ -604,6 +603,7 @@ ru: created_at: Создан updated_at: Обновлен has_issues: Включить трэкер + srpm: Импортировать код из src.rpm rpm: name: Название @@ -639,7 +639,6 @@ ru: created_at: Создан updated_at: Обновлен role: Роль в системе - language: Язык product_build_list: id: Id @@ -678,14 +677,12 @@ ru: status: Статус version: Версия build_list: Сборочный лист - download: name: Название version: Версия distro: Дистрибутив platform: Архитектура counter: Закачки - notifications: subjects: new_comment_notification: Новый комментарий к Вашей задаче diff --git a/db/migrate/20120124101727_add_srpm_columns_to_projects.rb b/db/migrate/20120124101727_add_srpm_columns_to_projects.rb new file mode 100644 index 000000000..3aa569326 --- /dev/null +++ b/db/migrate/20120124101727_add_srpm_columns_to_projects.rb @@ -0,0 +1,11 @@ +class AddSrpmColumnsToProjects < ActiveRecord::Migration + def self.up + change_table :projects do |t| + t.has_attached_file :srpm + end + end + + def self.down + drop_attached_file :projects, :srpm + end +end diff --git a/spec/models/cancan_spec.rb b/spec/models/cancan_spec.rb index e245c19ff..bafc774d1 100644 --- a/spec/models/cancan_spec.rb +++ b/spec/models/cancan_spec.rb @@ -91,7 +91,7 @@ describe CanCan do @ability.should be_able_to(:read, @admin) end - it "shoud be able to read index AutoBuildList" do + pending "shoud be able to read index AutoBuildList" do @ability.should be_able_to(:index, AutoBuildList) end From bdb31b4e133de605dc27e905a6f4332babf05c79 Mon Sep 17 00:00:00 2001 From: Pavel Chipiga Date: Tue, 24 Jan 2012 22:42:16 +0200 Subject: [PATCH 60/67] Fix locale. Refs #31 --- config/locales/ru.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/config/locales/ru.yml b/config/locales/ru.yml index 4726f4217..0ac0867c6 100644 --- a/config/locales/ru.yml +++ b/config/locales/ru.yml @@ -130,6 +130,7 @@ ru: comments: confirm_delete: Вы уверены, что хотите удалить комментарий? new_header: Новый комментарий + edit_header: Редактирование комментария platforms: admin_id: Владелец @@ -355,7 +356,7 @@ ru: platform_not_found: платформа не найдена platform_pending: платформа в процессе создания project_not_found: проект не найден - project_version_not_found: версия не найден + project_version_not_found: версия не найдена flash: settings: @@ -639,6 +640,7 @@ ru: created_at: Создан updated_at: Обновлен role: Роль в системе + language: Язык product_build_list: id: Id From c16cb352ca18efc95dcf4e98401a3a0838313395 Mon Sep 17 00:00:00 2001 From: Pavel Chipiga Date: Tue, 24 Jan 2012 23:25:16 +0200 Subject: [PATCH 61/67] Fix import_srpm tmp_dir. Refs #31 --- bin/import_srpm.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/bin/import_srpm.sh b/bin/import_srpm.sh index 753f5228b..6b3bd1512 100755 --- a/bin/import_srpm.sh +++ b/bin/import_srpm.sh @@ -5,8 +5,9 @@ srpm_path=$1 git_path=$2 git_branch=$3 -tmp_dir=/tmp/$RANDOM +name=$(rpm -q --qf '[%{Name}]' -p $srpm_path) version=$(rpm -q --qf '[%{Version}]' -p $srpm_path) +tmp_dir=/tmp/$name-$version-$RANDOM # Clone destination repo mkdir -p $tmp_dir From 60c1153d493e95f0fd5f26c6bca077ccbb4d979d Mon Sep 17 00:00:00 2001 From: Pavel Chipiga Date: Tue, 24 Jan 2012 23:29:23 +0200 Subject: [PATCH 62/67] Save with validation. Refs #31 --- app/models/project.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/project.rb b/app/models/project.rb index 4bc9447d7..b8f3d385a 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -146,7 +146,7 @@ class Project < ActiveRecord::Base def import_srpm(branch_name = 'import') if srpm? system("#{Rails.root.join('bin', 'import_srpm.sh')} #{srpm.path} #{path} #{branch_name} >> /dev/null 2>&1") - self.srpm = nil; save :validate => false # clear srpm + self.srpm = nil; save # clear srpm end end From 374628a2163dc0688dff920d7d32ca1c4058b06a Mon Sep 17 00:00:00 2001 From: Pavel Chipiga Date: Thu, 26 Jan 2012 00:28:11 +0200 Subject: [PATCH 63/67] Render answer before publication trying to avoid bug. Refs #97 --- app/controllers/build_lists_controller.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/controllers/build_lists_controller.rb b/app/controllers/build_lists_controller.rb index e0ce08136..29d869151 100644 --- a/app/controllers/build_lists_controller.rb +++ b/app/controllers/build_lists_controller.rb @@ -120,9 +120,9 @@ class BuildListsController < ApplicationController @build_list.notified_at = Time.current @build_list.save - @build_list.delay.publish if @build_list.auto_publish # && @build_list.can_publish? - render :nothing => true, :status => 200 + + @build_list.delay.publish if @build_list.auto_publish # && @build_list.can_publish? end def circle_build From 6cfb7d772302ae911d9268e7040728e3c591b9fd Mon Sep 17 00:00:00 2001 From: Vladimir Sharshov Date: Thu, 26 Jan 2012 23:30:12 +0400 Subject: [PATCH 64/67] Fix for mount script --- bin/mount_downloads.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/bin/mount_downloads.sh b/bin/mount_downloads.sh index 13c7b8d02..11c2f45ca 100755 --- a/bin/mount_downloads.sh +++ b/bin/mount_downloads.sh @@ -3,6 +3,7 @@ for f in `ls /srv/rosa_build/shared/downloads` do if [ -d /home/share ] + then # Staging case if [ -d /home/share/platforms/$f ] then @@ -17,4 +18,4 @@ do sudo mount --bind /share/platforms/$f /srv/rosa_build/shared/downloads/$f fi fi -done \ No newline at end of file +done From aea6631e6d19be2ee39847771b61650595d404c2 Mon Sep 17 00:00:00 2001 From: Vladimir Sharshov Date: Fri, 27 Jan 2012 01:49:27 +0400 Subject: [PATCH 65/67] Add NewRelic service support --- Gemfile | 2 +- Gemfile.lock | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/Gemfile b/Gemfile index f97b6797b..230731340 100644 --- a/Gemfile +++ b/Gemfile @@ -39,7 +39,7 @@ gem 'unicorn', '~> 4.1.1' group :production do gem "airbrake", '~> 3.0.5' - # gem 'newrelic_rpm', '~> 3.1.1' + gem 'newrelic_rpm' gem 'bluepill', :require => false end diff --git a/Gemfile.lock b/Gemfile.lock index 23cb9ae7d..17f22e1c7 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -113,6 +113,7 @@ GEM net-ssh (2.2.1) net-ssh-gateway (1.1.0) net-ssh (>= 1.99.1) + newrelic_rpm (3.3.1) omniauth (1.0.1) hashie (~> 1.2) rack @@ -228,6 +229,7 @@ DEPENDENCIES jammit meta-tags (~> 1.2.4) mysql2 (<= 0.2.9) + newrelic_rpm omniauth (~> 1.0.1) omniauth-openid (~> 1.0.1) paperclip (~> 2.5) From 45c175942b36d0aa9ffba4a3c949921ba4908136 Mon Sep 17 00:00:00 2001 From: Vladimir Sharshov Date: Fri, 27 Jan 2012 05:00:44 +0400 Subject: [PATCH 66/67] Temporary change arch for mass rebuild --- app/models/project.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/project.rb b/app/models/project.rb index b8f3d385a..3fab488f5 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -60,7 +60,7 @@ class Project < ActiveRecord::Base bl.pl = platform bl.bpl = platform bl.update_type = 'recommended' - bl.arch = Arch.find_by_name('i586') + bl.arch = Arch.find_by_name('x86_64') # Return i586 after mass rebuild # FIXME: Need to set "latest_#{platform.name}" bl.project_version = "latest_mandriva2011" bl.build_requires = false # already set as db default From 0cacdc9d4a70b09e28811642b6a2962f34ddf2ab Mon Sep 17 00:00:00 2001 From: George Vinogradov Date: Fri, 27 Jan 2012 18:38:33 +0400 Subject: [PATCH 67/67] [issue #64] Fixed bug in migration --- Gemfile.lock | 2 +- db/migrate/20120126214447_add_projects_count_to_groups.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 5fee68804..39b210530 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -126,8 +126,8 @@ GEM net-ssh (2.2.1) net-ssh-gateway (1.1.0) net-ssh (>= 1.99.1) - nokogiri (1.5.0) newrelic_rpm (3.3.1) + nokogiri (1.5.0) omniauth (1.0.1) hashie (~> 1.2) rack diff --git a/db/migrate/20120126214447_add_projects_count_to_groups.rb b/db/migrate/20120126214447_add_projects_count_to_groups.rb index 64d8c068e..ed65a68ef 100644 --- a/db/migrate/20120126214447_add_projects_count_to_groups.rb +++ b/db/migrate/20120126214447_add_projects_count_to_groups.rb @@ -9,6 +9,6 @@ class AddProjectsCountToGroups < ActiveRecord::Migration end def self.down - remove_column :groups, :projects_count + remove_column :groups, :own_projects_count end end