Merge branch 'master' into file-store-4_git_task

This commit is contained in:
Pavel Chipiga 2012-09-18 22:02:37 +03:00
commit faafd7a5dc
118 changed files with 1912 additions and 1043 deletions

1
.gitignore vendored
View File

@ -1,3 +1,4 @@
*~
.bundle
.rvmrc
.DS_Store

12
Gemfile
View File

@ -1,6 +1,6 @@
source 'http://rubygems.org'
gem 'rails', '3.2.7' #, :git => 'git://github.com/rails/rails.git'
gem 'rails', '3.2.8' #, :git => 'git://github.com/rails/rails.git'
gem 'pg', '~> 0.14.0'
# gem 'silent-postgres', :git => 'git://github.com/dolzenko/silent-postgres.git' #'~> 0.1.1'
@ -25,13 +25,13 @@ gem 'state_machine'
# gem 'rugged', '~> 0.16.0'
gem 'grack', :git => 'git://github.com/rdblue/grack.git', :require => 'git_http'
gem "grit", :git => 'git://github.com/warpc/grit.git' #, :path => '~/Sites/code/grit'
gem 'charlock_holmes', '~> 0.6.8' #, :git => 'git://github.com/brianmario/charlock_holmes.git', :branch => 'bundle-icu'
gem 'charlock_holmes', '~> 0.6.9' #, :git => 'git://github.com/brianmario/charlock_holmes.git', :branch => 'bundle-icu'
# gem 'ruby-filemagic', '~> 0.4.2', :require => 'filemagic/ext'
gem 'github-linguist', '~> 2.1.2', :require => 'linguist'
gem 'github-linguist', '~> 2.2.1', :require => 'linguist'
gem 'diff-display', '~> 0.0.1'
# Wiki
gem "gollum", :git => 'git://github.com/github/gollum.git'
gem "gollum", '~> 2.1.3'
gem "redcarpet", "1.17.2"
gem 'creole'
gem 'rdiscount'
@ -58,7 +58,7 @@ group :assets do
gem 'coffee-rails', '~> 3.2.2'
gem 'compass-rails', '~> 1.0.3'
gem 'uglifier', '~> 1.2.4'
gem 'therubyracer', '~> 0.10.1', :platforms => [:mri, :rbx]
gem 'therubyracer', '~> 0.10.2', :platforms => [:mri, :rbx]
gem 'therubyrhino', '~> 1.73.1', :platforms => :jruby
end
@ -81,7 +81,7 @@ end
group :test do
gem 'rspec-rails', '~> 2.11.0', :group => 'development'
gem 'factory_girl_rails', '~> 3.6.0'
gem 'factory_girl_rails', '~> 4.0.0'
gem 'rr', '~> 1.0.4'
gem 'shoulda'
end

View File

@ -6,23 +6,6 @@ GIT
redhillonrails_core (2.0.0.pre)
activerecord (>= 3.1.0.rc)
GIT
remote: git://github.com/github/gollum.git
revision: 8422b712048656c8ea391c2d7ef27fb29f66746b
specs:
gollum (2.1.0)
github-markdown
github-markup (>= 0.7.0, < 1.0.0)
grit (~> 2.5.0)
mustache (>= 0.11.2, < 1.0.0)
nokogiri (~> 1.4)
posix-spawn (~> 0.3.0)
pygments.rb (~> 0.2.0)
sanitize (~> 2.0.0)
sinatra (~> 1.0)
stringex (~> 1.4.0)
useragent (~> 0.4.9)
GIT
remote: git://github.com/rdblue/grack.git
revision: 020be3fef3fb308b9d214252522aa5945bf6584a
@ -42,12 +25,12 @@ GEM
remote: http://rubygems.org/
specs:
RedCloth (4.2.9)
actionmailer (3.2.7)
actionpack (= 3.2.7)
actionmailer (3.2.8)
actionpack (= 3.2.8)
mail (~> 2.4.4)
actionpack (3.2.7)
activemodel (= 3.2.7)
activesupport (= 3.2.7)
actionpack (3.2.8)
activemodel (= 3.2.8)
activesupport (= 3.2.8)
builder (~> 3.0.0)
erubis (~> 2.7.0)
journey (~> 1.0.4)
@ -55,18 +38,18 @@ GEM
rack-cache (~> 1.2)
rack-test (~> 0.6.1)
sprockets (~> 2.1.3)
activemodel (3.2.7)
activesupport (= 3.2.7)
activemodel (3.2.8)
activesupport (= 3.2.8)
builder (~> 3.0.0)
activerecord (3.2.7)
activemodel (= 3.2.7)
activesupport (= 3.2.7)
activerecord (3.2.8)
activemodel (= 3.2.8)
activesupport (= 3.2.8)
arel (~> 3.0.2)
tzinfo (~> 0.3.29)
activeresource (3.2.7)
activemodel (= 3.2.7)
activesupport (= 3.2.7)
activesupport (3.2.7)
activeresource (3.2.8)
activemodel (= 3.2.8)
activesupport (= 3.2.8)
activesupport (3.2.8)
i18n (~> 0.6)
multi_json (~> 1.0)
airbrake (3.1.2)
@ -92,9 +75,9 @@ GEM
net-ssh (>= 2.0.14)
net-ssh-gateway (>= 1.1.0)
capistrano_colors (0.5.5)
charlock_holmes (0.6.8)
charlock_holmes (0.6.9)
chronic (0.6.7)
chunky_png (1.2.5)
chunky_png (1.2.6)
cocaine (0.2.1)
coffee-rails (3.2.2)
coffee-script (>= 2.2.0)
@ -125,21 +108,33 @@ GEM
execjs (1.4.0)
multi_json (~> 1.0)
expression_parser (0.9.0)
factory_girl (3.6.0)
factory_girl (4.0.0)
activesupport (>= 3.0.0)
factory_girl_rails (3.6.0)
factory_girl (~> 3.6.0)
factory_girl_rails (4.0.0)
factory_girl (~> 4.0.0)
railties (>= 3.0.0)
ffi (1.0.11)
fssm (0.2.9)
github-linguist (2.1.2)
github-linguist (2.2.1)
charlock_holmes (~> 0.6.6)
escape_utils (~> 0.2.3)
mime-types (~> 1.18)
pygments.rb (>= 0.2.13)
github-markdown (0.5.0)
github-markup (0.7.4)
haml (3.1.6)
gollum (2.1.3)
github-markdown
github-markup (>= 0.7.0, < 1.0.0)
grit (~> 2.5.0)
mustache (>= 0.11.2, < 1.0.0)
nokogiri (~> 1.4)
posix-spawn (~> 0.3.0)
pygments.rb (~> 0.2.0)
sanitize (~> 2.0.0)
sinatra (~> 1.0)
stringex (~> 1.4.0)
useragent (~> 0.4.9)
haml (3.1.7)
haml-rails (0.3.4)
actionpack (~> 3.0)
activesupport (~> 3.0)
@ -150,7 +145,7 @@ GEM
hike (1.2.1)
hirb (0.7.0)
i18n (0.6.0)
jbuilder (0.4.0)
jbuilder (0.4.3)
activesupport (>= 3.0.0)
blankslate (>= 2.1.2.4)
journey (1.0.4)
@ -223,14 +218,14 @@ GEM
rack
rack-test (0.6.1)
rack (>= 1.0)
rails (3.2.7)
actionmailer (= 3.2.7)
actionpack (= 3.2.7)
activerecord (= 3.2.7)
activeresource (= 3.2.7)
activesupport (= 3.2.7)
rails (3.2.8)
actionmailer (= 3.2.8)
actionpack (= 3.2.8)
activerecord (= 3.2.8)
activeresource (= 3.2.8)
activesupport (= 3.2.8)
bundler (~> 1.0)
railties (= 3.2.7)
railties (= 3.2.8)
rails-backbone (0.7.2)
coffee-script (~> 2.2.0)
ejs (~> 1.0.0)
@ -239,9 +234,9 @@ GEM
railties (>= 3.0.0)
rails3-jquery-autocomplete (1.0.7)
rails (~> 3.0)
railties (3.2.7)
actionpack (= 3.2.7)
activesupport (= 3.2.7)
railties (3.2.8)
actionpack (= 3.2.8)
activesupport (= 3.2.8)
rack-ssl (~> 1.3.2)
rake (>= 0.8.7)
rdoc (~> 3.4)
@ -253,7 +248,7 @@ GEM
json (~> 1.4)
redcarpet (1.17.2)
redis (3.0.1)
redis-namespace (1.2.0)
redis-namespace (1.2.1)
redis (~> 3.0.0)
redisk (0.2.2)
redis (>= 0.1.1)
@ -277,7 +272,7 @@ GEM
rspec-core (2.11.1)
rspec-expectations (2.11.2)
diff-lcs (~> 1.1.3)
rspec-mocks (2.11.1)
rspec-mocks (2.11.2)
rspec-rails (2.11.0)
actionpack (>= 3.0)
activesupport (>= 3.0)
@ -296,7 +291,7 @@ GEM
capistrano (>= 2.0.0)
sanitize (2.0.3)
nokogiri (>= 1.4.4, < 1.6)
sass (3.1.20)
sass (3.2.0)
sass-rails (3.2.5)
railties (~> 3.2.0)
sass (>= 3.1.10)
@ -324,19 +319,19 @@ GEM
state_machine (1.1.2)
stringex (1.4.0)
systemu (2.5.2)
therubyracer (0.10.1)
therubyracer (0.10.2)
libv8 (~> 3.3.10)
thin (1.4.1)
daemons (>= 1.0.9)
eventmachine (>= 0.12.6)
rack (>= 1.0.0)
thor (0.15.4)
thor (0.16.0)
tilt (1.3.3)
treetop (1.4.10)
polyglot
polyglot (>= 0.3.1)
tzinfo (0.3.33)
uglifier (1.2.6)
uglifier (1.2.7)
execjs (>= 0.3.0)
multi_json (~> 1.3)
unicorn (4.3.1)
@ -370,15 +365,15 @@ DEPENDENCIES
cape
capistrano
capistrano_colors
charlock_holmes (~> 0.6.8)
charlock_holmes (~> 0.6.9)
coffee-rails (~> 3.2.2)
compass-rails (~> 1.0.3)
creole
devise (~> 2.1.2)
diff-display (~> 0.0.1)
factory_girl_rails (~> 3.6.0)
github-linguist (~> 2.1.2)
gollum!
factory_girl_rails (~> 4.0.0)
github-linguist (~> 2.2.1)
gollum (~> 2.1.3)
grack!
grit!
haml-rails (~> 0.3.4)
@ -394,7 +389,7 @@ DEPENDENCIES
paperclip (~> 3.1.4)
perform_later (~> 1.3.0)
pg (~> 0.14.0)
rails (= 3.2.7)
rails (= 3.2.8)
rails-backbone (~> 0.7.2)
rails3-generators
rails3-jquery-autocomplete (~> 1.0.7)
@ -413,7 +408,7 @@ DEPENDENCIES
shotgun
shoulda
state_machine
therubyracer (~> 0.10.1)
therubyracer (~> 0.10.2)
therubyrhino (~> 1.73.1)
trinidad (~> 1.0.2)
uglifier (~> 1.2.4)

View File

@ -0,0 +1,23 @@
Rosa.Views.ProjectModifyView = Backbone.View.extend({
initialize: function() {
_.bindAll(this, 'checkboxClick');
this.$checkbox_wrapper = $('#niceCheckbox1');
this._$checkbox = this.$checkbox_wrapper.children('#project_is_package').first();
this.$maintainer_form = $('#maintainer_form');
this.$checkbox_wrapper.on('click', this.checkboxClick);
},
checkboxClick: function() {
if (this._$checkbox.is(':checked')) {
this.$maintainer_form.slideDown();
} else {
this.$maintainer_form.slideUp();
}
},
render: function() {
this.checkboxClick();
}
});

View File

@ -1,32 +1,32 @@
function changeCheck(el) {
var el = el, input = el.find('input[type="checkbox"]');
if(input.attr("checked")) {
el.css('backgroundPosition', '0 0');
input.removeAttr('checked');
} else {
el.css('backgroundPosition', '0 -18px');
input.attr('checked', true);
}
return true;
}
function startChangeCheck(el) {
var el = el, input = el.find('input[type="checkbox"]');
if(input.attr('checked')) {
el.css('backgroundPosition', '0 -18px');
}
return true;
}
$(document).ready(function(){
$('.niceCheck-main').each(function(i,el) {
startChangeCheck($(el));
});
$('.niceCheck-main').click(function() {
changeCheck($(this));
});
});
function changeCheck(el) {
var input = el.find('input[type="checkbox"]');
if(input.attr("checked")) {
el.css('backgroundPosition', '0 0');
input.removeAttr('checked');
} else {
el.css('backgroundPosition', '0 -18px');
input.attr('checked', true);
}
return true;
}
function startChangeCheck(el) {
var input = el.find('input[type="checkbox"]');
if(input.attr('checked')) {
el.css('backgroundPosition', '0 -18px');
}
return true;
}
$(document).ready(function(){
$('.niceCheck-main').each(function(i,el) {
startChangeCheck($(el));
});
$('.niceCheck-main').click(function() {
changeCheck($(this));
});
});

View File

@ -1,102 +1,47 @@
$(document).ready(function() {
// TODO: Refactor this handler!! It's too complicated.
$('#build_list_save_to_platform_id').change(function() {
var platform_id = $(this).val();
var base_platforms = $('.all_platforms input[type=checkbox].build_bpl_ids');
$('#build_list_save_to_repository_id').change(function() {
var selected_option = $(this).find("option:selected");
base_platforms.each(function(){
if ($.inArray(platform_id, base_platforms.map(function(){ return $(this).val(); }).get()) >= 0) {
if ($(this).val() == platform_id) {
if ($(this).attr('data-released') === '1') {
$('#build_list_auto_publish').removeAttr('checked').attr('disabled', 'disabled');
//disableUpdateTypes();
} else {
$('#build_list_auto_publish').removeAttr('disabled').attr('checked', 'checked');
//enableUpdateTypes();
}
var platform_id = selected_option.attr('platform_id');
var rep_name = selected_option.text().match(/[\w-]+\/([\w-]+)/)[1];
$(this).attr('checked', 'checked').removeAttr('disabled').trigger('change');
$(this).parent().find('.offset25 input[type="checkbox"]').removeAttr('disabled');
var rep_name = $('#build_list_save_to_platform_id option[value="' + $(this).val() + '"]').text().match(/[\w-]+\/([\w-]+)/)[1];
if (rep_name != 'main') {
$(this).parent().find('.offset25 input[type="checkbox"][rep_name="' + rep_name + '"]').attr('checked', 'checked');
}
$(this).parent().find('.offset25 input[type="checkbox"][rep_name="main"]').attr('checked', 'checked');
} else {
$(this).removeAttr('checked').attr('disabled', 'disabled').trigger('change');
$(this).parent().find('.offset25 input[type="checkbox"]').attr('disabled', 'disabled').removeAttr('checked');
}
} else {
$(this).removeAttr('disabled').removeAttr('checked').trigger('change');
$(this).parent().find('.offset25 input[type="checkbox"]').removeAttr('disabled').removeAttr('checked');
$('#build_list_auto_publish').removeAttr('disabled').attr('checked', 'checked');
var build_platform = $('#build_for_pl_' + platform_id);
var all_repositories = $('.all_platforms input');
all_repositories.removeAttr('checked');
if (build_platform.size() == 0) {
all_repositories.removeAttr('disabled');
} else {
all_repositories.attr('disabled', 'disabled');
var parent = build_platform.parent();
parent.find('input').removeAttr('disabled');
parent.find('input[rep_name="main"]').attr('checked', 'checked');
if (rep_name != 'main') {
parent.find('input[rep_name="' + rep_name + '"]').attr('checked', 'checked');
}
});
if ($.inArray(platform_id, base_platforms.map(function(){ return $(this).val(); }).get()) === -1) {
// For personal platforms update types always enebaled:
enableUpdateTypes();
setBranchSelected(selected_option);
}
var build_list_auto_publish = $('#build_list_auto_publish');
if (selected_option.attr('publish_without_qa') == '1') {
build_list_auto_publish.removeAttr('disabled').attr('checked', 'checked');
} else {
build_list_auto_publish.removeAttr('checked').attr('disabled', 'disabled');
}
setBranchSelected();
});
$('#build_list_save_to_platform_id').trigger('change');
$('.offset25 label').click(function() {
setPlChecked($(this).prev()[0], !$(this).prev().attr('checked'));
});
$('.offset25 input[type="checkbox"]').click(function() {
setPlChecked(this, $(this).attr('checked'));
});
$('.build_bpl_ids').click(function() {
return false;
});
$('#build_list_save_to_repository_id').trigger('change');
});
function setPlChecked(pointer, checked) {
var pl_cbx = $(pointer).parent().parent().parent().find('input[type="checkbox"].build_bpl_ids');
var pl_id = pl_cbx.val();
if (checked && !$(pointer).attr('disabled')) {
pl_cbx.attr('checked', 'checked').trigger('change');
} else if ($('input[pl_id=' + pl_id + '][checked="checked"]').size() === 0) {
pl_cbx.removeAttr('checked').trigger('change');
function setBranchSelected(selected_option) {
var pl_name = selected_option.text().match(/([\w-.]+)\/[\w-.]+/)[1];
var bl_version_sel = $('#build_list_project_version');
var branch_pl_opt = bl_version_sel.find('option[value="latest_' + pl_name + '"]');
// If there is branch we need - set it selected:
if (branch_pl_opt.size() > 0) {
bl_version_sel.find('option[selected]').removeAttr('selected');
branch_pl_opt.attr('selected', 'selected');
bl_version_sel.val(branch_pl_opt);
// hack for FF to force render of select box.
bl_version_sel[0].innerHTML = bl_version_sel[0].innerHTML;
}
}
function setBranchSelected() {
var pl_id = $('#build_list_save_to_platform_id').val();
// Checks if selected platform is main or not:
if ( $('.all_platforms').find('input[type="checkbox"][value=' + pl_id + '].build_bpl_ids').size() > 0 ) {
var pl_name = $('#build_list_save_to_platform_id option[value="' + pl_id + '"]').text().match(/([\w-.]+)\/[\w-.]+/)[1];
var branch_pl_opt = $('#build_list_project_version option[value="latest_' + pl_name + '"]');
// If there is branch we need - set it selected:
if ( branch_pl_opt.size() > 0 ) {
$('#build_list_project_version option[selected]').removeAttr('selected');
branch_pl_opt.attr('selected', 'selected');
var bl_version_sel = $('#build_list_project_version');
bl_version_sel.val(branch_pl_opt);
// hack for FF to force render of select box.
bl_version_sel[0].innerHTML = bl_version_sel[0].innerHTML;
}
}
}
function disableUpdateTypes() {
$("select#build_list_update_type option").each(function(i,el) {
if ( $.inArray($(el).attr("value"), ["security", "bugfix"]) == -1 ) {
$(el).attr("disabled", "disabled");
// If disabled option is selected - select 'bugfix':
if ( $(el).attr("selected") ) {
$( $('select#build_list_update_type option[value="bugfix"]') ).attr("selected", "selected");
}
}
});
}
function enableUpdateTypes() {
$("select#build_list_update_type option").removeAttr("disabled");
}

View File

@ -1152,19 +1152,19 @@ form.mass_build section.right {
}
/* remove this lines after change to backbone */
table.tablesorter.advisories thead tr.search th {
table.tablesorter.static-search thead tr.search th {
padding: 0 5px;
}
table.tablesorter.advisories thead tr.search th input[type='text'] {
table.tablesorter.static-search thead tr.search th input[type='text'] {
width: 640px;
}
table.tablesorter.advisories thead tr.search th form {
table.tablesorter.static-search thead tr.search th form {
float: left;
}
table.tablesorter.advisories thead tr.search th form.button_to {
table.tablesorter.static-search thead tr.search th form.button_to {
padding: 3px 0 0 7px;
}
@ -1481,3 +1481,13 @@ div.log-wrapper {
}
}
}
table.tablesorter.platform-maintainers.static-search thead tr.search th input[type="text"] {
width: 430px;
}
.all_platforms {
> .both { margin: 0 0 5px; }
.build_for_pl { font-weight: bold; }
.offset25 { padding-left: 10px }
}

View File

@ -828,11 +828,11 @@ article div.activity div.fulltext.view {
margin: 0px 0px 10px 0px;
}
.right div.rightlist div.check {
div.rightlist div.check {
float: left;
}
.right div.rightlist div.forcheck {
div.rightlist div.forcheck {
float: left;
margin: 1px 0px 0px 5px;
}

View File

@ -10,7 +10,7 @@ class Groups::ProfileController < Groups::BaseController
end
def show
@projects = @group.projects #.paginate(:page => params[:project_page], :per_page => 10)
@projects = @group.projects.by_visibilities(['open'])
end
def new

View File

@ -9,11 +9,11 @@ class PagesController < ApplicationController
def tour_inside
@entries = case params[:id]
when 'projects'
when 'builds'
%w(repo builds monitoring)
when 'sources'
%w(source history annotation edit)
when 'builds'
when 'projects'
%w(control git tracker)
end
render "pages/tour/tour-inside", :layout => 'tour'

View File

@ -0,0 +1,15 @@
# -*- encoding : utf-8 -*-
class Platforms::MaintainersController < ApplicationController
before_filter :authenticate_user!
skip_before_filter :authenticate_user!, :only => [:index] if APP_CONFIG['anonymous_access']
load_and_authorize_resource :platform
def index
@maintainers = BuildList::Package.actual.by_platform(@platform)
.order('lower(name) ASC, length(name) ASC')
.includes(:project)
@maintainers = @maintainers.where('name ILIKE ?', "%#{params[:q]}%") if params[:q].present?
@maintainers = @maintainers.paginate(:page => params[:page])
end
end

View File

@ -2,7 +2,7 @@
class Platforms::PlatformsController < Platforms::BaseController
before_filter :authenticate_user!
skip_before_filter :authenticate_user!, :only => [:advisories] if APP_CONFIG['anonymous_access']
skip_before_filter :authenticate_user!, :only => [:advisories, :members, :show] if APP_CONFIG['anonymous_access']
load_and_authorize_resource
autocomplete :user, :uname
@ -86,33 +86,23 @@ class Platforms::PlatformsController < Platforms::BaseController
end
def remove_members
all_user_ids = params['user_remove'].inject([]) {|a, (k, v)| a << k if v.first == '1'; a}
all_user_ids.each do |uid|
Relation.by_target(@platform).where(:actor_id => uid, :actor_type => 'User').each{|r| r.destroy}
end
user_ids = params[:user_remove] ?
params[:user_remove].map{ |k, v| k if v.first == '1' }.compact : []
User.where(:id => user_ids).each{ |user| @platform.remove_member(user) }
redirect_to members_platform_path(@platform)
end
def remove_member
u = User.find(params[:member_id])
Relation.by_actor(u).by_target(@platform).each{|r| r.destroy}
User.where(:id => params[:member_id]).each{ |user| @platform.remove_member(user) }
redirect_to members_platform_path(@platform)
end
def add_member
if params[:member_id].present?
member = User.find(params[:member_id])
if @platform.relations.exists?(:actor_id => member.id, :actor_type => member.class.to_s) or @platform.owner == member
flash[:warning] = t('flash.platform.members.already_added', :name => member.uname)
if member = User.where(:id => params[:member_id]).first
if @platform.add_member(member)
flash[:notice] = t('flash.platform.members.successfully_added', :name => member.uname)
else
rel = @platform.relations.build(:role => 'admin')
rel.actor = member
if rel.save
flash[:notice] = t('flash.platform.members.successfully_added', :name => member.uname)
else
flash[:error] = t('flash.platform.members.error_in_adding', :name => member.uname)
end
flash[:error] = t('flash.platform.members.error_in_adding', :name => member.uname)
end
end
redirect_to members_platform_url(@platform)

View File

@ -23,7 +23,7 @@ class Platforms::ProductBuildListsController < Platforms::BaseController
end
def destroy
if @product_build_list.destroy
if @product_build_list.destroy
flash[:notice] = t('flash.product_build_list.delete')
else
flash[:error] = t('flash.product_build_list.delete_error')

View File

@ -1,7 +1,8 @@
# -*- encoding : utf-8 -*-
class Platforms::ProductsController < Platforms::BaseController
before_filter :authenticate_user!
skip_before_filter :authenticate_user!, :only => [:index, :show] if APP_CONFIG['anonymous_access']
load_and_authorize_resource :platform
load_and_authorize_resource :product, :through => :platform

View File

@ -1,9 +1,11 @@
# -*- encoding : utf-8 -*-
class Platforms::RepositoriesController < Platforms::BaseController
before_filter :authenticate_user!
skip_before_filter :authenticate_user!, :only => [:index, :show, :projects_list] if APP_CONFIG['anonymous_access']
load_and_authorize_resource :platform
load_and_authorize_resource :repository, :through => :platform, :shallow => true
before_filter :set_members, :only => [:edit, :update]
def index
@repositories = @repositories.paginate(:page => params[:page])
@ -14,6 +16,46 @@ class Platforms::RepositoriesController < Platforms::BaseController
@projects = @projects.search(params[:query]).search_order if params[:query].present?
end
def edit
end
def update
if @repository.update_attributes(
:description => params[:repository][:description],
:publish_without_qa => (params[:repository][:publish_without_qa] || @repository.publish_without_qa)
)
flash[:notice] = I18n.t("flash.repository.updated")
redirect_to platform_repository_path(@platform, @repository)
else
flash[:error] = I18n.t("flash.repository.update_error")
flash[:warning] = @repository.errors.full_messages.join('. ')
render :action => :edit
end
end
def remove_members
user_ids = params[:user_remove] ?
params[:user_remove].map{ |k, v| k if v.first == '1' }.compact : []
User.where(:id => user_ids).each{ |user| @repository.remove_member(user) }
redirect_to edit_platform_repository_path(@platform, @repository)
end
def remove_member
User.where(:id => params[:member_id]).each{ |user| @repository.remove_member(user) }
redirect_to edit_platform_repository_path(@platform, @repository)
end
def add_member
if member = User.where(:id => params[:member_id]).first
if @repository.add_member(member)
flash[:notice] = t('flash.repository.members.successfully_added', :name => member.uname)
else
flash[:error] = t('flash.repository.members.error_in_adding', :name => member.uname)
end
end
redirect_to edit_platform_repository_path(@platform, @repository)
end
def new
@repository = Repository.new
@platform_id = params[:platform_id]
@ -94,4 +136,10 @@ class Platforms::RepositoriesController < Platforms::BaseController
redirect_to platform_repository_path(@platform, @repository), :notice => t('flash.repository.project_removed')
end
protected
def set_members
@members = @repository.members.order('name')
end
end

View File

@ -44,15 +44,18 @@ class Projects::BuildListsController < Projects::BaseController
def create
notices, errors = [], []
@platform = Platform.includes(:repositories).find params[:build_list][:save_to_platform_id]
@repository = Repository.find params[:build_list][:save_to_repository_id]
@platform = @repository.platform
@repository = @project.repositories.where(:id => @platform.repository_ids).first
params[:build_list][:save_to_platform_id] = @platform.id
params[:build_list][:auto_publish] = false unless @repository.publish_without_qa?
params[:build_list][:save_to_repository_id] = @repository.id
params[:build_list][:auto_publish] = false if @platform.released
build_for_platforms = Repository.select(:platform_id).
where(:id => params[:build_list][:include_repos]).group(:platform_id).map(&:platform_id)
Arch.where(:id => params[:arches]).each do |arch|
Platform.main.where(:id => params[:build_for_platforms]).each do |build_for_platform|
Platform.main.where(:id => build_for_platforms).each do |build_for_platform|
@build_list = @project.build_lists.build(params[:build_list])
@build_list.commit_hash = @project.repo.commits(@build_list.project_version.match(/^latest_(.+)/).to_a.last ||
@build_list.project_version).first.id if @build_list.project_version

View File

@ -4,7 +4,7 @@ class Projects::CommentsController < Projects::BaseController
load_and_authorize_resource :project
before_filter :find_commentable
before_filter :find_or_build_comment
load_and_authorize_resource
load_and_authorize_resource #:through => :commentable
include CommentsHelper

View File

@ -5,9 +5,7 @@ class Projects::ProjectsController < Projects::BaseController
def index
@projects = Project.accessible_by(current_ability, :membered)
# @projects = @projects.search(params[:query]).search_order if params[:query].present?
#puts prepare_list(@projects).inspect
respond_to do |format|
format.html { @projects = @projects.recent.paginate(:page => params[:page], :per_page => 25) }
format.json { @projects = prepare_list(@projects) }
@ -39,6 +37,7 @@ class Projects::ProjectsController < Projects::BaseController
end
def update
params[:project].delete(:maintainer_id) if params[:project][:maintainer_id].blank?
if @project.update_attributes(params[:project])
flash[:notice] = t('flash.project.saved')
redirect_to @project
@ -86,6 +85,14 @@ class Projects::ProjectsController < Projects::BaseController
redirect_to projects_path
end
def autocomplete_maintainers
term, limit = params[:term], params[:limit] || 10
items = User.member_of_project(@project)
.where("users.name ILIKE ? OR users.uname ILIKE ?", "%#{term}%", "%#{term}%")
.limit(limit).map { |u| {:value => u.fullname, :label => u.fullname, :id => u.id} }
render :json => items
end
protected
def prepare_list(projects)

View File

@ -5,7 +5,6 @@ class SearchController < ApplicationController
def index
params[:type] ||= 'all'
params[:type] = 'projects' unless current_user
case params[:type]
when 'all'
find_collection('projects')

View File

@ -3,8 +3,6 @@ class Users::ProfileController < Users::BaseController
autocomplete :user, :uname
def show
@groups = @user.groups.uniq
@platforms = @user.platforms.paginate(:page => params[:platform_page], :per_page => 10)
@projects = @user.projects.paginate(:page => params[:project_page], :per_page => 10)
@projects = @user.projects.by_visibilities(['open'])
end
end

View File

@ -8,6 +8,7 @@ class Users::RegisterRequestsController < ApplicationController
end
def create
params[:register_request][:language] = I18n.locale if params[:register_request]
RegisterRequest.create(params[:register_request])
render :thanks
end

View File

@ -36,8 +36,24 @@ class UserMailer < ActionMailer::Base
end
end
def build_list_notification(build_list, user)
I18n.locale = user.language if user.language
@user, @build_list = user, build_list
subject = "[№ #{build_list.bs_id.present? ? build_list.bs_id : t("layout.build_lists.bs_id_not_set")}] "
subject << (build_list.project ? build_list.project.name_with_owner : t("layout.projects.unexisted_project"))
subject << " - #{build_list.human_status} "
subject << I18n.t("notifications.subjects.for_arch", :arch => @build_list.arch.name)
mail(:to => user.email, :subject => subject) do |format|
format.html
end
end
def invite_approve_notification(register_request)
I18n.locale = register_request.language if register_request.language
@register_request = register_request
mail :to => register_request.email, :subject => I18n.t("notifications.subjects.invite_approve_notification")
mail :to => register_request.email, :subject => I18n.t("notifications.subjects.invite_approve_notification") do |format|
format.html
end
end
end

View File

@ -13,17 +13,21 @@ class Ability
@user = user
# Shared rights between guests and registered users
can :show, Project, :visibility => 'open'
can :archive, Project, :visibility => 'open'
can [:show, :archive], Project, :visibility => 'open'
can :read, Issue, :project => {:visibility => 'open'}
can :search, BuildList
can [:read, :log, :everything], BuildList, :project => {:visibility => 'open'}
can :read, ProductBuildList#, :product => {:platform => {:visibility => 'open'}} # double nested hash don't work
can :read, Advisory
can(:advisories, Platform) {APP_CONFIG['anonymous_access']}
# Core callbacks
can [:publish_build, :status_build, :pre_build, :post_build, :circle_build, :new_bbdt], BuildList
# Platforms block
can [:show, :members, :advisories], Platform, :visibility == 'open'
can [:read, :projects_list], Repository, :platform => {:visibility => 'open'}
can :read, Product, :platform => {:visibility => 'open'}
if user.guest? # Guest rights
# can [:new, :create], RegisterRequest
else # Registered user rights
@ -55,7 +59,7 @@ class Ability
can [:read, :archive], Project, :owner_type => 'Group', :owner_id => user.group_ids
can([:read, :membered], Project, read_relations_for('projects')) {|project| local_reader? project}
can(:write, Project) {|project| local_writer? project} # for grack
can([:update, :sections, :manage_collaborators], Project) {|project| local_admin? project}
can([:update, :sections, :manage_collaborators, :autocomplete_maintainers], Project) {|project| local_admin? project}
can(:fork, Project) {|project| can? :read, project}
can(:fork, Project) {|project| project.owner_type == 'Group' and can? :update, project.owner}
can(:destroy, Project) {|project| owner? project}
@ -69,37 +73,34 @@ class Ability
can([:create, :update], BuildList) {|build_list| build_list.project.is_package && can?(:write, build_list.project)}
can(:publish, BuildList) do |build_list|
build_list.can_publish? and build_list.save_to_platform.released ? local_admin?(build_list.save_to_platform) : can?(:write, build_list.project)
build_list.can_publish? and build_list.save_to_repository.publish_without_qa ? can?(:write, build_list.project) : local_admin?(build_list.save_to_platform)
end
can(:reject_publish, BuildList) do |build_list|
build_list.can_reject_publish? and build_list.save_to_platform.released and local_admin?(build_list.save_to_platform)
build_list.can_reject_publish? and not build_list.save_to_repository.publish_without_qa and local_admin?(build_list.save_to_platform)
end
can(:cancel, BuildList) {|build_list| build_list.can_cancel? && can?(:write, build_list.project)}
can [:read], Advisory
can [:read, :members], Platform, :visibility => 'open'
can [:read, :owned, :related, :members], Platform, :owner_type => 'User', :owner_id => user.id
can [:read, :related, :members], Platform, :owner_type => 'Group', :owner_id => user.group_ids
can([:read, :related, :members], Platform, read_relations_for('platforms')) {|platform| local_reader? platform}
can([:update, :members], Platform) {|platform| local_admin? platform}
can([:destroy, :members, :add_member, :remove_member, :remove_members] , Platform) {|platform| owner?(platform) || local_admin?(platform) }
can [:autocomplete_user_uname, :read_advisories, :advisories], Platform
can [:autocomplete_user_uname], Platform
can([:failed_builds_list, :create], MassBuild) {|mass_build| (owner?(mass_build.platform) || local_admin?(mass_build.platform)) && mass_build.platform.main? }
can(:cancel, MassBuild) {|mass_build| (owner?(mass_build.platform) || local_admin?(mass_build.platform)) && !mass_build.stop_build && mass_build.platform.main?}
can [:read, :projects_list], Repository, :platform => {:visibility => 'open'}
can [:read, :projects_list], Repository, :platform => {:owner_type => 'User', :owner_id => user.id}
can [:read, :projects_list], Repository, :platform => {:owner_type => 'Group', :owner_id => user.group_ids}
can([:read, :projects_list], Repository, read_relations_for('repositories', 'platforms')) {|repository| local_reader? repository.platform}
can([:create, :update, :projects_list, :add_project, :remove_project], Repository) {|repository| local_admin? repository.platform}
can([:create, :edit, :update, :destroy, :projects_list, :add_project, :remove_project], Repository) {|repository| local_admin? repository.platform}
can([:remove_members, :remove_member, :add_member], Repository) {|repository| owner?(repository.platform) || local_admin?(repository.platform)}
can([:add_project, :remove_project], Repository) {|repository| repository.members.exists?(:id => user.id)}
can(:clear, Platform) {|platform| local_admin?(platform) && platform.personal?}
can([:change_visibility, :settings, :destroy], Repository) {|repository| owner? repository.platform}
can([:change_visibility, :settings, :destroy, :edit, :update], Repository) {|repository| owner? repository.platform}
can([:create, :destroy], KeyPair) {|key_pair| owner?(key_pair.repository.platform) || local_admin?(key_pair.repository.platform)}
can :read, Product, :platform => {:visibility => 'open'}
can :read, Product, :platform => {:owner_type => 'User', :owner_id => user.id, :platform_type => 'main'}
can :read, Product, :platform => {:owner_type => 'Group', :owner_id => user.group_ids, :platform_type => 'main'}
can(:read, Product, read_relations_for('products', 'platforms')) {|product| product.platform.main?}
@ -119,13 +120,13 @@ class Ability
cannot :manage, Issue, :project => {:has_issues => false} # switch off issues
can(:create, Comment) {|comment| can? :read, comment.project}
can(:update, Comment) {|comment| comment.user_id == user.id or local_admin?(comment.project || comment.commentable.project)}
can(:update, Comment) {|comment| comment.user == user or comment.project.owner == user or local_admin?(comment.project)}
cannot :manage, Comment, :commentable_type => 'Issue', :commentable => {:project => {:has_issues => false}} # switch off issues
end
# Shared cannot rights for all users (registered, admin)
cannot :destroy, Platform, :platform_type => 'personal'
cannot [:create, :destroy, :add_project, :remove_project], Repository, :platform => {:platform_type => 'personal'}
cannot [:create, :destroy, :edit, :update, :add_project, :remove_project], Repository, :platform => {:platform_type => 'personal'}
cannot :clear, Platform, :platform_type => 'main'
cannot :destroy, Issue

View File

@ -79,7 +79,7 @@ class BuildList < ActiveRecord::Base
scope :recent, order("#{table_name}.updated_at DESC")
scope :for_status, lambda {|status| where(:status => status) }
scope :for_user, lambda { |user| where(:user_id => user.id) }
scope :for_platform, lambda { |platform| where(:build_for_platform_id => platform.id) }
scope :for_platform, lambda { |platform| where(:build_for_platform_id => platform) }
scope :by_mass_build, lambda { |mass_build| where(:mass_build_id => mass_build) }
scope :scoped_to_arch, lambda {|arch| where(:arch_id => arch) }
scope :scoped_to_save_platform, lambda {|pl_id| where(:save_to_platform_id => pl_id) }
@ -125,7 +125,7 @@ class BuildList < ActiveRecord::Base
end
end
after_transition :on => :published, :do => :set_version_and_tag
after_transition :on => :published, :do => [:set_version_and_tag, :actualize_packages]
event :place_build do
transition :waiting_for_response => :build_pending, :if => lambda { |build_list|
@ -201,6 +201,19 @@ class BuildList < ActiveRecord::Base
save
end
def actualize_packages
ActiveRecord::Base.transaction do
old_pkgs = self.class.where(:project_id => self.project_id)
.where(:save_to_repository_id => self.save_to_repository_id)
.for_platform(self.build_for_platform_id)
.scoped_to_arch(self.arch_id)
.for_status(BUILD_PUBLISHED)
.recent.limit(2).last.packages # packages from previous build_list
old_pkgs.update_all(:actual => false)
self.packages.update_all(:actual => true)
end
end
#TODO: Share this checking on product owner.
def can_cancel?
[BUILD_PENDING, BuildServer::PLATFORM_PENDING].include?(status) && bs_id
@ -211,7 +224,7 @@ class BuildList < ActiveRecord::Base
end
def can_reject_publish?
can_publish? and save_to_platform.released
can_publish? and not save_to_repository.publish_without_qa
end

View File

@ -7,6 +7,18 @@ class BuildList::Package < ActiveRecord::Base
attr_accessible :fullname, :name, :release, :version
validates :build_list_id, :project_id, :platform_id, :fullname, :package_type, :name, :release, :version, :presence => true
validates :build_list_id, :project_id, :platform_id, :fullname,
:package_type, :name, :release, :version,
:presence => true
validates :package_type, :inclusion => PACKAGE_TYPES
# Fetches only actual (last publised) packages.
scope :actual, where(:actual => true)
scope :by_platform, lambda {|platform| where(:platform_id => platform) }
scope :by_name, lambda {|name| where(:name => name) }
scope :by_package_type, lambda {|type| where(:package_type => type) }
def assignee
project.maintainer
end
end

View File

@ -1,4 +1,7 @@
class BuildListObserver < ActiveRecord::Observer
PUBLICATION_STATUSES = [BuildList::BUILD_PUBLISHED, BuildList::FAILED_PUBLISH]
STATUSES = [BuildServer::BUILD_ERROR, BuildServer::SUCCESS] + PUBLICATION_STATUSES
observe :build_list
def before_update(record)
@ -15,6 +18,28 @@ class BuildListObserver < ActiveRecord::Observer
record.project.update_attributes({ :average_build_time => new_av_time, :build_count => build_count + 1 }, :without_protection => true)
end
end
BuildListObserver.notify_users(record)
end
end
end # before_update
private
def self.notify_users(build_list)
if !build_list.mass_build_id &&
( (build_list.auto_publish? && PUBLICATION_STATUSES.include?(build_list.status)) ||
(!build_list.auto_publish? && STATUSES.include?(build_list.status)) )
users = []
if build_list.project # find associated users
users = build_list.project.all_members.
select{ |user| user.notifier.can_notify? && user.notifier.new_associated_build? }
end
if build_list.user.notifier.can_notify? && build_list.user.notifier.new_build?
users = users | [build_list.user]
end
users.each do |user|
UserMailer.build_list_notification(build_list, user).deliver
end
end
end # notify_users
end

View File

@ -45,8 +45,8 @@ class MassBuild < ActiveRecord::Base
end
def cancel_all
self.update_attribute(:stop_build, true)
self.build_lists.find_each(:batch_size => 100) do |bl|
update_column(:stop_build, true)
build_lists.find_each(:batch_size => 100) do |bl|
bl.cancel
end
end

View File

@ -28,13 +28,12 @@ class Platform < ActiveRecord::Base
before_create :xml_rpc_create, :unless => lambda {Thread.current[:skip]}
before_destroy :xml_rpc_destroy
after_update :freeze_platform
after_update :freeze_platform_and_update_repos
after_update :update_owner_relation
after_create lambda { symlink_directory unless hidden? }
after_destroy lambda { remove_symlink_directory unless hidden? }
after_update :update_owner_relation
scope :search_order, order("CHAR_LENGTH(name) ASC")
scope :search, lambda {|q| where("name ILIKE ?", "%#{q.to_s.strip}%")}
scope :by_visibilities, lambda {|v| where(:visibility => v)}
@ -74,6 +73,14 @@ class Platform < ActiveRecord::Base
build_path(name)
end
def add_member(member, role = 'admin')
Relation.add_member(member, self, role)
end
def remove_member(member)
Relation.remove_member(member, self)
end
def symlink_path
Rails.root.join("public", "downloads", name)
end
@ -131,11 +138,11 @@ class Platform < ActiveRecord::Base
end
def change_visibility
if !self.hidden?
self.update_attribute(:visibility, 'hidden')
if !hidden?
update_attributes(:visibility => 'hidden')
remove_symlink_directory
else
self.update_attribute(:visibility, 'open')
update_attributes(:visibility => 'open')
symlink_directory
end
end
@ -230,10 +237,11 @@ class Platform < ActiveRecord::Base
end
later :xml_rpc_clone, :loner => true, :queue => :clone_build
def freeze_platform
def freeze_platform_and_update_repos
if released_changed? && released == true
result = BuildServer.freeze(name)
result = BuildServer.freeze(name)
raise "Failed freeze platform #{name} with code #{result}" if result != BuildServer::SUCCESS
repositories.update_all(:publish_without_qa => false)
end
end
end

View File

@ -5,6 +5,7 @@ class Project < ActiveRecord::Base
NAME_REGEXP = /[a-zA-Z0-9_\-\+\.]+/
belongs_to :owner, :polymorphic => true, :counter_cache => :own_projects_count
belongs_to :maintainer, :class_name => "User"
has_many :issues, :dependent => :destroy
has_many :labels, :dependent => :destroy
@ -21,12 +22,15 @@ class Project < ActiveRecord::Base
has_many :packages, :class_name => "BuildList::Package", :dependent => :destroy
has_and_belongs_to_many :advisories # should be without :dependent => :destroy
validates :name, :uniqueness => {:scope => [:owner_id, :owner_type], :case_sensitive => false}, :presence => true, :format => {:with => /^#{NAME_REGEXP}$/, :message => I18n.t("activerecord.errors.project.uname")}
validates :name, :uniqueness => {:scope => [:owner_id, :owner_type], :case_sensitive => false},
:presence => true,
:format => {:with => /^#{NAME_REGEXP}$/, :message => I18n.t("activerecord.errors.project.uname")}
validates :owner, :presence => true
validates :maintainer_id, :presence => true, :unless => :new_record?
validates :visibility, :presence => true, :inclusion => {:in => VISIBILITIES}
validate { errors.add(:base, :can_have_less_or_equal, :count => MAX_OWN_PROJECTS) if owner.projects.size >= MAX_OWN_PROJECTS }
attr_accessible :name, :description, :visibility, :srpm, :is_package, :default_branch, :has_issues, :has_wiki
attr_accessible :name, :description, :visibility, :srpm, :is_package, :default_branch, :has_issues, :has_wiki, :maintainer_id
attr_readonly :name, :owner_id, :owner_type
scope :recent, order("name ASC")
@ -35,9 +39,19 @@ class Project < ActiveRecord::Base
scope :by_name, lambda {|name| where('projects.name ILIKE ?', name)}
scope :by_visibilities, lambda {|v| where(:visibility => v)}
scope :opened, where(:visibility => 'open')
scope :addable_to_repository, lambda { |repository_id| where("projects.id NOT IN (SELECT project_to_repositories.project_id FROM project_to_repositories WHERE (project_to_repositories.repository_id = #{ repository_id }))") }
scope :package, where(:is_package => true)
scope :addable_to_repository, lambda { |repository_id| where %Q(
projects.id NOT IN (
SELECT
ptr.project_id
FROM
project_to_repositories AS ptr
WHERE (ptr.repository_id = #{ repository_id })
)
) }
after_create :attach_to_personal_repository
before_create :set_maintainer
after_save :attach_to_personal_repository
has_ancestry :orphan_strategy => :rootify #:adopt not available yet
@ -62,8 +76,12 @@ class Project < ActiveRecord::Base
name
end
def all_members
members | (owner_type == 'User' ? [owner] : owner.members)
end
def members
collaborators + groups.map(&:members).flatten
collaborators | groups.map(&:members).flatten
end
def platforms
@ -120,6 +138,8 @@ class Project < ActiveRecord::Base
c.parent_id = id
c.owner = new_owner
c.updated_at = nil; c.created_at = nil # :id = nil
# Hack to call protected method :)
c.send :set_maintainer
c.save
end
end
@ -153,6 +173,16 @@ class Project < ActiveRecord::Base
protected
def attach_to_personal_repository
repositories << self.owner.personal_repository if !repositories.exists?(:id => self.owner.personal_repository)
owner_rep = self.owner.personal_repository
if is_package
repositories << owner_rep unless repositories.exists?(:id => owner_rep)
else
repositories.delete owner_rep
end
end
def set_maintainer
self.maintainer_id = (owner_type == 'User') ? self.owner_id : self.owner.owner_id
end
end

View File

@ -1,16 +1,17 @@
# -*- encoding : utf-8 -*-
class RegisterRequest < ActiveRecord::Base
default_scope order('created_at ASC')
scope :rejected, where(:rejected => true)
scope :approved, where(:approved => true)
scope :unprocessed, where(:approved => false, :rejected => false)
validates :email, :presence => true, :uniqueness => {:case_sensitive => false}, :format => { :with => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i }
# before_create :generate_token
before_update :invite_approve_notification
validates :email, :presence => true, :uniqueness => {:case_sensitive => false}, :format => { :with => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i }
def approve
update_attributes(:approved => true, :rejected => false)
end
@ -26,7 +27,7 @@ class RegisterRequest < ActiveRecord::Base
end
def invite_approve_notification
if approved_changed? and approved == true
if approved_changed? && approved?
generate_token
UserMailer.invite_approve_notification(self).deliver
end

View File

@ -10,9 +10,9 @@ class Relation < ActiveRecord::Base
before_validation :add_default_role
scope :by_user_through_groups, lambda {|u| where("actor_type = 'User' AND actor_id = ? OR actor_type = 'Group' AND actor_id IN (?)", u.id, u.group_ids)}
scope :by_actor, lambda {|obj| {:conditions => ['actor_id = ? AND actor_type = ?', obj.id, obj.class.to_s]}}
scope :by_target, lambda {|tar| {:conditions => ['target_id = ? AND target_type = ?', tar.id, tar.class.to_s]}}
scope :by_role, lambda {|role| {:conditions => ['role = ?', role]}}
scope :by_actor, lambda {|obj| where(:actor_id => obj.id, :actor_type => obj.class.to_s)}
scope :by_target, lambda {|tar| where(:target_id => tar.id, :target_type => tar.class.to_s)}
scope :by_role, lambda {|role| where(:role => role)}
def self.create_with_role(actor, target, role)
r = self.new
@ -22,6 +22,20 @@ class Relation < ActiveRecord::Base
r.save
end
def self.add_member(member, target, role)
if target.relations.exists?(:actor_id => member.id, :actor_type => member.class.to_s) || @platform.try(:owner) == member
true
else
rel = target.relations.build(:role => role)
rel.actor = member
rel.save
end
end
def self.remove_member(member, target)
Relation.by_actor(member).by_target(target).each{|r| r.destroy}
end
protected
def add_default_role

View File

@ -2,6 +2,11 @@
class Repository < ActiveRecord::Base
belongs_to :platform
has_many :relations, :as => :target, :dependent => :destroy
has_many :actors, :as => :target, :class_name => 'Relation', :dependent => :destroy
has_many :members, :through => :actors, :source => :actor, :source_type => 'User'
has_many :project_to_repositories, :dependent => :destroy, :validate => true
has_many :projects, :through => :project_to_repositories
has_one :key_pair, :dependent => :destroy
@ -14,7 +19,7 @@ class Repository < ActiveRecord::Base
before_create :xml_rpc_create, :unless => lambda {Thread.current[:skip]}
before_destroy :xml_rpc_destroy, :unless => lambda {Thread.current[:skip]}
attr_accessible :name, :description
attr_accessible :name, :description, :publish_without_qa
attr_readonly :name, :platform_id
def base_clone(attrs = {})
@ -38,6 +43,14 @@ class Repository < ActiveRecord::Base
end
end
def add_member(member, role = 'admin')
Relation.add_member(member, self, role)
end
def remove_member(member)
Relation.remove_member(member, self)
end
class << self
def build_stub(platform)
rep = Repository.new

View File

@ -34,7 +34,7 @@ class Subscribe < ActiveRecord::Base
def self.set_subscribe_to_commit(options, status)
if subscribe = Subscribe.where(options).first
subscribe.update_attribute(:status, status)
subscribe.update_attributes(:status => status)
else
Subscribe.create(options.merge(:status => status))
end

View File

@ -52,6 +52,10 @@ class User < ActiveRecord::Base
scope :admin, where(:role => 'admin')
scope :real, where(:role => ['', nil])
scope :member_of_project, lambda {|item|
where "#{table_name}.id IN (?)", item.members.map(&:id).uniq
}
after_create lambda { self.create_notifier }
before_create :ensure_authentication_token

View File

@ -0,0 +1,43 @@
class MaintainerPresenter < ApplicationPresenter
attr_reader :package, :package_link, :package_name, :package_type,
:package_version, :package_release, :package_version_release,
:package_updated_at
attr_reader :maintainer, :maintainer_fullname, :maintainer_email,
:maintainer_link, :maintainer_mail_link
delegate :package_type, :to => :package
[:name, :version, :release, :updated_at].each do |meth|
define_method "package_#{meth}" do
@package.send meth
end
end
[:fullname, :email].each do |meth|
define_method "maintainer_#{meth}" do
@maintainer.send meth
end
end
def initialize(package, opts = {})
@package = package
@maintainer = package.try(:assignee)
end
def package_link
link_to @package.name, @package.project
end
def package_version_release
"#{@package.version}-#{@package.release}"
end
def maintainer_link
link_to @maintainer.fullname, @maintainer
end
def maintainer_email_link
mail_to @maintainer.email, @maintainer.email, :encode => "javascript"
end
end

View File

@ -1,4 +1,4 @@
%table#myTable.tablesorter.advisories{:cellspacing => "0", :cellpadding => "0"}
%table#myTable.tablesorter.advisories.static-search{:cellspacing => "0", :cellpadding => "0"}
%thead
%tr
%th.th1= t("activerecord.attributes.advisory.advisory_id")

View File

@ -3,7 +3,7 @@
%h3= @group.name
%h4= t("activerecord.attributes.group.description") + ":"
%p= @group.description
%h4= t("layout.groups.projects_list") + ":"
%h4= t("layout.groups.public_projects_list") + ":"
%p
- @projects.each do |project|
= link_to project.name, project

View File

@ -10,13 +10,16 @@
= link_to t("layout.platforms.about"), platform_path(@platform)
%li{:class => (contr == :repositories) ? 'active' : ''}
= link_to t("layout.repositories.list_header"), platform_repositories_path(@platform)
- if can? :show, @platform
%li{:class => (act == :index && contr == :maintainers) ? 'active' : nil}
= link_to t("layout.platforms.maintainers"), platform_maintainers_path(@platform)
- if can? :edit, @platform
%li{:class => (contr == :mass_builds && [:index, :create].include?(act)) ? 'active' : ''}
= link_to t("layout.platforms.mass_build"), platform_mass_builds_path(@platform)
- if can? :read, @platform.products.build
%li{:class => (contr == :products) ? 'active' : ''}
= link_to t("layout.products.list_header"), platform_products_path(@platform)
- if can? :read_advisories, @platform
- if can? :advisories, @platform
%li{:class => (contr == :platforms and act == :advisories) ? 'active' : ''}
= link_to t("layout.advisories.list_header"), advisories_platform_path(@platform)
- if can? :update, @platform

View File

@ -0,0 +1,25 @@
%table#myTable.tablesorter.platform-maintainers.static-search{:cellspacing => "0", :cellpadding => "0"}
%thead
%tr
%th.centered= t("activerecord.attributes.maintainer.package_name")
%th.centered= t("activerecord.attributes.maintainer.package_type")
%th.centered= t("activerecord.attributes.maintainer.version")
%th.centered{:colspan => 2}= t("activerecord.models.maintainer")
%th.centered= t("activerecord.attributes.maintainer.updated_at")
%tr.search
-# TODO: change filter to Backbone.js
%th{:colspan => 6, :rowspan => 1}
= form_tag platform_maintainers_path(@platform), :method => :get do |f|
= text_field_tag('q', params[:q], :placeholder => t("layout.maintainers.search_by_package"), :class => params[:q].present? ? 'black' : 'gray')
%input{:type => 'submit', :value => t("layout.search.header")}
= button_to t('layout.clear'), {:action => :index} , :method => :get
%tbody
- MaintainerPresenter.present_collection(@maintainers) do |pr|
%tr{:class => cycle("odd", "even")}
%td= pr.package_link
%td= pr.package_type
%td= pr.package_version_release
%td= pr.maintainer_link
%td= pr.maintainer_email_link.html_safe
%td= pr.package_updated_at

View File

@ -0,0 +1 @@
doHandleAbfAssignee(<%= @ret.to_json.html_safe %>);

View File

@ -0,0 +1,7 @@
-set_meta_tags :title => [title_object(@platform), t('layout.maintainers.list_header')]
-# FIXME: no these 'base' links!
= render 'platforms/base/submenu'
= render 'platforms/base/sidebar'
= render :partial => 'list', :object => @maintainers
= will_paginate @maintainers

View File

@ -2,42 +2,9 @@
= render 'submenu'
= render 'sidebar'
= form_tag remove_members_platform_path(@platform), :id => 'members_form', :method => :post do
%table.tablesorter{:cellpadding => "0", :cellspacing => "0"}
%thead
%tr
- if can? :remove_members, @platform
%th
\ 
%th
= t("layout.collaborators.members")
- if can? :remove_member, @platform
%th.buttons
= t("layout.remove")
%tbody
- @members.select{|u| u != @platform.owner}.each_with_index do |user, num|
%tr{:id => "admin-table-members-row#{num}", :class => cycle(:odd, :even)}
- if can? :remove_members, @platform
%td
%span.niceCheck-main{:id => "niceCheckbox#{num}", :style => "background-position: 0px 0px; "}
= check_box_tag "user_remove[#{user.id}][]"
%td
.img
= image_tag avatar_url(user)
.forimg= link_to user.fullname, user_path(user)
- if can? :remove_member, @platform
%td.buttons
= link_to remove_member_platform_path(@platform, :member_id => user.id), :method => :delete, :confirm => t("layout.confirm") do
%span.delete &nbsp;
- if can? :remove_memvers, @platforms
= submit_tag t("layout.delete"), :class => 'button'
.both
- if can? :add_member, @platform
.hr.top
= form_tag add_member_platform_path(@platform) do
.admin-search
= autocomplete_field_tag 'member_id', params[:member_id], autocomplete_user_uname_users_path, :id_element => '#member_id_field'
= hidden_field_tag 'member_id', nil, :id => 'member_id_field'
= submit_tag t("layout.add"), :class => 'button'
.both
= render "shared/members_table",
:remove_members_path => remove_members_platform_path(@platform),
:remove_member_path => remove_member_platform_path(@platform),
:add_member_path => add_member_platform_path(@platform),
:members => @members.select{|u| u != @platform.owner},
:editable_object => @platform

View File

@ -1,9 +1,13 @@
.leftlist= f.label :name, t("activerecord.attributes.repository.name"), :class => :label
.rightlist= f.text_field :name, :class => 'text_field'
- unless ['edit', 'update'].include? controller.action_name
.leftlist= f.label :name, t("activerecord.attributes.repository.name"), :class => :label
.rightlist= f.text_field :name, :class => 'text_field'
.leftlist= f.label :description, t("activerecord.attributes.repository.description"), :class => :label
.rightlist= f.text_field :description, :class => 'text_field'
.leftlist= f.label :publish_without_qa, t("activerecord.attributes.repository.publish_without_qa"), :class => :label
.rightlist= f.check_box :publish_without_qa, :class => 'check_box'
.both
.button_block

View File

@ -3,7 +3,7 @@
%tr
%th.th1= t("activerecord.attributes.repository.name")
%th.th2= t("layout.repositories.projects")
%th= t("layout.delete")
%th= t("activerecord.attributes.repository.publish_without_qa")
%tbody
- @repositories.each do |repository|
%tr{:class => cycle("odd", "even")}
@ -11,7 +11,5 @@
= link_to repository.name, platform_repository_path(@platform, repository)
%td
= repository.projects.count
%td.buttons
- if can? :destroy, repository
= link_to platform_repository_path(@platform, repository), :method => :delete, :confirm => t("layout.repositories.confirm_delete") do
%span.delete &nbsp;
%td
= repository.publish_without_qa

View File

@ -0,0 +1,16 @@
-set_meta_tags :title => [title_object(@repository), t('layout.repositories.edit')]
= render 'submenu'
= render 'sidebar'
%h3.fix= "#{t("layout.repositories.about")}: #{@repository.name}"
= form_for @repository, :url => platform_repository_path(@platform, @repository), :html => { :class => :form } do |f|
= render "form", :f => f
%br
= render "shared/members_table",
:remove_members_path => remove_members_platform_repository_path(@platform, @repository),
:remove_member_path => remove_member_platform_repository_path(@platform, @repository),
:add_member_path => add_member_platform_repository_path(@platform, @repository),
:members => @members,
:editable_object => @repository

View File

@ -2,10 +2,15 @@
= render 'submenu'
= render 'sidebar'
%h3.fix= "#{t("layout.repositories.about")}: #{@repository.name}"
%h3 #{t("layout.repositories.about")} #{@repository.name}
%p= @repository.description
.buttons_block
- if can? :update, @repository
= link_to image_tag("code.png", :alt => t("layout.edit")) + " " + t("layout.edit"), edit_platform_repository_path(@platform, @repository), :class => "button"
- if can? :destroy, @repository
= link_to image_tag("x.png", :alt => t("layout.delete")) + " " + t("layout.delete"), platform_repository_path(@platform, @repository), :method => "delete", :class => "button", :confirm => t("layout.repositories.confirm_delete")
%br
%br
%h3.fix= t("layout.projects.list_header")

View File

@ -1,4 +1,4 @@
- platform.repositories.each do |repo|
.both
= check_box_tag "build_list[include_repos][]", repo.id, repo.name == 'main' || @project.repositories.map(&:id).include?(repo.id), :id => "include_repos_#{repo.id}", :save_to_platform_id => platform.id, :rep_name => repo.name
= check_box_tag "build_list[include_repos][]", repo.id, repo.name == 'main' || @project.repositories.map(&:id).include?(repo.id), :id => "include_repos_#{repo.id}", :rep_name => repo.name
= label_tag "include_repos_#{repo.id}", repo.name

View File

@ -6,12 +6,13 @@
- Platform.main.each do |pl|
- if pl.repository_ids.size > 0
.both
= check_box_tag "build_for_platforms[]", pl.id, (params[:build_for_platforms]||[]).include?(pl.id.to_s), :class => 'build_bpl_ids', :id => "bpls_#{pl.id}", :'data-released' => pl.released ? 1 : 0
= label_tag "bpls_#{pl.id}", pl.name
.offset25{:style => 'padding-left: 25px'}= render 'include_repos', :platform => pl
=# check_box_tag "build_for_platforms[]", pl.id, (params[:build_for_platforms]||[]).include?(pl.id.to_s), :class => 'build_bpl_ids', :id => "bpls_#{pl.id}"
=# label_tag "bpls_#{pl.id}", pl.name
%div{:id => "build_for_pl_#{pl.id}", :class => 'build_for_pl'}= pl.name
.offset25= render 'include_repos', :platform => pl
%section.right
%h3= t("activerecord.attributes.build_list.save_to_platform")
.lineForm= f.select :save_to_platform_id, @project.repositories.collect{|r| ["#{r.platform.name}/#{r.name}", r.platform.id]}
%h3= t("activerecord.attributes.build_list.save_to_repository")
.lineForm= f.select :save_to_repository_id, @project.repositories.collect{|r| ["#{r.platform.name}/#{r.name}", r.id, {:publish_without_qa => r.publish_without_qa? ? 1 : 0, :platform_id => r.platform.id}]}
%h3= t("activerecord.attributes.build_list.project_version")
.lineForm= f.select :project_version, versions_for_group_select(@project), :selected => params[:build_list].try(:fetch, :project_version) || "latest_" + @project.default_branch
%h3= t("activerecord.attributes.build_list.arch")

View File

@ -128,10 +128,11 @@
= render :partial => 'projects/build_lists/log'
- if (can_publish = @build_list.can_publish? && can?(:publish, @build_list)) || (can_reject = @build_list.can_reject_publish? && can?(:reject_publish, @build_list))
- if (can_publish = @build_list.can_publish? && can?(:publish, @build_list))
.hr
= submit_tag t("layout.publish"), :confirm => t("layout.confirm"), :name => 'publish' if can_publish
= submit_tag t("layout.reject_publish"), :confirm => t("layout.confirm"), :name => 'reject_publish' if can_reject
- if @build_list.can_reject_publish? && can?(:reject_publish, @build_list)
= submit_tag t("layout.reject_publish"), :confirm => t("layout.confirm"), :name => 'reject_publish'
.hr
%h3= t("layout.build_lists.items_header")

View File

@ -30,7 +30,7 @@
%h3= t("layout.projects.git_global_setup")
%p
%code
= "git config --global user.name #{current_user.fullname}"
= "git config --global user.name '#{current_user.fullname}'"
%br/
= "git config --global user.email #{current_user.email}"
%br/

View File

@ -6,14 +6,12 @@
.leftlist= f.label :description, t("activerecord.attributes.project.description"), :class => :label
.rightlist= f.text_area :description, :class => 'text_field', :cols => 80
.both
- if ['new', 'create'].include? controller.action_name
- if [:new, :create].include? act
.leftlist= f.label :owner_id, t("activerecord.attributes.project.owner"), :class => :label
.rightlist
= label_tag t("activerecord.attributes.project.who_owns.me")
- if Group.can_own_project(current_user).count > 0
= radio_button_tag :who_owns, 'me', @who_owns == :me #{}.merge( (@who_owns == :me) ? {:checked => 'checked'} : {} )
- puts @who_owns.inspect
- puts @who_owns == :group
= label_tag t("activerecord.attributes.project.who_owns.group")
= radio_button_tag :who_owns, 'group', @who_owns == :group #{}.merge( (@who_owns == :group) ? {:checked => 'checked'} : {} )
-# TODO: Make our own select_box helper with new design, blackjack and bitches!
@ -33,19 +31,33 @@
= image_tag("lock.png")
= t("activerecord.attributes.project.visibilities.#{visibility}")
.both
.leftlist
\ 
.rightlist
.check
%span#niceCheckbox1.niceCheck-main= f.check_box :is_package#, :class => 'niceCheckbox1'
.forcheck= t("activerecord.attributes.project.is_package")
.both
.both
- if [:edit, :update].include? act
.leftlist= t("activerecord.attributes.project.default_branch")
.rightlist= f.select :default_branch, options_from_collection_for_select(@project.repo.branches, :name, :name, @project.default_branch), :class => 'sel80', :id => 'branch_selector'
.both
- if [:edit, :update].include? act
.leftlist
\ 
.rightlist
.check
%span#niceCheckbox1.niceCheck-main= f.check_box :is_package#, :class => 'niceCheckbox1'
.forcheck= t("activerecord.attributes.project.is_package")
.both
.both
= f.select :default_branch,
options_from_collection_for_select( @project.repo.branches,
:name, :name, @project.default_branch),
:class => 'sel80', :id => 'branch_selector'
.both
#maintainer_form{:class => @project.is_package ? '' : 'hidden'}
= f.hidden_field :maintainer_id, :value => @project.maintainer_id
.leftlist
= t("activerecord.attributes.project.maintainer")
.rightlist
-# TODO: Maybe use something like Chosen with filter and prepopulated
-# list of potential maintainers?
= autocomplete_field_tag :maintainer_name, @project.maintainer.fullname,
autocomplete_maintainers_path(@project.owner, @project),
:id_element => '#project_maintainer_id',
:placeholder => @project.maintainer.fullname
- if [:new, :create].include? act
.leftlist= f.label :srpm, t("activerecord.attributes.project.srpm"), :class => :label
.rightlist= f.file_field :srpm, :class => 'file_field'
@ -54,3 +66,7 @@
\ 
.rightlist= submit_tag t("layout.save"), :class => 'button'
.both
:javascript
$(function() {
( new Rosa.Views.ProjectModifyView ).render();
});

View File

@ -0,0 +1,39 @@
= form_tag remove_members_path, :id => 'members_form', :method => :post do
%table.tablesorter{:cellpadding => "0", :cellspacing => "0"}
%thead
%tr
- if can? :remove_members, editable_object
%th
\ 
%th
= t("layout.collaborators.members")
- if can? :remove_member, editable_object
%th.buttons
= t("layout.remove")
%tbody
- members.each_with_index do |user, num|
%tr{:id => "admin-table-members-row#{num}", :class => cycle(:odd, :even)}
- if can? :remove_members, editable_object
%td
%span.niceCheck-main{:id => "niceCheckbox#{num}", :style => "background-position: 0px 0px; "}
= check_box_tag "user_remove[#{user.id}][]"
%td
.img
= image_tag avatar_url(user)
.forimg= link_to user.fullname, user_path(user)
- if can? :remove_member, editable_object
%td.buttons
= link_to "#{remove_member_path}?member_id=#{user.id}", :method => :delete, :confirm => t("layout.confirm") do
%span.delete &nbsp;
- if can? :remove_memvers, editable_object
= submit_tag t("layout.delete"), :class => 'button'
.both
- if can? :add_member, editable_object
.hr.top
= form_tag add_member_path do
.admin-search
= autocomplete_field_tag 'member_id', params[:member_id], autocomplete_user_uname_users_path, :id_element => '#member_id_field'
= hidden_field_tag 'member_id', nil, :id => 'member_id_field'
= submit_tag t("layout.add"), :class => 'button'
.both

View File

@ -0,0 +1,15 @@
%p
Build project
- if @build_list.project
= link_to @build_list.project.name_with_owner, project_url(@build_list.project)
- else
= t("layout.projects.unexisted_project")
completed with status
= @build_list.human_status
for arch
= "#{@build_list.arch.name}."
%p
More detailed information you can get by link:
= link_to "task [№ #{@build_list.bs_id ? @build_list.bs_id : t("layout.build_lists.bs_id_not_set")}]", build_list_url(@build_list)
%p== Support team «ROSA Build System»

View File

@ -0,0 +1,15 @@
%p
Сборка проекта
- if @build_list.project
= link_to @build_list.project.name_with_owner, project_url(@build_list.project)
- else
= t("layout.projects.unexisted_project")
завершена со статусом
= @build_list.human_status
для архитектуры
= "#{@build_list.arch.name}."
%p
Более подробную информацию можно получить по ссылке:
= link_to "задание [№ #{@build_list.bs_id ? @build_list.bs_id : t("layout.build_lists.bs_id_not_set")}]", build_list_url(@build_list)
%p== Команда поддержки «ROSA Build System»

View File

@ -0,0 +1,7 @@
%p== Hello, #{@register_request.name || @register_request.email}.
%p
You have been invited to project ABF. Please click on the following link for registration:
= link_to 'link', new_user_registration_url(:invitation_token => @register_request.token)
%p== Support team «ROSA Build System»

View File

@ -6,13 +6,13 @@
%h3= title @user.uname
= @user.name
%br
= link_to @user.email, "mailto:#{@user.email}"
= mail_to @user.email, @user.email, :encode => "javascript"
%br
%h4= t("activerecord.attributes.user.professional_experience") + ":"
%p= @user.professional_experience
%h4= t("layout.users.public_projects_list") + ":"
%p
- @user.projects.by_visibilities(['open']).each do |project|
- @projects.each do |project|
= link_to project.name, project
%br

View File

@ -0,0 +1,3 @@
.leftside.w25= f.check_box field
.leftside= f.label field, t("activerecord.attributes.settings.notifier.#{field}")
.both

View File

@ -7,32 +7,16 @@
%br
= form_for @user.notifier, :url => notifiers_settings_path, :html => {:class => :form} do |f|
.leftside.w25= f.check_box :can_notify
.leftside= f.label :can_notify, t('activerecord.attributes.settings.notifier.can_notify')
.both
= render 'notifier', :f => f, :field => :can_notify
%h3= t("layout.settings.notifiers.code_header")
.leftside.w25= f.check_box :new_comment_commit_owner, :class => 'notify_cbx'
.leftside= f.label :new_comment_commit_owner, t('activerecord.attributes.settings.notifier.new_comment_commit_owner')
.both
.leftside.w25= f.check_box :new_comment_commit_repo_owner, :class => 'notify_cbx'
.leftside= f.label :new_comment_commit_repo_owner, t('activerecord.attributes.settings.notifier.new_comment_commit_repo_owner')
.both
.leftside.w25= f.check_box :new_comment_commit_commentor, :class => 'notify_cbx'
.leftside= f.label :new_comment_commit_commentor, t('activerecord.attributes.settings.notifier.new_comment_commit_commentor')
.both
- [:new_comment_commit_owner, :new_comment_commit_repo_owner, :new_comment_commit_commentor].each do |field|
= render 'notifier', :f => f, :field => field
%h3= t("layout.settings.notifiers.tracker_header")
.leftside.w25= f.check_box :new_comment, :class => 'notify_cbx'
.leftside= f.label :new_comment, t('activerecord.attributes.settings.notifier.new_comment')
.both
.leftside.w25= f.check_box :new_comment_reply, :class => 'notify_cbx'
.leftside= f.label :new_comment_reply, t('activerecord.attributes.settings.notifier.new_comment_reply')
.both
.leftside.w25= f.check_box :new_issue, :class => 'notify_cbx'
.leftside= f.label :new_issue, t('activerecord.attributes.settings.notifier.new_issue')
.both
.leftside.w25= f.check_box :issue_assign, :class => 'notify_cbx'
.leftside= f.label :issue_assign, t('activerecord.attributes.settings.notifier.issue_assign')
.both
- [:new_comment, :new_comment_reply, :new_issue, :issue_assign].each do |field|
= render 'notifier', :f => f, :field => field
%h3= t("layout.settings.notifiers.build_list_header")
- [:new_build, :new_associated_build].each do |field|
= render 'notifier', :f => f, :field => field
%br
.leftside.w25

View File

@ -55,7 +55,7 @@ namespace :deploy do
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 "cp -n #{fetch :release_path}/config/application.yml.sample #{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
@ -101,3 +101,33 @@ namespace :rake_tasks do
mirror_rake_tasks 'db:seeds'
end
end
namespace :update do
desc "Copy remote production shared files to localhost"
task :shared do
run_locally "rsync --recursive --times --rsh=ssh --compress --human-readable --progress #{user}@#{domain}:#{shared_path}/shared_contents/uploads public/uploads"
end
desc "Dump remote production postgresql database, rsync to localhost"
task :postgresql do
get("#{current_path}/config/database.yml", "tmp/database.yml")
remote_settings = YAML::load_file("tmp/database.yml")[rails_env]
local_settings = YAML::load_file("config/database.yml")["development"]
run "export PGPASSWORD=#{remote_settings["password"]} && pg_dump --host=#{remote_settings["host"]} --port=#{remote_settings["port"]} --username #{remote_settings["username"]} --file #{current_path}/tmp/#{remote_settings["database"]}_dump -Fc #{remote_settings["database"]}"
run_locally "rsync --recursive --times --rsh=ssh --compress --human-readable --progress #{user}@#{domain}:#{current_path}/tmp/#{remote_settings["database"]}_dump tmp/"
run_locally "dropdb -U #{local_settings["username"]} --host=#{local_settings["host"]} --port=#{local_settings["port"]} #{local_settings["database"]}"
run_locally "createdb -U #{local_settings["username"]} --host=#{local_settings["host"]} --port=#{local_settings["port"]} -T template0 #{local_settings["database"]}"
run_locally "pg_restore -U #{local_settings["username"]} --host=#{local_settings["host"]} --port=#{local_settings["port"]} -d #{local_settings["database"]} tmp/#{remote_settings["database"]}_dump"
end
desc "Dump all remote data to localhost"
task :all do
# update.shared
update.postgresql
end
end

View File

@ -1,16 +0,0 @@
production:
action_mailer_host: "abf.rosalinux.ru"
root_path: /share
nginx_log: /srv/rosa_build/shared/log/nginx.access.log
do-not-reply-email: do-not-reply@rosalinux.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.144
nau5: 192.168.122.203
product_builder_port: 12554
product_builder_path: /xmlrpc
distr_types: ['mdv']

View File

@ -1,33 +0,0 @@
common: &common
project_name: ABF TEST
repo_project_name: ABF TEST
anonymous_access: false
distr_types: ['mdv', 'nau5']
wiki_formats:
markdown: "Markdown"
textile: "Textile"
# rdoc: "RDoc"
org: "Org-mode"
# creole: "Creole"
# mediawiki: "MediaWiki"
feedback:
email:
- 'test@example.com'
- 'test1@example.com'
production:
<<: *common
action_mailer_host: "195.19.76.241"
root_path: /share
do-not-reply-email: do-not-reply@test.rosalinux.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']

View File

@ -1,23 +0,0 @@
common: &common
project_name: ABF
repo_project_name: ABF
distr_types: ['mdv', 'nau5', 'suse', 'deb']
wiki_formats:
markdown: "Markdown"
textile: "Textile"
org: "Org-mode"
production:
<<: *common
action_mailer_host: "school.rosalab.ru"
root_path: /share
nginx_log: /srv/rosa_build/shared/log/nginx.access.log
do-not-reply-email: do-not-reply@school.rosalab.ru
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

View File

@ -1,16 +0,0 @@
production:
action_mailer_host: "dev-abf.rosalinux.ru"
root_path: /share
nginx_log: /srv/rosa_build/shared/log/nginx.access.log
do-not-reply-email: do-not-reply@dev-abf.rosalinux.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']

View File

@ -57,6 +57,7 @@ en:
change_email_link: Change email address
code_header: Code
tracker_header: Tracker
build_list_header: Build List
devise:
shared_links:
@ -178,6 +179,8 @@ en:
new_comment_commit_owner: Notify about comments to my commit
new_comment_commit_repo_owner: Notify about comments to my repository commits
new_comment_commit_commentor: Notify about comments after my commit
new_build: Notify about my build tasks
new_associated_build: Notify about associated with me build tasks
private_user:
login: Login

View File

@ -18,6 +18,7 @@ en:
new_user_notification: Registered on project «%{ project_name }»
issue_assign_notification: New task assigned
invite_approve_notification: Invitation to ABF
for_arch: for arch %{arch}.
bodies:
new_comment_notification:

View File

@ -18,7 +18,7 @@ ru:
new_user_notification: Регистрация на проекте «%{ project_name }»
issue_assign_notification: Вам назначили задачу
invite_approve_notification: Приглашение в ABF
build_task: Сборочное задание
for_arch: для архитектуры %{arch}.
bodies:
new_comment_notification:

View File

@ -18,8 +18,7 @@ en:
additional_repos: Additional repositories
include_repos: Included repositories
created_at: Created on
save_to_platform: Platform
save_to_repository: Repository
save_to_repository: Save to repository
build_for_platform: Build for platform
update_type: Update type
build_requires: Build with all the required packages
@ -72,7 +71,7 @@ en:
main_data: Main data
human_current_duration: Build currently takes %{hours} h. %{minutes} min.
human_duration: Builded in %{hours} h. %{minutes} min.
human_duration: Built in %{hours} h. %{minutes} min.
attached_advisory: Attached advisory
create_advisory: Create new advisory

View File

@ -18,8 +18,7 @@ ru:
additional_repos: Дополнительные репозитории
include_repos: Подключаемые репозитории
created_at: Создан
save_to_platform: Платформа
save_to_repository: Репозиторий
save_to_repository: Сохранить в репозиторий
build_for_platform: Собрано для платформы
update_type: Критичность обновления
build_requires: Пересборка с зависимостями

View File

@ -16,6 +16,7 @@ en:
description: Descripton
leave_group: Leave group
projects_list: Projects list
public_projects_list: Public projects list
public_profile: Public profile
delete_warning: Attention! Deleted group can not be restored!

View File

@ -16,6 +16,7 @@ ru:
description: Описание
leave_group: Покинуть группу
projects_list: Список проектов
public_projects_list: Список публичных проектов
public_profile: Публичный профиль
delete_warning: Внимание! Удаленная группа восстановлению не подлежит.

View File

@ -0,0 +1,25 @@
en:
layout:
maintainers:
list_header: Maintainers
search_by_package: Search by package name
flash:
maintainer:
saved: Maintainer saved
created: Maintainer created
save_error: Maintainer saves error
create_error: Maintainer create error
destroyed: Maintainer deleted
activerecord:
models:
maintainer: Maintainer
attributes:
maintainer:
package_name: Package
package_type: Type
created_at: First Update
updated_at: Last Update
version: Version-Release

View File

@ -0,0 +1,25 @@
ru:
layout:
maintainers:
list_header: Майнтейнеры
search_by_package: Искать по имени пакета
flash:
maintainer:
saved: Майнтейнер успешно сохранен
created: Майнтейнер успешно добавлен
save_error: Не удалось сохранить майнтейнера
create_error: Не удалось создать майнтейнера
destroyed: Майнтейнер успешно удален
activerecord:
models:
maintainer: Майнтейнер
attributes:
maintainer:
package_name: Пакет
package_type: Тип
created_at: Создан
updated_at: Обновлен
version: Версия-Релиз

View File

@ -40,6 +40,7 @@ en:
target_platform: Target platform
target_architecture: Target architecture
members: Members
maintainers: Maintainers
project: Project
arch: Architecture
mass_build: Mass build
@ -62,7 +63,6 @@ en:
cancel_mass_build: Mass build canceled
clone_success: Cloned successfully
members:
already_added: "%{name} is already a member of platform"
successfully_added: "%{name} successfully added to the platform"
error_in_adding: "Unable to add %{name} as member"

View File

@ -40,6 +40,7 @@ ru:
target_platform: Целевая платформа
target_architecture: Целевая архитектура
members: Участники
maintainers: Майнтейнеры
arch: Архитектура
mass_build: Массовая сборка
build_task: Сборочное задание
@ -62,7 +63,6 @@ ru:
cancel_mass_build: Массовая сборка отменена
clone_success: Клонирование успешно
members:
already_added: "%{name} уже является участником платформы"
successfully_added: "Участник %{name} успешно добавлен к платформе"
error_in_adding: "Не удалось добавить участника %{name}"

View File

@ -10,7 +10,7 @@ en:
'2': 'build in progress'
build_failed: Build failed
build_started: Build in progress
build_completed: Builded
build_completed: Built
ownership:
header: Build list ownership

View File

@ -93,6 +93,8 @@ en:
group: Group
default_branch: Default branch
is_package: Project is a package
maintainer: Maintainer of project
maintainer_id: Maintainer of project
errors:
project:
uname: The name can only use lower case Latin letters (a-z), numbers (0-9) and underscore (_)

View File

@ -93,6 +93,8 @@ ru:
group: Группа
default_branch: Ветка по умолчанию
is_package: Проект является пакетом
maintainer_id: Майнтейнер проекта
maintainer: Майнтейнер проекта
errors:
project:
uname: В имени можно использовать только строчные символы латинского алфавита (a-z), цифры (0-9) и символ нижнего подчеркивания (_)

View File

@ -2,6 +2,7 @@ en:
layout:
repositories:
add_project_to: Add project to repository
edit: Settings
list: List
about: About repository
list_header: Repositories
@ -29,13 +30,18 @@ en:
flash:
repository:
saved: Repository added
updated: Repository updated
save_error: Unable to add repository
update_error: Unable to update repository
destroyed: Repository deleted
project_added: Project added to repository
project_not_added: Project adding error. A project with such name already exists in this repository. Remove the old project first
project_removed: Project deleted
project_not_removed: Unable to delete project from repository
clear: Platform successfully cleared!
members:
successfully_added: "%{name} successfully added to the repository"
error_in_adding: "Unable to add %{name} as member"
activerecord:
models:
@ -44,6 +50,7 @@ en:
repository:
name: Name
description: Description
publish_without_qa: Publication without QA
platform_id: Platform
platform: Platform
created_at: Created

View File

@ -2,6 +2,7 @@ ru:
layout:
repositories:
add_project_to: Добавить проект к репозиторию
edit: Настройки
list: Список
about: О репозитории
list_header: Репозитории
@ -29,13 +30,18 @@ ru:
flash:
repository:
saved: Репозиторий успешно добавлен
updated: Репозиторий успешно обновлен
save_error: Не удалось добавить репозиторий
update_error: Не удалось обновить репозиторий
destroyed: Репозиторий успешно удален
project_added: Проект добавлен к репозиторию
project_not_added: Не удалось добавить проект. В этом репозитории уже есть проект с таким именем. Сначала нужно удалить старый проект
project_removed: Проект удален из репозитория
project_not_removed: Не удалось удалить проект из репозитория
clear: Платформа успешно очищена!
members:
successfully_added: "Участник %{name} успешно добавлен к репозиторию"
error_in_adding: "Не удалось добавить участника %{name}"
activerecord:
models:
@ -44,6 +50,7 @@ ru:
repository:
name: Название
description: Описание
publish_without_qa: Публикация без участия QA
platform_id: Платформа
platform: Платформа
created_at: Создан

View File

@ -57,6 +57,7 @@ ru:
change_email_link: Изменить адрес электронной почты
code_header: Код
tracker_header: Трекер задач
build_list_header: Сборочные задания
devise:
shared_links:
@ -179,6 +180,8 @@ ru:
new_comment_commit_owner: Оповещать о комментариях к моему коммиту
new_comment_commit_repo_owner: Оповещать о комментариях к коммитам в моем репозитории
new_comment_commit_commentor: Оповещать о комментариях к коммиту после моего
new_build: Оповещать о моих сборочных заданиях
new_associated_build: Оповещать о связанных со мной сборочных заданиях
private_user:
login: Логин

View File

@ -56,7 +56,7 @@ Rosa::Application.routes.draw do
post :clear
get :clone
get :members
post :remove_members
post :remove_members # fixme: change post to delete
delete :remove_member
post :add_member
post :make_clone
@ -76,13 +76,16 @@ Rosa::Application.routes.draw do
get :add_project
delete :remove_project
get :projects_list
post :remove_members # fixme: change post to delete
delete :remove_member
post :add_member
end
end
resources :key_pairs, :only => [:create, :index, :destroy]
resources :products do
resources :product_build_lists, :only => [:create, :destroy]
end
resources :maintainers, :only => [:index]
end
match '/private/:platform_name/*file_path' => 'privates#show'
@ -184,6 +187,7 @@ Rosa::Application.routes.draw do
end
end
# Resource
get '/autocomplete_maintainers' => 'projects#autocomplete_maintainers', :as => :autocomplete_maintainers
get '/modify' => 'projects#edit', :as => :edit_project
put '/' => 'projects#update'
delete '/' => 'projects#destroy'

View File

@ -5,7 +5,7 @@ class AddProjectToComment < ActiveRecord::Migration
Subscribe.reset_column_information
Comment.where(:commentable_type => 'Grit::Commit').destroy_all
Comment.where(:commentable_type => 'Issue').each do |comment|
comment.update_attribute(:project_id, comment.commentable.project)
comment.update_column(:project_id, comment.commentable.project.id)
end
end

View File

@ -0,0 +1,5 @@
class AddNamePlatformIndexToBuildListPackages < ActiveRecord::Migration
def change
add_index :build_list_packages, [:name,:project_id]
end
end

View File

@ -0,0 +1,9 @@
class AddMaintainerIdToProjects < ActiveRecord::Migration
def self.up
add_column :projects, :maintainer_id, :integer
end
def self.down
remove_column :projects, :maintainer_id
end
end

View File

@ -0,0 +1,14 @@
class AddActualToBuildListPackages < ActiveRecord::Migration
def self.up
add_column :build_list_packages, :actual, :boolean, :default => false
add_index :build_list_packages, [:actual, :platform_id]
add_index :build_lists, [:project_id, :save_to_repository_id, :build_for_platform_id, :arch_id],
:name => :maintainer_search_index
end
def self.down
remove_index :build_list_packages, [:actual, :platform_id]
remove_column :build_list_packages, :actual
remove_index :build_lists, :name => :maintainer_search_index
end
end

View File

@ -0,0 +1,20 @@
class AddPublishWithoutQaToRepositories < ActiveRecord::Migration
class Platform < ActiveRecord::Base
has_many :repositories, :dependent => :destroy
end
class Repository < ActiveRecord::Base
belongs_to :platform
end
def up
add_column :repositories, :publish_without_qa, :boolean, :default => true
Platform.where(:released => true).each{|p| p.repositories.update_all(:publish_without_qa => false)}
Platform.where(:released => false).each{|p| p.repositories.update_all(:publish_without_qa => true)}
end
def down
remove_column :repositories, :publish_without_qa
end
end

View File

@ -0,0 +1,5 @@
class AddLanguageToRegisterRequest < ActiveRecord::Migration
def change
add_column :register_requests, :language, :string
end
end

View File

@ -0,0 +1,6 @@
class AddBuildListNotificationsToSettingsNotifier < ActiveRecord::Migration
def change
add_column :settings_notifiers, :new_build, :boolean, :default => true
add_column :settings_notifiers, :new_associated_build, :boolean, :default => true
end
end

View File

@ -11,14 +11,14 @@
#
# It's strongly recommended to check this file into your version control system.
ActiveRecord::Schema.define(:version => 20120730214052) do
ActiveRecord::Schema.define(:version => 20120914160741) do
create_table "activity_feeds", :force => true do |t|
t.integer "user_id", :null => false
t.string "kind"
t.text "data"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "advisories", :force => true do |t|
@ -91,11 +91,14 @@ ActiveRecord::Schema.define(:version => 20120730214052) do
t.string "version"
t.string "release"
t.string "package_type"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.boolean "actual", :default => false
end
add_index "build_list_packages", ["actual", "platform_id"], :name => "index_build_list_packages_on_actual_and_platform_id"
add_index "build_list_packages", ["build_list_id"], :name => "index_build_list_packages_on_build_list_id"
add_index "build_list_packages", ["name", "project_id"], :name => "index_build_list_packages_on_name_and_project_id"
add_index "build_list_packages", ["platform_id"], :name => "index_build_list_packages_on_platform_id"
add_index "build_list_packages", ["project_id"], :name => "index_build_list_packages_on_project_id"
@ -107,8 +110,8 @@ ActiveRecord::Schema.define(:version => 20120730214052) do
t.integer "project_id"
t.integer "arch_id"
t.datetime "notified_at"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.datetime "created_at"
t.datetime "updated_at"
t.boolean "is_circle", :default => false
t.text "additional_repos"
t.string "name"
@ -131,6 +134,7 @@ ActiveRecord::Schema.define(:version => 20120730214052) do
add_index "build_lists", ["advisory_id"], :name => "index_build_lists_on_advisory_id"
add_index "build_lists", ["arch_id"], :name => "index_build_lists_on_arch_id"
add_index "build_lists", ["project_id", "save_to_repository_id", "build_for_platform_id", "arch_id"], :name => "maintainer_search_index"
add_index "build_lists", ["bs_id"], :name => "index_build_lists_on_bs_id", :unique => true
add_index "build_lists", ["project_id"], :name => "index_build_lists_on_project_id"
@ -138,8 +142,8 @@ ActiveRecord::Schema.define(:version => 20120730214052) do
t.string "commentable_type"
t.integer "user_id"
t.text "body"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.datetime "created_at"
t.datetime "updated_at"
t.decimal "commentable_id", :precision => 50, :scale => 0
t.integer "project_id"
end
@ -156,8 +160,8 @@ ActiveRecord::Schema.define(:version => 20120730214052) do
t.string "controller"
t.string "action"
t.text "message"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "flash_notifies", :force => true do |t|
@ -169,12 +173,10 @@ ActiveRecord::Schema.define(:version => 20120730214052) do
t.datetime "updated_at", :null => false
end
add_index "projects", ["owner_id"], :name => "index_projects_on_name_and_owner_id_and_owner_type", :unique => true, :case_sensitive => false
create_table "groups", :force => true do |t|
t.integer "owner_id"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.datetime "created_at"
t.datetime "updated_at"
t.string "uname"
t.integer "own_projects_count", :default => 0, :null => false
t.text "description"
@ -187,8 +189,8 @@ ActiveRecord::Schema.define(:version => 20120730214052) do
t.string "title"
t.text "body"
t.string "status", :default => "open"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.datetime "created_at"
t.datetime "updated_at"
t.integer "user_id"
t.datetime "closed_at"
t.integer "closed_by"
@ -248,8 +250,8 @@ ActiveRecord::Schema.define(:version => 20120730214052) do
t.string "description"
t.string "name", :null => false
t.integer "parent_platform_id"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.datetime "created_at"
t.datetime "updated_at"
t.boolean "released", :default => false, :null => false
t.integer "owner_id"
t.string "owner_type"
@ -264,16 +266,16 @@ ActiveRecord::Schema.define(:version => 20120730214052) do
t.integer "platform_id"
t.string "login"
t.string "password"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.datetime "created_at"
t.datetime "updated_at"
t.integer "user_id"
end
create_table "product_build_lists", :force => true do |t|
t.integer "product_id"
t.integer "status", :default => 2, :null => false
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.datetime "created_at"
t.datetime "updated_at"
end
add_index "product_build_lists", ["product_id"], :name => "index_product_build_lists_on_product_id"
@ -281,8 +283,8 @@ ActiveRecord::Schema.define(:version => 20120730214052) do
create_table "products", :force => true do |t|
t.string "name", :null => false
t.integer "platform_id", :null => false
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.datetime "created_at"
t.datetime "updated_at"
t.text "build_script"
t.text "counter"
t.text "ks"
@ -301,8 +303,8 @@ ActiveRecord::Schema.define(:version => 20120730214052) do
t.string "name"
t.string "version"
t.datetime "file_mtime"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.datetime "created_at"
t.datetime "updated_at"
t.integer "platform_id"
end
@ -311,29 +313,30 @@ ActiveRecord::Schema.define(:version => 20120730214052) do
create_table "project_to_repositories", :force => true do |t|
t.integer "project_id"
t.integer "repository_id"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "projects", :force => true do |t|
t.string "name"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.datetime "created_at"
t.datetime "updated_at"
t.integer "owner_id"
t.string "owner_type"
t.string "visibility", :default => "open"
t.text "description"
t.string "ancestry"
t.boolean "has_issues", :default => true
t.boolean "has_wiki", :default => false
t.string "srpm_file_name"
t.string "srpm_content_type"
t.integer "srpm_file_size"
t.datetime "srpm_updated_at"
t.string "srpm_content_type"
t.boolean "has_wiki", :default => false
t.string "default_branch", :default => "master"
t.boolean "is_package", :default => true, :null => false
t.integer "average_build_time", :default => 0, :null => false
t.integer "build_count", :default => 0, :null => false
t.integer "maintainer_id"
end
add_index "projects", ["owner_id"], :name => "index_projects_on_name_and_owner_id_and_owner_type", :unique => true, :case_sensitive => false
@ -344,10 +347,11 @@ ActiveRecord::Schema.define(:version => 20120730214052) do
t.string "token"
t.boolean "approved", :default => false
t.boolean "rejected", :default => false
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.datetime "created_at"
t.datetime "updated_at"
t.string "interest"
t.text "more"
t.string "language"
end
add_index "register_requests", ["email"], :name => "index_register_requests_on_email", :unique => true, :case_sensitive => false
@ -358,17 +362,18 @@ ActiveRecord::Schema.define(:version => 20120730214052) do
t.string "actor_type"
t.integer "target_id"
t.string "target_type"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.datetime "created_at"
t.datetime "updated_at"
t.string "role"
end
create_table "repositories", :force => true do |t|
t.string "description", :null => false
t.integer "platform_id", :null => false
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.string "name", :null => false
t.string "description", :null => false
t.integer "platform_id", :null => false
t.datetime "created_at"
t.datetime "updated_at"
t.string "name", :null => false
t.boolean "publish_without_qa", :default => true
end
create_table "settings_notifiers", :force => true do |t|
@ -378,18 +383,20 @@ ActiveRecord::Schema.define(:version => 20120730214052) do
t.boolean "new_comment_reply", :default => true
t.boolean "new_issue", :default => true
t.boolean "issue_assign", :default => true
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.datetime "created_at"
t.datetime "updated_at"
t.boolean "new_comment_commit_owner", :default => true
t.boolean "new_comment_commit_repo_owner", :default => true
t.boolean "new_comment_commit_commentor", :default => true
t.boolean "new_build", :default => true
t.boolean "new_associated_build", :default => true
end
create_table "subscribes", :force => true do |t|
t.string "subscribeable_type"
t.integer "user_id"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.datetime "created_at"
t.datetime "updated_at"
t.boolean "status", :default => true
t.integer "project_id"
t.decimal "subscribeable_id", :precision => 50, :scale => 0
@ -397,13 +404,14 @@ ActiveRecord::Schema.define(:version => 20120730214052) do
create_table "users", :force => true do |t|
t.string "name"
t.string "email", :default => "", :null => false
t.string "encrypted_password", :default => "", :null => false
t.string "email", :default => "", :null => false
t.string "encrypted_password", :limit => 128, :default => "", :null => false
t.string "reset_password_token"
t.datetime "reset_password_sent_at"
t.datetime "remember_created_at"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.datetime "created_at"
t.datetime "updated_at"
t.text "ssh_key"
t.string "uname"
t.string "role"
t.string "language", :default => "en"
@ -416,14 +424,14 @@ ActiveRecord::Schema.define(:version => 20120730214052) do
t.string "avatar_content_type"
t.integer "avatar_file_size"
t.datetime "avatar_updated_at"
t.integer "failed_attempts", :default => 0
t.integer "failed_attempts", :default => 0
t.string "unlock_token"
t.datetime "locked_at"
t.string "confirmation_token"
t.datetime "confirmed_at"
t.datetime "confirmation_sent_at"
t.string "authentication_token"
t.integer "build_priority", :default => 50
t.integer "build_priority", :default => 50
end
add_index "users", ["authentication_token"], :name => "index_users_on_authentication_token"

View File

@ -6,6 +6,7 @@ module RosaPresenter
include ActionDispatch::Routing::UrlFor
include ActionView::Helpers::UrlHelper
include ActionView::Helpers::TextHelper
include ActionView::Helpers::JavaScriptHelper
include Rails.application.routes.url_helpers
def initialize(item, opts)

View File

@ -6,6 +6,7 @@ namespace :add_branch do
task :fork_branch, :path, :src_branch, :dst_branch do |t, args|
tmp_path = File.join Dir.tmpdir, "#{Time.now.to_i}#{rand(1000)}"
system("git clone #{args[:path]} #{tmp_path}")
system("cd #{tmp_path} && git push origin :#{args[:dst_branch]}")
system("cd #{tmp_path} && git checkout remotes/origin/#{args[:src_branch]} || git checkout master")
system("cd #{tmp_path} && git checkout -b #{args[:dst_branch]} && git push origin HEAD")
FileUtils.rm_rf tmp_path

View File

@ -1,6 +1,6 @@
namespace :buildlist do
namespace :clear do
desc 'Remove outdated BuildLists and MassBuilds'
task :outdated => :environment do
@ -17,4 +17,32 @@ namespace :buildlist do
say "Outdated BuildLists and MassBuilds was successfully removed"
end
end
namespace :packages do
# TODO Maybe do it in migration, because it's just a single query?
desc 'Actualize packages for all platforms'
task :actualize => :environment do
say "Updating packages"
packages = BuildList::Package.joins( %q{
JOIN (
SELECT
name AS j_pn,
package_type AS j_pt,
platform_id AS j_plid,
MAX(created_at) AS j_ca
FROM
build_list_packages
GROUP BY
j_pn, j_pt, j_plid
) AS lastmaints
ON
j_pn = name
AND j_pt = package_type
AND j_plid = platform_id
AND j_ca = created_at
} ).update_all(:actual => true)
say "'Actual' setted to #{packages} packages"
end
end
end

28
lib/tasks/projects.rake Normal file
View File

@ -0,0 +1,28 @@
namespace :project do
namespace :maintainer do
desc 'Set maintainer to owner (or to owners owner if owner is a group) to projects'
task :set_to_owner => :environment do
projects = Project.scoped
count = projects.count
say "Setting maintainer to all projects (#{count})"
percent_per_batch = 100 * 1000 / count
i = 1
projects.find_in_batches do |batch|
ActiveRecord::Base.transaction do
batch.each do |proj|
maintainer_id = (proj.owner_type == 'User') ? proj.owner_id : proj.owner.owner_id
proj.maintainer_id = maintainer_id
proj.save
end
end
say "#{percent_per_batch * i}% done."
i += 1
end
say "100% done"
end
end
task :maintainer => 'maintainer:set_to_owner'
end

View File

@ -129,7 +129,8 @@ describe Groups::ProfileController do
before(:each) do
@user = FactoryGirl.create(:user)
set_session_for(@user)
@group.update_attribute(:owner, @user)
@group.owner = @user
@group.save
@group.actors.create(:actor_type => 'User', :actor_id => @user.id, :role => 'admin')
end

View File

@ -126,7 +126,9 @@ describe Platforms::KeyPairsController do
before(:each) do
@user = FactoryGirl.create(:user)
set_session_for(@user)
@platform.update_attribute(:owner, @user)
@platform.owner = @user
@platform.save
end
it_should_behave_like 'key_pair platform owner'

View File

@ -0,0 +1,69 @@
# -*- encoding : utf-8 -*-
require 'spec_helper'
shared_examples_for 'guest user' do
it "should be able to view maintainers list(index)" do
get :index, :platform_id => @platform.id
response.should be_success
end
end
describe Platforms::MaintainersController do
before(:each) do
stub_symlink_methods
@platform = FactoryGirl.create(:platform)
@user = FactoryGirl.create(:user)
set_session_for(@user)
end
context 'for guest' do
before {set_session_for(User.new)}
it "should be able to view maintainers list(index)", :anonymous_access => true do
get :index, :platform_id => @platform.id
response.should be_success
end
it "should not be able to view maintainers list(index)", :anonymous_access => false do
get :index, :platform_id => @platform.id
response.should redirect_to(new_user_session_path)
end
end
context 'for global admin' do
before(:each) do
@user.role = "admin"
@user.save
end
it_should_behave_like 'guest user'
end
context 'for registrated user' do
it_should_behave_like 'guest user'
end
context 'for platform owner' do
before(:each) do
@user = @platform.owner
set_session_for(@user)
end
it_should_behave_like 'guest user'
end
context 'for platform member' do
before(:each) do
@platform.relations.create!(:actor_type => 'User', :actor_id => @user.id, :role => 'admin')
end
it_should_behave_like 'guest user'
end
end

View File

@ -23,7 +23,7 @@ shared_examples_for 'mass_build platform owner' do
end
it 'should not be able to perform cancel action if stop_build is true' do
@mass_build.update_attribute(:stop_build, true)
@mass_build.stop_build = true; @mass_build.save
post :cancel, :platform_id => @platform, :id => @mass_build
response.should redirect_to(forbidden_path)
end
@ -133,7 +133,9 @@ describe Platforms::MassBuildsController do
before(:each) do
@user = FactoryGirl.create(:user)
set_session_for(@user)
@platform.update_attribute(:owner, @user)
@platform.owner = @user
@platform.save
end
it_should_behave_like 'mass_build platform owner'

View File

@ -2,7 +2,6 @@
require 'spec_helper'
shared_examples_for 'platform owner' do
it_should_behave_like 'platform index viewer'
it 'should not be able to destroy personal platform' do
delete :destroy, :id => @personal_platform.id
@ -19,14 +18,39 @@ shared_examples_for 'platform owner' do
end
end
shared_examples_for 'platform index viewer' do
shared_examples_for 'system registered user' do
it 'should be able to perform index action' do
get :index
response.should render_template(:index)
end
end
it 'should be able to perform show action' do
get :show, :id => @platform.id
response.should render_template(:show)
assigns(:platform).should eq @platform
end
it 'should be able to perform members action' do
get :members, :id => @platform.id
response.should render_template(:members)
response.should be_success
end
it 'should be able to perform advisories action' do
get :advisories, :id => @platform.id
response.should render_template(:advisories)
response.should be_success
end
end
shared_examples_for 'user without create rights' do
it 'should not be able to perform new action' do
get :new
response.should redirect_to(forbidden_path)
end
it 'should not be able to create platform' do
post :create, @create_params
response.should redirect_to(forbidden_path)
@ -39,16 +63,22 @@ describe Platforms::PlatformsController do
@platform = FactoryGirl.create(:platform)
@personal_platform = FactoryGirl.create(:platform, :platform_type => 'personal')
@user = FactoryGirl.create(:user)
set_session_for(@user)
@create_params = {:platform => {
:name => 'pl1',
:description => 'pl1',
:platform_type => 'main',
:distrib_type => APP_CONFIG['distr_types'].first
}}
end
end
context 'for guest' do
before(:each) do
set_session_for(User.new)
end
[:index, :create].each do |action|
it "should not be able to perform #{ action } action" do
@ -57,21 +87,39 @@ describe Platforms::PlatformsController do
end
end
[:show, :new, :edit, :clone, :destroy].each do |action|
[:new, :edit, :clone, :destroy].each do |action|
it "should not be able to perform #{ action } action" do
get action, :id => @platform
response.should redirect_to(new_user_session_path)
end
end
[:show, :members, :advisories].each do |action|
it "should not be able to perform #{ action } action", :anonymous_access => false do
get action, :id => @platform
response.should redirect_to(new_user_session_path)
end
end
[:show, :members, :advisories].each do |action|
it "should be able to perform #{ action } action", :anonymous_access => true do
get action, :id => @platform
response.should render_template(action)
response.should be_success
end
end
end
context 'for global admin' do
before(:each) do
@admin = FactoryGirl.create(:admin)
@user = FactoryGirl.create(:user)
set_session_for(@admin)
@user.role = "admin"
@user.save
end
it_should_behave_like 'system registered user'
it_should_behave_like 'platform owner'
it 'should be able to perform new action' do
get :new
response.should render_template(:new)
@ -86,51 +134,37 @@ describe Platforms::PlatformsController do
lambda { post :create, @create_params }.should change{ Platform.count }.by(1)
end
it_should_behave_like 'platform owner'
it 'should create platform with mentioned owner if owner id present' do
post :create, @create_params.merge({:admin_id => @user.id, :admin_uname => @user.uname})
Platform.last.owner.id.should eql(@user.id)
owner = FactoryGirl.create(:user)
post :create, @create_params.merge({:admin_id => owner.id, :admin_uname => owner.uname})
Platform.last.owner.id.should eql(owner.id)
end
it 'should create platform with current user as owner if owner id not present' do
post :create, @create_params
Platform.last.owner.id.should eql(@admin.id)
Platform.last.owner.id.should eql(@user.id)
end
end
context 'for owner user' do
before(:each) do
@user = FactoryGirl.create(:user)
@user = @platform.owner
set_session_for(@user)
@platform.update_attribute(:owner, @user)
@platform.relations.create!(:actor_type => 'User', :actor_id => @user.id, :role => 'admin')
end
it_should_behave_like 'system registered user'
it_should_behave_like 'user without create rights'
it_should_behave_like 'platform owner'
it 'should be able to perform new action' do
get :new
response.should redirect_to(forbidden_path)
end
it 'should be able to perform create action' do
post :create, @create_params
response.should redirect_to(forbidden_path)
end
end
context 'for reader user' do
before(:each) do
@user = FactoryGirl.create(:user)
set_session_for(@user)
@platform.relations.create!(:actor_type => 'User', :actor_id => @user.id, :role => 'reader')
end
it_should_behave_like 'platform index viewer'
it_should_behave_like 'system registered user'
it_should_behave_like 'user without create rights'
it 'should not be able to perform destroy action' do

View File

@ -31,9 +31,16 @@ describe Platforms::ProductsController do
@product = FactoryGirl.create(:product, :platform => @platform)
@create_params = {:product => {:name => 'pro'}, :platform_id => @platform.id}
@update_params = {:product => {:name => 'pro2'}, :platform_id => @platform.id}
@user = FactoryGirl.create(:user)
set_session_for(@user)
end
context 'for guest' do
context 'for guest' do
before(:each) do
set_session_for(User.new)
end
[:create].each do |action|
it "should not be able to perform #{ action } action" do
get action, :platform_id => @platform.id
@ -41,40 +48,56 @@ describe Platforms::ProductsController do
end
end
[:show, :new, :edit, :update, :destroy].each do |action|
[:new, :edit, :update, :destroy].each do |action|
it "should not be able to perform #{ action } action" do
get action, :id => @product.id, :platform_id => @platform.id
response.should redirect_to(new_user_session_path)
end
end
[:show, :index].each do |action|
it "should not be able to perform #{ action } action", :anonymous_access => false do
get action, :id => @product.id, :platform_id => @platform.id
response.should redirect_to(new_user_session_path)
end
end
[:show, :index].each do |action|
it "should be able to perform #{ action } action", :anonymous_access => true do
get action, :id => @product.id, :platform_id => @platform.id
response.should render_template(action)
response.should be_success
end
end
end
context 'for global admin' do
before(:each) do
@admin = FactoryGirl.create(:admin)
set_session_for(@admin)
end
before(:each) do
@user.role = "admin"
@user.save
end
it_should_behave_like 'admin user'
end
context 'for platform owner' do
before(:each) do
@user = @platform.owner
set_session_for(@user)
end
it_should_behave_like 'admin user'
end
context 'for admin relation user' do
before(:each) do
@user = FactoryGirl.create(:user)
set_session_for(@user)
before(:each) do
@platform.relations.create!(:actor_type => 'User', :actor_id => @user.id, :role => 'admin')
end
end
it_should_behave_like 'admin user'
end
context 'for no relation user' do
before(:each) do
@user = FactoryGirl.create(:user)
set_session_for(@user)
end
it 'should not be able to create product' do
lambda { post :create, @create_params }.should change{ Product.count }.by(0)

Some files were not shown because too many files have changed in this diff Show More