diff --git a/Gemfile b/Gemfile index 7ed9a93a3..65f5da383 100644 --- a/Gemfile +++ b/Gemfile @@ -1,20 +1,20 @@ source 'http://rubygems.org' -gem 'rails', '3.2.6' #, :git => 'git://github.com/rails/rails.git' +gem 'rails', '3.2.7' #, :git => 'git://github.com/rails/rails.git' -gem 'pg', '~> 0.13.2' +gem 'pg', '~> 0.14.0' # gem 'silent-postgres', :git => 'git://github.com/dolzenko/silent-postgres.git' #'~> 0.1.1' gem 'redhillonrails_core', :git => 'git://github.com/chipiga/redhillonrails_core.git', :branch => 'rails31' # '~> 2.0.0.pre' # deprecated # gem 'schema_plus', '~> 0.2.1' # buggy shit! -gem 'devise', '~> 2.0.4' -gem 'omniauth', '~> 1.0.3' +gem 'devise', '~> 2.1.2' +gem 'omniauth', '~> 1.1.0' gem 'omniauth-openid', '~> 1.0.1' -gem 'cancan', '~> 1.6.7' +gem 'cancan', '1.6.7' # 1.6.8 fail specs with strange error gem 'ancestry', '~> 1.3.0' -gem 'paperclip', '~> 3.0.4' -gem 'resque', '~> 1.20.0' +gem 'paperclip', '~> 3.1.4' +gem 'resque', '~> 1.21.0' gem 'resque-status', '~> 0.3.3' gem 'resque_mailer', '~> 2.1.0' gem 'perform_later', '~> 1.3.0' # should be after resque_mailer @@ -26,10 +26,12 @@ gem 'state_machine' 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 'ruby-filemagic', '~> 0.4.2', :require => 'filemagic/ext' +gem 'github-linguist', '~> 2.1.2', :require => 'linguist' gem 'diff-display', '~> 0.0.1' # Wiki -gem "gollum", "1.3.1" +gem "gollum", :git => 'git://github.com/github/gollum.git' gem "redcarpet", "1.17.2" gem 'creole' gem 'rdiscount' @@ -39,7 +41,7 @@ gem 'wikicloth' gem 'unicorn', '~> 4.3.1', :platforms => [:mri, :rbx] gem 'trinidad', '~> 1.0.2', :platforms => :jruby -gem 'newrelic_rpm', '~> 3.3.5', :platforms => [:mri, :rbx] +gem 'newrelic_rpm', '~> 3.4.1', :platforms => [:mri, :rbx] gem 'whenever', '~> 0.7.3', :require => false gem 'jbuilder', '~> 0.4.0' @@ -54,14 +56,14 @@ gem 'rails-backbone', '~> 0.7.2' group :assets do gem 'sass-rails', '~> 3.2.5' gem 'coffee-rails', '~> 3.2.2' - gem 'compass-rails', '~> 1.0.2' + gem 'compass-rails', '~> 1.0.3' gem 'uglifier', '~> 1.2.4' gem 'therubyracer', '~> 0.10.1', :platforms => [:mri, :rbx] gem 'therubyrhino', '~> 1.73.1', :platforms => :jruby end group :production do - gem "airbrake", '~> 3.1.1' + gem "airbrake", '~> 3.1.2' gem 'bluepill', '~> 0.0.60', :require => false end @@ -78,8 +80,8 @@ group :development do end group :test do - gem 'rspec-rails', '~> 2.10.1', :group => 'development' - gem 'factory_girl_rails', '~> 3.4.0' + gem 'rspec-rails', '~> 2.11.0', :group => 'development' + gem 'factory_girl_rails', '~> 3.5.0' gem 'rr', '~> 1.0.4' gem 'shoulda' end diff --git a/Gemfile.lock b/Gemfile.lock index 15dc97662..8d70a5ad0 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -6,6 +6,23 @@ GIT redhillonrails_core (2.0.0.pre) activerecord (>= 3.1.0.rc) +GIT + remote: git://github.com/github/gollum.git + revision: c9bc2a89f655760c0a21da6d3ab37c5f6267e96c + 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 @@ -14,9 +31,9 @@ GIT GIT remote: git://github.com/warpc/grit.git - revision: 696b0967cb7e6bac044569d898e5acef431d4f97 + revision: f04f779fb052725b964ba259f8073a34e493c0c7 specs: - grit (2.4.1) + grit (2.5.0) diff-lcs (~> 1.1) mime-types (~> 1.15) posix-spawn (~> 0.3.6) @@ -25,38 +42,36 @@ GEM remote: http://rubygems.org/ specs: RedCloth (4.2.9) - actionmailer (3.2.6) - actionpack (= 3.2.6) + actionmailer (3.2.7) + actionpack (= 3.2.7) mail (~> 2.4.4) - actionpack (3.2.6) - activemodel (= 3.2.6) - activesupport (= 3.2.6) + actionpack (3.2.7) + activemodel (= 3.2.7) + activesupport (= 3.2.7) builder (~> 3.0.0) erubis (~> 2.7.0) - journey (~> 1.0.1) + journey (~> 1.0.4) rack (~> 1.4.0) rack-cache (~> 1.2) rack-test (~> 0.6.1) sprockets (~> 2.1.3) - activemodel (3.2.6) - activesupport (= 3.2.6) + activemodel (3.2.7) + activesupport (= 3.2.7) builder (~> 3.0.0) - activerecord (3.2.6) - activemodel (= 3.2.6) - activesupport (= 3.2.6) + activerecord (3.2.7) + activemodel (= 3.2.7) + activesupport (= 3.2.7) arel (~> 3.0.2) tzinfo (~> 0.3.29) - activeresource (3.2.6) - activemodel (= 3.2.6) - activesupport (= 3.2.6) - activesupport (3.2.6) + activeresource (3.2.7) + activemodel (= 3.2.7) + activesupport (= 3.2.7) + activesupport (3.2.7) i18n (~> 0.6) multi_json (~> 1.0) - airbrake (3.1.1) + airbrake (3.1.2) activesupport builder - albino (1.3.3) - posix-spawn (>= 0.3.6) ancestry (1.3.0) activerecord (>= 2.3.14) arel (3.0.2) @@ -88,43 +103,42 @@ GEM coffee-script-source execjs coffee-script-source (1.3.3) - compass (0.12.1) + compass (0.12.2) chunky_png (~> 1.2) fssm (>= 0.2.7) sass (~> 3.1) - compass-rails (1.0.2) - compass (>= 0.12.0, < 0.14) + compass-rails (1.0.3) + compass (>= 0.12.2, < 0.14) creole (0.4.2) daemons (1.1.6) - devise (2.0.4) + devise (2.1.2) bcrypt-ruby (~> 3.0) - orm_adapter (~> 0.0.3) + orm_adapter (~> 0.1) railties (~> 3.1) - warden (~> 1.1.1) + warden (~> 1.2.1) diff-display (0.0.1) diff-lcs (1.1.3) ejs (1.0.0) erubis (2.7.0) + escape_utils (0.2.4) eventmachine (0.12.10) execjs (1.4.0) multi_json (~> 1.0) expression_parser (0.9.0) - factory_girl (3.4.0) + factory_girl (3.5.0) activesupport (>= 3.0.0) - factory_girl_rails (3.4.0) - factory_girl (~> 3.4.0) + factory_girl_rails (3.5.0) + factory_girl (~> 3.5.0) railties (>= 3.0.0) + ffi (1.0.11) fssm (0.2.9) - github-markup (0.7.2) - gollum (1.3.1) - albino (~> 1.3.2) - github-markup (>= 0.4.0, < 1.0.0) - grit (~> 2.4.1) - mustache (>= 0.11.2, < 1.0.0) - nokogiri (~> 1.4) - redcarpet - sanitize (~> 2.0.0) - sinatra (~> 1.0) + github-linguist (2.1.2) + 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) haml-rails (0.3.4) actionpack (~> 3.0) @@ -132,18 +146,18 @@ GEM haml (~> 3.0) railties (~> 3.0) hashie (1.2.0) - highline (1.6.12) + highline (1.6.13) hike (1.2.1) - hirb (0.6.2) + hirb (0.7.0) i18n (0.6.0) jbuilder (0.4.0) activesupport (>= 3.0.0) blankslate (>= 2.1.2.4) - journey (1.0.3) + journey (1.0.4) jquery-rails (2.0.2) railties (>= 3.2.0, < 5.0) thor (~> 0.14) - json (1.7.3) + json (1.7.4) kgio (2.7.4) libv8 (3.3.10.4) macaddr (1.6.1) @@ -152,18 +166,18 @@ GEM i18n (>= 0.4.0) mime-types (~> 1.16) treetop (~> 1.4.8) - mailcatcher (0.5.6) + mailcatcher (0.5.8) activesupport (~> 3.0) eventmachine (~> 0.12) haml (~> 3.1) mail (~> 2.3) sinatra (~> 1.2) - skinny (~> 0.2) + skinny (~> 0.2, >= 0.2.1) sqlite3 (~> 1.3) thin (~> 1.2) meta-tags (1.2.6) actionpack - mime-types (1.18) + mime-types (1.19) multi_json (1.3.6) mustache (0.99.4) net-scp (1.0.4) @@ -173,16 +187,16 @@ GEM net-ssh (2.5.2) net-ssh-gateway (1.1.0) net-ssh (>= 1.99.1) - newrelic_rpm (3.3.5) - nokogiri (1.5.4) - omniauth (1.0.3) + newrelic_rpm (3.4.1) + nokogiri (1.5.5) + omniauth (1.1.0) hashie (~> 1.2) rack omniauth-openid (1.0.1) omniauth (~> 1.0) rack-openid (~> 1.3.1) - orm_adapter (0.0.7) - paperclip (3.0.4) + orm_adapter (0.4.0) + paperclip (3.1.4) activemodel (>= 3.0.0) activerecord (>= 3.0.0) activesupport (>= 3.0.0) @@ -192,9 +206,11 @@ GEM rails (~> 3.0) redis resque - pg (0.13.2) + pg (0.14.0) polyglot (0.3.3) posix-spawn (0.3.6) + pygments.rb (0.2.13) + rubypython (~> 0.5.3) rack (1.4.1) rack-cache (1.2) rack (>= 0.4) @@ -207,14 +223,14 @@ GEM rack rack-test (0.6.1) rack (>= 1.0) - rails (3.2.6) - actionmailer (= 3.2.6) - actionpack (= 3.2.6) - activerecord (= 3.2.6) - activeresource (= 3.2.6) - activesupport (= 3.2.6) + rails (3.2.7) + actionmailer (= 3.2.7) + actionpack (= 3.2.7) + activerecord (= 3.2.7) + activeresource (= 3.2.7) + activesupport (= 3.2.7) bundler (~> 1.0) - railties (= 3.2.6) + railties (= 3.2.7) rails-backbone (0.7.2) coffee-script (~> 2.2.0) ejs (~> 1.0.0) @@ -223,28 +239,28 @@ GEM railties (>= 3.0.0) rails3-jquery-autocomplete (1.0.7) rails (~> 3.0) - railties (3.2.6) - actionpack (= 3.2.6) - activesupport (= 3.2.6) + railties (3.2.7) + actionpack (= 3.2.7) + activesupport (= 3.2.7) rack-ssl (~> 1.3.2) rake (>= 0.8.7) rdoc (~> 3.4) thor (>= 0.14.6, < 2.0) - raindrops (0.9.0) + raindrops (0.10.0) rake (0.9.2.2) rdiscount (1.6.8) rdoc (3.12) json (~> 1.4) redcarpet (1.17.2) - redis (2.2.2) - redis-namespace (1.0.3) - redis (< 3.0.0) + redis (3.0.1) + redis-namespace (1.2.0) + redis (~> 3.0.0) redisk (0.2.2) redis (>= 0.1.1) redis-namespace (>= 0.1.0) - resque (1.20.0) + resque (1.21.0) multi_json (~> 1.0) - redis-namespace (~> 1.0.2) + redis-namespace (~> 1.0) sinatra (>= 0.9.2) vegas (~> 0.1.2) resque-status (0.3.3) @@ -254,46 +270,50 @@ GEM resque_mailer (2.1.0) actionmailer (~> 3.0) rr (1.0.4) - rspec (2.10.0) - rspec-core (~> 2.10.0) - rspec-expectations (~> 2.10.0) - rspec-mocks (~> 2.10.0) - rspec-core (2.10.1) - rspec-expectations (2.10.0) + rspec (2.11.0) + rspec-core (~> 2.11.0) + rspec-expectations (~> 2.11.0) + rspec-mocks (~> 2.11.0) + rspec-core (2.11.1) + rspec-expectations (2.11.2) diff-lcs (~> 1.1.3) - rspec-mocks (2.10.1) - rspec-rails (2.10.1) + rspec-mocks (2.11.1) + rspec-rails (2.11.0) actionpack (>= 3.0) activesupport (>= 3.0) railties (>= 3.0) - rspec (~> 2.10.0) + rspec (~> 2.11.0) ruby-haml-js (0.0.3) execjs sprockets (>= 2.0.0) - ruby-openid (2.1.8) + ruby-openid (2.2.0) + rubypython (0.5.3) + blankslate (>= 2.1.2.3) + ffi (~> 1.0.7) russian (0.6.0) i18n (>= 0.5.0) - rvm-capistrano (1.2.2) + rvm-capistrano (1.2.5) capistrano (>= 2.0.0) sanitize (2.0.3) nokogiri (>= 1.4.4, < 1.6) - sass (3.1.19) + sass (3.1.20) sass-rails (3.2.5) railties (~> 3.2.0) sass (>= 3.1.10) tilt (~> 1.3) shotgun (0.9) rack (>= 1.0) - shoulda (3.0.1) - shoulda-context (~> 1.0.0) - shoulda-matchers (~> 1.0.0) + shoulda (3.1.1) + shoulda-context (~> 1.0) + shoulda-matchers (~> 1.2) shoulda-context (1.0.0) - shoulda-matchers (1.0.0) + shoulda-matchers (1.2.0) + activesupport (>= 3.0.0) sinatra (1.3.2) rack (~> 1.3, >= 1.3.6) rack-protection (~> 1.2) tilt (~> 1.3, >= 1.3.3) - skinny (0.2.0) + skinny (0.2.1) eventmachine (~> 0.12) thin (~> 1.2) sprockets (2.1.3) @@ -302,31 +322,33 @@ GEM tilt (~> 1.1, != 1.3.0) sqlite3 (1.3.6) state_machine (1.1.2) - systemu (2.5.1) + stringex (1.4.0) + systemu (2.5.2) therubyracer (0.10.1) libv8 (~> 3.3.10) - thin (1.3.1) + thin (1.4.1) daemons (>= 1.0.9) eventmachine (>= 0.12.6) rack (>= 1.0.0) - thor (0.15.2) + thor (0.15.4) tilt (1.3.3) treetop (1.4.10) polyglot polyglot (>= 0.3.1) tzinfo (0.3.33) - uglifier (1.2.4) + uglifier (1.2.6) execjs (>= 0.3.0) - multi_json (>= 1.0.2) + multi_json (~> 1.3) unicorn (4.3.1) kgio (~> 2.6) rack raindrops (~> 0.7) + useragent (0.4.10) uuid (2.3.5) macaddr (~> 1.0) vegas (0.1.11) rack (>= 1.0.0) - warden (1.1.1) + warden (1.2.1) rack (>= 1.0) whenever (0.7.3) activesupport (>= 2.3.4) @@ -341,21 +363,22 @@ PLATFORMS DEPENDENCIES RedCloth - airbrake (~> 3.1.1) + airbrake (~> 3.1.2) ancestry (~> 1.3.0) bluepill (~> 0.0.60) - cancan (~> 1.6.7) + cancan (= 1.6.7) cape capistrano capistrano_colors charlock_holmes (~> 0.6.8) coffee-rails (~> 3.2.2) - compass-rails (~> 1.0.2) + compass-rails (~> 1.0.3) creole - devise (~> 2.0.4) + devise (~> 2.1.2) diff-display (~> 0.0.1) - factory_girl_rails (~> 3.4.0) - gollum (= 1.3.1) + factory_girl_rails (~> 3.5.0) + github-linguist (~> 2.1.2) + gollum! grack! grit! haml-rails (~> 0.3.4) @@ -365,24 +388,24 @@ DEPENDENCIES jquery-rails (~> 2.0.2) mailcatcher meta-tags (~> 1.2.5) - newrelic_rpm (~> 3.3.5) - omniauth (~> 1.0.3) + newrelic_rpm (~> 3.4.1) + omniauth (~> 1.1.0) omniauth-openid (~> 1.0.1) - paperclip (~> 3.0.4) + paperclip (~> 3.1.4) perform_later (~> 1.3.0) - pg (~> 0.13.2) - rails (= 3.2.6) + pg (~> 0.14.0) + rails (= 3.2.7) rails-backbone (~> 0.7.2) rails3-generators rails3-jquery-autocomplete (~> 1.0.7) rdiscount redcarpet (= 1.17.2) redhillonrails_core! - resque (~> 1.20.0) + resque (~> 1.21.0) resque-status (~> 0.3.3) resque_mailer (~> 2.1.0) rr (~> 1.0.4) - rspec-rails (~> 2.10.1) + rspec-rails (~> 2.11.0) ruby-haml-js (~> 0.0.3) russian (~> 0.6.0) rvm-capistrano diff --git a/app/assets/javascripts/extra/flash_notifies.js b/app/assets/javascripts/extra/flash_notifies.js new file mode 100644 index 000000000..52c9fbf53 --- /dev/null +++ b/app/assets/javascripts/extra/flash_notifies.js @@ -0,0 +1,18 @@ +function setCookie (name, value, expires, path, domain, secure) { + document.cookie = name + "=" + escape(value) + + ((expires) ? "; expires=" + expires : "") + + ((path) ? "; path=" + path : "") + + ((domain) ? "; domain=" + domain : "") + + ((secure) ? "; secure" : ""); +} + +$(document).ready(function() { + if ($(".alert").size()) { + $(".alert").alert() + } + + $('#close-alert').click(function () { + setCookie("flash_notify_hash", FLASH_HASH_ID, FLASH_EXPIRES_AT); + }); +}); + diff --git a/app/assets/stylesheets/design/custom.scss b/app/assets/stylesheets/design/custom.scss index ccf97e3d0..d15e12be6 100644 --- a/app/assets/stylesheets/design/custom.scss +++ b/app/assets/stylesheets/design/custom.scss @@ -1172,3 +1172,77 @@ table.tablesorter tr td.no_results { text-align: center; } /* end */ + +hr.bootstrap { + border: 0; + border-top: 1px solid #eeeeee; + border-bottom: 1px solid #ffffff; +} + +.fork-modal { + top: 45%; +} + +.modal-body-fork { + max-height: 280px; +} + +/* Flash Notifies */ + +.flash_notify { + .alert-success { + color: #468847; + background-color: #DFF0D8; + border-color: #D6E9C6; + } + + .alert { + padding: 8px 35px 8px 14px; + margin-bottom: 18px; + color: #C09853; + text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); + background-color: #FCF8E3; + border: 1px solid #FBEED5; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + } + + .alert-danger, .alert-error { + color: #B94A48; + background-color: #F2DEDE; + border-color: #EED3D7; + } + + .alert-info { + color: #3A87AD; + background-color: #D9EDF7; + border-color: #BCE8F1; + } + + .alert .close { + position: relative; + top: -2px; + right: -21px; + line-height: 18px; + } + + button.close { + padding: 0; + cursor: pointer; + background: transparent; + border: 0; + -webkit-appearance: none; + } + + .close { + float: right; + font-size: 20px; + font-weight: bold; + line-height: 18px; + color: black; + text-shadow: 0 1px 0 white; + opacity: 0.2; + filter: alpha(opacity=20); + } +} diff --git a/app/controllers/admin/flash_notifies_controller.rb b/app/controllers/admin/flash_notifies_controller.rb new file mode 100644 index 000000000..5946427bf --- /dev/null +++ b/app/controllers/admin/flash_notifies_controller.rb @@ -0,0 +1,41 @@ +class Admin::FlashNotifiesController < Admin::BaseController + def index + @flash_notifies = FlashNotify.paginate(:page => params[:page], :per_page => 20) + end + + def new + @flash_notify = FlashNotify.new(:published => true) + end + + def create + @flash_notify = FlashNotify.new(params[:flash_notify]) + if @flash_notify.save + flash[:notice] = t("flash.flash_notify.saved") + redirect_to admin_flash_notifies_path + else + flash[:error] = t("flash.flash_notify.save_error") + flash[:warning] = @flash_notify.errors.full_messages.join('. ') + render :new + end + end + + def update + if @flash_notify.update_attributes(params[:flash_notify]) + flash[:notice] = t("flash.flash_notify.saved") + redirect_to admin_flash_notifies_path + else + flash[:error] = t("flash.flash_notify.save_error") + flash[:warning] = @flash_notify.errors.full_messages.join('. ') + render :edit + end + end + + def destroy + if @flash_notify.destroy + flash[:notice] = t("flash.flash_notify.destroyed") + else + flash[:error] = t("flash.flash_notify.destroy_error") + end + redirect_to admin_flash_notifies_path + end +end diff --git a/app/controllers/admin/users_controller.rb b/app/controllers/admin/users_controller.rb index 91d5076b8..9b947578d 100644 --- a/app/controllers/admin/users_controller.rb +++ b/app/controllers/admin/users_controller.rb @@ -12,7 +12,7 @@ class Admin::UsersController < Admin::BaseController def create @user.role = params[:role] @user.confirmed_at = Time.now.utc - if @user.save + if (@user.save rescue false) flash[:notice] = t('flash.user.saved') redirect_to admin_users_path else @@ -60,7 +60,6 @@ class Admin::UsersController < Admin::BaseController end @filter = params[:filter] || 'all' @users = @users.send(@filter) if ['real', 'admin', 'banned'].include? @filter - @total_user = @users.count @users = @users.order(order) render :partial => 'users_ajax', :layout => false diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 642ee629b..b191227aa 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -17,6 +17,7 @@ class ApplicationController < ActionController::Base rescue_from CanCan::AccessDenied do |exception| redirect_to forbidden_url, :alert => t("flash.exception_message") end + rescue_from Grit::NoSuchPathError, :with => :not_found protected @@ -53,4 +54,8 @@ class ApplicationController < ActionController::Base "application" end end + + def not_found + raise ActionController::RoutingError.new('Not Found') + end end diff --git a/app/controllers/groups/profile_controller.rb b/app/controllers/groups/profile_controller.rb index 30b62c795..1fd4ebab5 100644 --- a/app/controllers/groups/profile_controller.rb +++ b/app/controllers/groups/profile_controller.rb @@ -49,7 +49,7 @@ class Groups::ProfileController < Groups::BaseController end def remove_user - Relation.by_object(current_user).by_target(@group).destroy_all + Relation.by_actor(current_user).by_target(@group).destroy_all redirect_to groups_path end end diff --git a/app/controllers/platforms/repositories_controller.rb b/app/controllers/platforms/repositories_controller.rb index d37caf8c6..7e617e7d5 100644 --- a/app/controllers/platforms/repositories_controller.rb +++ b/app/controllers/platforms/repositories_controller.rb @@ -76,11 +76,13 @@ class Platforms::RepositoriesController < Platforms::BaseController @projects = Project.joins(owner_subquery).addable_to_repository(@repository.id) @projects = @projects.by_visibilities('open') if @repository.platform.platform_type == 'main' end - @projects = @projects.paginate(:page => (params[:iDisplayStart].to_i/params[:iDisplayLength].to_i).to_i + 1, :per_page => params[:iDisplayLength]) + @projects = @projects.paginate( + :page => (params[:iDisplayStart].to_i/(params[:iDisplayLength].present? ? params[:iDisplayLength] : 25).to_i).to_i + 1, + :per_page => params[:iDisplayLength].present? ? params[:iDisplayLength] : 25 + ) - @total_projects = @projects.count + @total_projects_count = @projects.count @projects = @projects.search(params[:sSearch]).search_order if params[:sSearch].present? - @total_project = @projects.count @projects = @projects.order(order) render :partial => (params[:added] == "true") ? 'project' : 'proj_ajax', :layout => false diff --git a/app/controllers/projects/build_lists_controller.rb b/app/controllers/projects/build_lists_controller.rb index cb5115741..ce7364d52 100644 --- a/app/controllers/projects/build_lists_controller.rb +++ b/app/controllers/projects/build_lists_controller.rb @@ -46,7 +46,8 @@ class Projects::BuildListsController < Projects::BaseController Arch.where(:id => params[:arches]).each do |arch| Platform.main.where(:id => params[:build_for_platforms]).each do |build_for_platform| @build_list = @project.build_lists.build(params[:build_list]) - @build_list.commit_hash = @project.git_repository.commits(@build_list.project_version.match(/^latest_(.+)/).to_a.last || @build_list.project_version).first.id if @build_list.project_version + @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 @build_list.build_for_platform = build_for_platform; @build_list.arch = arch; @build_list.user = current_user @build_list.include_repos = @build_list.include_repos.select {|ir| @build_list.build_for_platform.repository_ids.include? ir.to_i} @build_list.priority = current_user.build_priority # User builds more priority than mass rebuild with zero priority @@ -98,7 +99,6 @@ class Projects::BuildListsController < Projects::BaseController else @build_list.fail_publish end - render :nothing => true, :status => 200 end diff --git a/app/controllers/projects/comments_controller.rb b/app/controllers/projects/comments_controller.rb index 371365eb9..3b36c3456 100644 --- a/app/controllers/projects/comments_controller.rb +++ b/app/controllers/projects/comments_controller.rb @@ -41,7 +41,7 @@ class Projects::CommentsController < Projects::BaseController def find_commentable @commentable = params[:issue_id].present? && @project.issues.find_by_serial_id(params[:issue_id]) || - params[:commit_id].present? && @project.git_repository.commit(params[:commit_id]) + params[:commit_id].present? && @project.repo.commit(params[:commit_id]) end def find_or_build_comment diff --git a/app/controllers/projects/commit_subscribes_controller.rb b/app/controllers/projects/commit_subscribes_controller.rb index de5b2ac6e..b7dbc31c7 100644 --- a/app/controllers/projects/commit_subscribes_controller.rb +++ b/app/controllers/projects/commit_subscribes_controller.rb @@ -25,7 +25,7 @@ class Projects::CommitSubscribesController < Projects::BaseController protected def find_commit - @commit = @project.git_repository.commit(params[:commit_id]) + @commit = @project.repo.commit(params[:commit_id]) @options = {:project_id => @project.id, :subscribeable_id => @commit.id.hex, :subscribeable_type => @commit.class.name, :user_id => current_user.id} end end diff --git a/app/controllers/projects/git/base_controller.rb b/app/controllers/projects/git/base_controller.rb index 37168d764..a77c39ffd 100644 --- a/app/controllers/projects/git/base_controller.rb +++ b/app/controllers/projects/git/base_controller.rb @@ -4,36 +4,19 @@ class Projects::Git::BaseController < Projects::BaseController skip_before_filter :authenticate_user!, :only => [:show, :index, :blame, :raw, :archive] if APP_CONFIG['anonymous_access'] load_and_authorize_resource :project - before_filter :find_git_repository - before_filter :find_tags - before_filter :find_branches - before_filter :set_treeish - before_filter :set_current_tag - before_filter :set_current_branch + before_filter :set_treeish_and_path + before_filter :set_branch_and_tree protected - def find_git_repository - @git_repository = @project.git_repository - end - - def find_tags - @tags = @git_repository.tags - end - - def find_branches - @branches = @git_repository.branches - end - - def set_treeish + def set_treeish_and_path @treeish = params[:treeish].presence || @project.default_branch + @path = params[:path] end - def set_current_tag - @current_tag = @tags.select{|t| t.name == @treeish }.first - end - - def set_current_branch - @current_branch = @branches.select{|b| b.name == @treeish }.first + def set_branch_and_tree + @branch = @project.repo.branches.detect{|b| b.name == @treeish} + @tree = @project.repo.tree(@treeish) + # raise Grit::NoSuchPathError if @tree.blobs.blank? end end diff --git a/app/controllers/projects/git/blobs_controller.rb b/app/controllers/projects/git/blobs_controller.rb index b8abb0799..96dc586dc 100644 --- a/app/controllers/projects/git/blobs_controller.rb +++ b/app/controllers/projects/git/blobs_controller.rb @@ -1,34 +1,17 @@ # -*- encoding : utf-8 -*- class Projects::Git::BlobsController < Projects::Git::BaseController - before_filter :find_tree - before_filter :find_branch - before_filter :set_path_blob + before_filter :set_blob + before_filter lambda {authorize! :write, @project}, :only => [:edit, :update] def show - redirect_to project_path(@project) and return unless @blob.present? - if params[:raw] - response.headers['Cache-Control'] = "public, max-age=#{12.hours.to_i}" - response.headers['Content-Type'] = @blob.mime_type - response.headers['Content-Disposition'] = 'inline' - render(:text => @blob.data) and return - end end def edit - redirect_to project_path(@project) and return unless @blob.present? - authorize! :write, @project end def update - redirect_to project_path(@project) and return unless @blob.present? - authorize! :write, @project - # Here might be callbacks for notification purposes: - # @git_repository.after_update_file do |repo, sha| - # end - - res = @git_repository.update_file(params[:path], params[:content].gsub("\r", ''), - :message => params[:message].gsub("\r", ''), :actor => current_user, :head => @treeish) - if res + if @project.update_file(params[:path], params[:content].gsub("\r", ''), + :message => params[:message].gsub("\r", ''), :actor => current_user, :head => @treeish) flash[:notice] = t("flash.blob.successfully_updated", :name => params[:path]) else flash[:notice] = t("flash.blob.updating_error", :name => params[:path]) @@ -37,28 +20,17 @@ class Projects::Git::BlobsController < Projects::Git::BaseController end def blame - @blame = Grit::Blob.blame(@git_repository.repo, @commit.id, @path) + @blame = Grit::Blob.blame(@project.repo, @commit.id, @path) end def raw - redirect_to project_path(@project) and return unless @blob.present? - headers["Content-Disposition"] = %[attachment;filename="#{@blob.name}"] - render :text => @blob.data, :content_type => @blob.mime_type + send_data @blob.data, :type => @blob.content_type, :disposition => @blob.disposition end protected - def find_branch - @branch = @project.branch(@treeish) - end - - def set_path_blob - @path = params[:path] - @blob = @tree / @path - @commit = @git_repository.log(@treeish, @path, :max_count => 1).first - end - - def find_tree - @tree = @git_repository.tree(@treeish) + def set_blob + @blob = @tree / @path or raise Grit::NoSuchPathError + @commit = @project.repo.log(@treeish, @path, :max_count => 1).first end end diff --git a/app/controllers/projects/git/commits_controller.rb b/app/controllers/projects/git/commits_controller.rb index cf9a20021..31816996c 100644 --- a/app/controllers/projects/git/commits_controller.rb +++ b/app/controllers/projects/git/commits_controller.rb @@ -1,42 +1,19 @@ # -*- encoding : utf-8 -*- class Projects::Git::CommitsController < Projects::Git::BaseController - helper_method :split_commits_by_date - def index - @branch_name = params[:treeish] || @project.default_branch - @branch = @project.branch(@branch_name) - @path = params[:path] - if @path.present? - @commits = @git_repository.repo.log(@branch_name, @path) - @render_paginate = false + @commits = @project.repo.log(@treeish, @path) else - @commits, @page, @last_page = @git_repository.paginate_commits(@branch_name, :page => params[:page]) - @render_paginate = true + @commits, @page, @last_page = @project.paginate_commits(@treeish, :page => params[:page]) end end def show - @commit = @git_repository.commit(params[:id]) # @git_repository.commits(params[:id]).first - + @commit = @project.repo.commit(params[:id]) respond_to do |format| format.html format.diff { render :text => (@commit.diffs.map(&:diff).join("\n") rescue ''), :content_type => "text/plain" } format.patch { render :text => (@commit.to_patch rescue ''), :content_type => "text/plain" } end end - - protected - - def split_commits_by_date(commits) - res = commits.sort{|x, y| y.authored_date <=> x.authored_date}.inject({}) do |h, commit| - dt = commit.authored_date - h[dt.year] ||= {} - h[dt.year][dt.month] ||= {} - h[dt.year][dt.month][dt.day] ||= [] - h[dt.year][dt.month][dt.day] << commit - h - end - return res - end end diff --git a/app/controllers/projects/git/trees_controller.rb b/app/controllers/projects/git/trees_controller.rb index 9655ffd4b..45dae2aa1 100644 --- a/app/controllers/projects/git/trees_controller.rb +++ b/app/controllers/projects/git/trees_controller.rb @@ -1,32 +1,21 @@ # -*- encoding : utf-8 -*- class Projects::Git::TreesController < Projects::Git::BaseController + before_filter lambda{redirect_to @project if params[:treeish] == @project.default_branch and params[:path].blank?}, :only => 'show' + def show - redirect_to project_path(@project) and return if params[:treeish] == @project.default_branch and params[:path].blank? - - @path = params[:path] - @tree = @git_repository.tree(@treeish) - @branch = @project.branch(@treeish) - -# @commit = @git_repository.commits(@treeish, 1).first -# Raises Grit::Git::GitTimeout - @commit = @branch.present? ? @branch.commit() : @git_repository.log(@treeish, @path, :max_count => 1).first - render "empty" and return unless @commit - - @tree = @tree / @path if @path + @tree = @tree / @path if @path.present? + @commit = @branch.present? ? @branch.commit() : @project.repo.log(@treeish, @path, :max_count => 1).first + render 'empty' unless @commit end def archive - treeish = params[:treeish].presence || @project.default_branch - format = params[:format] || 'tar' - commit = @project.git_repository.log(treeish, nil, :max_count => 1).first - if !commit or !['tar', 'zip'].include?(format) - raise ActiveRecord::RecordNotFound#("Couldn't send Project archive with id=#{@project.id}, treeish=#{treeish} and format=#{format}") - end - name = "#{@project.owner.uname}-#{@project.name}#{@project.tags.include?(treeish) ? "-#{treeish}" : ''}-#{commit.id[0..19]}" - fullname = "#{name}.#{format == 'tar' ? 'tar.gz' : 'zip'}" + @commit = @project.repo.log(@treeish, nil, :max_count => 1).first + raise Grit::NoSuchPathError unless @commit + name = "#{@project.owner.uname}-#{@project.name}#{@project.repo.tags.include?(@treeish) ? "-#{@treeish}" : ''}-#{@commit.id[0..19]}" + fullname = "#{name}.#{params[:format] == 'tar' ? 'tar.gz' : 'zip'}" file = Tempfile.new fullname, 'tmp' - system("cd #{@project.path}; git archive --format=#{format} --prefix=#{name}/ #{treeish} #{format == 'tar' ? ' | gzip -9' : ''} > #{file.path}") + system("cd #{@project.path}; git archive --format=#{params[:format]} --prefix=#{name}/ #{@treeish} #{params[:format] == 'tar' ? ' | gzip -9' : ''} > #{file.path}") file.close - send_file file.path, :disposition => 'attachment', :type => "application/#{format == 'tar' ? 'x-tar-gz' : 'zip'}", :filename => fullname + send_file file.path, :disposition => 'attachment', :type => "application/#{params[:format] == 'tar' ? 'x-tar-gz' : 'zip'}", :filename => fullname end end diff --git a/app/controllers/projects/projects_controller.rb b/app/controllers/projects/projects_controller.rb index b948f5d7c..30b452dc4 100644 --- a/app/controllers/projects/projects_controller.rb +++ b/app/controllers/projects/projects_controller.rb @@ -1,11 +1,7 @@ # -*- encoding : utf-8 -*- class Projects::ProjectsController < Projects::BaseController before_filter :authenticate_user! - load_and_authorize_resource - # TODO WTF ? fork, update, sections not authorize - before_filter do |controller| - authorize! params[:action].to_sym, @project if params[:action] != 'index' - end + load_and_authorize_resource :id_param => :project_name # to force member actions load def index @projects = Project.accessible_by(current_ability, :membered) @@ -85,7 +81,7 @@ class Projects::ProjectsController < Projects::BaseController end def remove_user - @project.relations.by_object(current_user).destroy_all + @project.relations.by_actor(current_user).destroy_all flash[:notice] = t("flash.project.user_removed") redirect_to projects_path end diff --git a/app/helpers/git_helper.rb b/app/helpers/git_helper.rb index 78af65bda..753db6e64 100644 --- a/app/helpers/git_helper.rb +++ b/app/helpers/git_helper.rb @@ -4,7 +4,7 @@ module GitHelper def render_path # TODO: Looks ugly, rewrite with clear mind. if @path.present? - if @treeish == "master" + if @treeish == @project.default_branch res = "#{link_to @project.name, tree_path(@project)} / " else res = "#{link_to @project.name, tree_path(@project, @treeish)} / " @@ -36,22 +36,6 @@ module GitHelper res.html_safe end - def render_blob(blob) - blob.data.split("\n").collect do |line| - content_tag :div, line.present? ? h(line) : tag(:br) - end.join.html_safe - end - - def choose_render_way(blob) - case - when blob.mime_type.match(/image/); :image - when blob.binary?; :binary - else - @text = @blob.data.split("\n") - :text - end - end - def iterate_path(path, &block) path.split(File::SEPARATOR).inject('') do |a, e| if e != '.' and e != '..' @@ -63,7 +47,6 @@ module GitHelper end end - # TODO This is very dirty hack. Maybe need to be changed. def branch_selector_options(project) p = params.dup p.delete(:path) if p[:path].present? # to root path @@ -71,10 +54,28 @@ module GitHelper current = url_for(p).split('?', 2).first res = [] - res << [I18n.t('layout.git.repositories.commits'), [truncate(params[:treeish], :length => 20)]] unless (project.branches + project.tags).map(&:name).include?(params[:treeish] || project.default_branch) - res << [I18n.t('layout.git.repositories.branches'), project.branches.map{|b| [truncate(b.name, :length => 20), url_for(p.merge :treeish => b.name).split('?', 2).first]}] - res << [I18n.t('layout.git.repositories.tags'), project.tags.map{|t| [truncate(t.name, :length => 20), url_for(p.merge :treeish => t.name).split('?', 2).first]}] + res << [I18n.t('layout.git.repositories.commits'), [params[:treeish].truncate(20)]] unless project.repo.branches_and_tags.map(&:name).include?(params[:treeish] || project.default_branch) + linking = Proc.new {|t| [t.name.truncate(20), url_for(p.merge :treeish => t.name).split('?', 2).first]} + res << [I18n.t('layout.git.repositories.branches'), project.repo.branches.map(&linking)] + res << [I18n.t('layout.git.repositories.tags'), project.repo.tags.map(&linking)] grouped_options_for_select(res, current) end + + def versions_for_group_select(project) + [ ['Branches', project.repo.branches.map{|b| "latest_#{b.name}"}], + ['Tags', project.repo.tags.map(&:name)] ] + end + + def split_commits_by_date(commits) + commits.sort{|x, y| y.authored_date <=> x.authored_date}.inject({}) do |h, commit| + dt = commit.authored_date + h[dt.year] ||= {} + h[dt.year][dt.month] ||= {} + h[dt.year][dt.month][dt.day] ||= [] + h[dt.year][dt.month][dt.day] << commit + h + end + end end + diff --git a/app/models/activity_feed_observer.rb b/app/models/activity_feed_observer.rb index 94a12fbc2..a62366f1f 100644 --- a/app/models/activity_feed_observer.rb +++ b/app/models/activity_feed_observer.rb @@ -74,7 +74,7 @@ class ActivityFeedObserver < ActiveRecord::Observer change_type = record.change_type branch_name = record.refname.split('/').last - last_commits = record.project.git_repository.repo.log(branch_name, nil).first(3) + last_commits = record.project.repo.log(branch_name, nil).first(3) first_commiter = User.find_by_email(last_commits[0].author.email) unless last_commits.blank? last_commits = last_commits.collect do |commit| #:author => 'author' [commit.sha, commit.message] @@ -87,7 +87,7 @@ class ActivityFeedObserver < ActiveRecord::Observer else kind = 'git_new_push_notification' options = {:project_id => record.project.id, :project_name => record.project.name, :last_commits => last_commits, :branch_name => branch_name, - :change_type => change_type, :user_email => record.project.git_repository.repo.log(branch_name, nil).first.author.email, + :change_type => change_type, :user_email => record.project.repo.repo.log(branch_name, nil).first.author.email, :project_owner => record.project.owner.uname} options.merge!({:user_id => first_commiter.id, :user_name => first_commiter.name}) if first_commiter end diff --git a/app/models/build_list.rb b/app/models/build_list.rb index a3f0b416b..3df87673d 100644 --- a/app/models/build_list.rb +++ b/app/models/build_list.rb @@ -189,7 +189,7 @@ class BuildList < ActiveRecord::Base # TODO: remove 'return' after deployment ABF kernel 2.0 return if pkg.nil? # For old client that does not sends data about packages self.package_version = "#{pkg.platform.name}-#{pkg.version}-#{pkg.release}" - system("cd #{self.project.git_repository.path} && git tag #{self.package_version} #{self.commit_hash}") # TODO REDO through grit + system("cd #{self.project.repo.path} && git tag #{self.package_version} #{self.commit_hash}") # TODO REDO through grit save end diff --git a/app/models/build_list/filter.rb b/app/models/build_list/filter.rb index b6095fc71..48f0b59cc 100644 --- a/app/models/build_list/filter.rb +++ b/app/models/build_list/filter.rb @@ -20,15 +20,7 @@ class BuildList::Filter build_lists = build_lists.scoped_to_is_circle(@options[:is_circle]) if @options[:is_circle].present? build_lists = build_lists.scoped_to_project_name(@options[:project_name]) if @options[:project_name] build_lists = build_lists.by_mass_build(@options[:mass_build_id]) if @options[:mass_build_id] - -# TODO [BuildList#created_at filters] Uncomment here and in build_lists/_filter.html.haml to return filters -# -# if @options[:created_at_start] || @options[:created_at_end] -# build_lists = build_lists.for_creation_date_period(@options[:created_at_start], @options[:created_at_end]) -# end - if @options[:updated_at_start] || @options[:updated_at_end] - build_lists = build_lists.for_notified_date_period(@options[:updated_at_start], @options[:updated_at_end]) - end + build_lists = build_lists.for_notified_date_period(@options[:updated_at_start], @options[:updated_at_end]) if @options[:updated_at_start] || @options[:updated_at_end] end build_lists @@ -49,8 +41,6 @@ class BuildList::Filter @options = HashWithIndifferentAccess.new(options.reverse_merge({ :ownership => nil, :status => nil, - :created_at_start => nil, - :created_at_end => nil, :updated_at_start => nil, :updated_at_end => nil, :arch_id => nil, @@ -63,14 +53,12 @@ class BuildList::Filter })) @options[:ownership] = @options[:ownership].presence || (@project || !@user ? 'index' : 'owned') - @options[:status] = @options[:status].present? ? @options[:status].to_i : nil - @options[:created_at_start] = build_date_from_params(:created_at_start, @options) - @options[:created_at_end] = build_date_from_params(:created_at_end, @options) + @options[:status] = @options[:status].try(:to_i) @options[:updated_at_start] = build_date_from_params(:updated_at_start, @options) @options[:updated_at_end] = build_date_from_params(:updated_at_end, @options) @options[:project_version] = @options[:project_version].presence - @options[:arch_id] = @options[:arch_id].present? ? @options[:arch_id].to_i : nil - @options[:platform_id] = @options[:platform_id].present? ? @options[:platform_id].to_i : nil + @options[:arch_id] = @options[:arch_id].try(:to_i) + @options[:platform_id] = @options[:platform_id].try(:to_i) @options[:is_circle] = @options[:is_circle].present? ? @options[:is_circle] == "1" : nil @options[:bs_id] = @options[:bs_id].presence @options[:project_name] = @options[:project_name].presence diff --git a/app/models/comment.rb b/app/models/comment.rb index e5c22c36f..6960860cc 100644 --- a/app/models/comment.rb +++ b/app/models/comment.rb @@ -15,7 +15,9 @@ class Comment < ActiveRecord::Base attr_accessible :body def commentable - commit_comment? ? project.git_repository.commit(commentable_id.to_s(16)) : super + # raise commentable_id.inspect + # raise commentable_id.to_s(16).inspect + commit_comment? ? project.repo.commit(commentable_id.to_s(16)) : super # TODO leading zero problem end def commentable=(c) diff --git a/app/models/flash_notify.rb b/app/models/flash_notify.rb new file mode 100644 index 000000000..601b197b2 --- /dev/null +++ b/app/models/flash_notify.rb @@ -0,0 +1,24 @@ +require 'digest/md5' + +class FlashNotify < ActiveRecord::Base + # attr_accessible :title, :body + + STATUSES = %w[error success info] + + validates :status, :inclusion => {:in => STATUSES} + validates :body_ru, :body_en, :status, :presence => true + + scope :published, where(:published => true) + + def hash_id + @digest ||= Digest::MD5.hexdigest("#{self.id}-#{self.updated_at}") + end + + def body(language) + read_attribute("body_#{language}") + end + + def should_show?(cookie_hash_id) + cookie_hash_id != hash_id && published + end +end diff --git a/app/models/git/repository.rb b/app/models/git/repository.rb deleted file mode 100644 index 057ba4968..000000000 --- a/app/models/git/repository.rb +++ /dev/null @@ -1,130 +0,0 @@ -# -*- encoding : utf-8 -*- -class Git::Repository - delegate :commits, :commit, :tree, :tags, :heads, :commit_count, :log, :branches, :to => :repo - - attr_accessor :path, :name, :repo, :last_actor - - def initialize(path) - @path = path - @update_callbacks = [] - end - - def master - commits('master', 1).first - end - - def to_s - name - end - - def repo - @repo ||= Grit::Repo.new(path) rescue Grit::Repo.new(GAP_REPO_PATH) - end - - # Adds a callback to be fired after update file. - # - # block - A block that expects this Git::Repository instance and the created - # commit's SHA1 as the arguments. - # - # For example: - # - # after_update_file do |repo, sha| - # # callback body - # end - # - # Returns nothing. - def after_update_file(&block) - @update_callbacks << block - end - - # Writes file to repo and runs 'after_update_file' callbacks - # - # path - path to file in repository - # data - new content of file - # options - an optional Hash of options - # :head - branch name to write this commit to - # (Default: 'master') - # :actor - author of this commit. (See Git::Repository#get_actor) - # (Default: nil) - # :message - commit message - # (Default: "Updated file ") - # - # Returns commits sha if committing was successful and false otherwise - def update_file(path, data, options = {}) - head = options[:head].to_s || 'master' - actor = get_actor(options[:actor]) - filename = File.split(path).last - message = options[:message] - message = "Updated file #{filename}" if message.nil? or message.empty? - - # can not write to unexisted branch - return false if branches.select{|b| b.name == head}.size != 1 - - parent = commits(head).first - - index = repo.index - index.read_tree(parent.tree.id) - - # can not create new file - return false if (index.current_tree / path).nil? - - index.add(path, data) - sha = index.commit(message, :parents => [parent], :actor => actor, - :last_tree => parent.tree.id, :head => head) - # call all defined callbacks - @update_callbacks.each do |cb| - cb.call(self, sha) - end - sha - end - - def self.create(path) - repo = Grit::Repo.init_bare(path) - repo.enable_daemon_serve - end - - def paginate_commits(treeish, options = {}) - options[:page] = 1 unless options[:page].present? - options[:page] = options[:page].to_i - - options[:per_page] = 20 unless options[:per_page].present? - options[:per_page] = options[:per_page].to_i - - skip = options[:per_page] * (options[:page] - 1) - last_page = (skip + options[:per_page]) >= commit_count(treeish) - - [commits(treeish, options[:per_page], skip), options[:page], last_page] - end - - # Pretty object inspection - def inspect - %Q{#} - end - - protected - - # Creates new Grit::Actor instance - # - # Might be: - # * A Hash containing :name and :email - # * An instance of Grit::Actor - # * A String like "John Doe - # * Any object that responds to `name` and `email` methods - def get_actor(actor = nil) - @last_actor = case actor.class.to_s - when 'Grit::Actor' then options[:actor] - when 'Hash' then Grit::Actor.new(actor[:name], actor[:email]) - when 'String' then Grit::Actor.from_stirng(actor) - else begin - if actor.respond_to?(:name) and actor.respond_to?(:email) - Grit::Actor.new(actor.name, actor.email) - else - config = Grit::Config.new(repo) - Grit::Actor.new(config['user.name'], config['user.email']) - end - end - end - @last_actor - end - -end diff --git a/app/models/project.rb b/app/models/project.rb index e00e74a11..c69f1125e 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -25,9 +25,6 @@ class Project < ActiveRecord::Base validates :owner, :presence => true validate { errors.add(:base, :can_have_less_or_equal, :count => MAX_OWN_PROJECTS) if owner.projects.size >= MAX_OWN_PROJECTS } - validates_attachment_size :srpm, :less_than => 500.megabytes - validates_attachment_content_type :srpm, :content_type => ['application/octet-stream', "application/x-rpm", "application/x-redhat-package-manager"], :message => I18n.t('layout.invalid_content_type') - attr_accessible :name, :description, :visibility, :srpm, :is_package, :default_branch, :has_issues, :has_wiki attr_readonly :name @@ -40,34 +37,50 @@ class Project < ActiveRecord::Base 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 }))") } after_create :attach_to_personal_repository - after_create :create_git_repo - after_create {|p| p.fork_git_repo unless p.is_root?} - after_save :create_wiki - after_destroy :destroy_git_repo - after_destroy :destroy_wiki - after_save {|p| p.import_attached_srpm if p.srpm?} # later with resque # should be after create_git_repo - # after_rollback lambda { destroy_git_repo rescue true if new_record? } - - has_ancestry - - has_attached_file :srpm + has_ancestry :orphan_strategy => :rootify #:adopt not available yet include Modules::Models::Owner + include Modules::Models::Git + include Modules::Models::Wiki + + class << self + def find_by_owner_and_name(owner_name, project_name) + owner = User.find_by_uname(owner_name) || Group.find_by_uname(owner_name) || User.by_uname(owner_name).first || Group.by_uname(owner_name).first and + scoped = where(:owner_id => owner.id, :owner_type => owner.class) and + scoped.find_by_name(project_name) || scoped.by_name(project_name).first + # owner.projects.find_by_name(project_name) || owner.projects.by_name(project_name).first # TODO force this work? + end + + def find_by_owner_and_name!(owner_name, project_name) + find_by_owner_and_name(owner_name, project_name) or raise ActiveRecord::RecordNotFound + end + end def to_param name end - def self.find_by_owner_and_name(owner_name, project_name) - owner = User.find_by_uname(owner_name) || Group.find_by_uname(owner_name) || User.by_uname(owner_name).first || Group.by_uname(owner_name).first and - scoped = where(:owner_id => owner.id, :owner_type => owner.class) and - scoped.find_by_name(project_name) || scoped.by_name(project_name).first - # owner.projects.find_by_name(project_name) || owner.projects.by_name(project_name).first # TODO force this work? + def members + collaborators + groups.map(&:members).flatten end - def self.find_by_owner_and_name!(owner_name, project_name) - find_by_owner_and_name(owner_name, project_name) or raise ActiveRecord::RecordNotFound + def platforms + @platforms ||= repositories.map(&:platform).uniq + end + + def owner_and_admin_ids + recipients = self.relations.by_role('admin').where(:actor_type => 'User').map { |rel| rel.read_attribute(:actor_id) } + recipients = recipients | [self.owner_id] if self.owner_type == 'User' + recipients + end + + def public? + visibility == 'open' + end + + def owner?(user) + owner == user end def build_for(platform, user, arch = 'i586', auto_publish = false, mass_build_id = nil, priority = 0) @@ -93,85 +106,6 @@ class Project < ActiveRecord::Base end end - def tags - self.git_repository.tags #.sort_by{|t| t.name.gsub(/[a-zA-Z.]+/, '').to_i} - end - - def branches - self.git_repository.branches - end - - def last_active_branch - @last_active_branch ||= branches.inject do |r, c| - r_last = r.commit.committed_date || r.commit.authored_date unless r.nil? - c_last = c.commit.committed_date || c.commit.authored_date - if r.nil? or r_last < c_last - r = c - end - r - end - @last_active_branch - end - - def branch(name = nil) - name = default_branch if name.blank? - branches.select{|b| b.name == name}.first - end - - def tree_info(tree, treeish = nil, path = nil) - treeish = tree.id unless treeish.present? - # initialize result as hash of => nil - res = (tree.trees.sort + tree.blobs.sort).inject({}){|h, e| h.merge!({e => nil})} - # fills result vith commits that describes this file - res = res.inject(res) do |h, (entry, commit)| - # only if commit == nil ... - if commit.nil? and entry.respond_to? :name - # ... find last commit corresponds to this file ... - c = git_repository.log(treeish, File.join([path, entry.name].compact), :max_count => 1).first - # ... and add it to result. - h[entry] = c - # find another files, that linked to this commit and set them their commit - # c.diffs.map{|diff| diff.b_path.split(File::SEPARATOR, 2).first}.each do |name| - # h.each_pair do |k, v| - # h[k] = c if k.name == name and v.nil? - # end - # end - end - h - end - end - - def versions - tags.map(&:name) + branches.map{|b| "latest_#{b.name}"} - end - - def versions_for_group_select - [ - ['Branches', branches.map{|b| "latest_#{b.name}"}], - ['Tags', tags.map(&:name)] - ] - end - - def members - collaborators + groups.map(&:members).flatten - end - - def git_repository - @git_repository ||= Git::Repository.new(path) - end - - def git_repo_name - File.join owner.uname, name - end - - def wiki_repo_name - File.join owner.uname, "#{name}.wiki" - end - - def public? - visibility == 'open' - end - def fork(new_owner) dup.tap do |c| c.parent_id = id @@ -181,12 +115,8 @@ class Project < ActiveRecord::Base end end - def path - build_path(git_repo_name) - end - - def wiki_path - build_wiki_path(git_repo_name) + def human_average_build_time + I18n.t("layout.projects.human_average_build_time", {:hours => (average_build_time/3600).to_i, :minutes => (average_build_time%3600/60).to_i}) end def xml_rpc_create(repository) @@ -207,97 +137,9 @@ class Project < ActiveRecord::Base end end - def platforms - @platforms ||= repositories.map(&:platform).uniq - end - - def import_srpm(srpm_path = srpm.path, branch_name = 'import') - system("#{Rails.root.join('bin', 'import_srpm.sh')} #{srpm_path} #{path} #{branch_name} >> /dev/null 2>&1") - end - - def owner?(user) - owner == user - end - - def owner_and_admin_ids - recipients = self.relations.by_role('admin').where(:actor_type => 'User').map { |rel| rel.read_attribute(:actor_id) } - recipients = recipients | [self.owner_id] if self.owner_type == 'User' - recipients - end - - def human_average_build_time - time = average_build_time - I18n.t("layout.projects.human_average_build_time", {:hours => (time/3600).to_i, :minutes => (time%3600/60).to_i}) - end - protected - def build_path(dir) - File.join(APP_CONFIG['root_path'], 'git_projects', "#{dir}.git") - end - - def build_wiki_path(dir) - File.join(APP_CONFIG['root_path'], 'git_projects', "#{dir}.wiki.git") - end - def attach_to_personal_repository repositories << self.owner.personal_repository if !repositories.exists?(:id => self.owner.personal_repository) end - - def create_git_repo - if is_root? - Grit::Repo.init_bare(path) - write_hook - end - end - - def fork_git_repo - dummy = Grit::Repo.new(path) rescue parent.git_repository.repo.fork_bare(path) - write_hook - end - later :fork_git_repo, :queue => :fork_import - - def destroy_git_repo - FileUtils.rm_rf path - end - - def import_attached_srpm - if srpm? - import_srpm # srpm.path - self.srpm = nil; save # clear srpm - end - end - later :import_attached_srpm, :queue => :fork_import - - def create_wiki - if has_wiki && !FileTest.exist?(wiki_path) - Grit::Repo.init_bare(wiki_path) - wiki = Gollum::Wiki.new(wiki_path, {:base_path => Rails.application.routes.url_helpers.project_wiki_index_path(owner, self)}) - wiki.write_page('Home', :markdown, I18n.t("wiki.seed.welcome_content"), - {:name => owner.name, :email => owner.email, :message => 'Initial commit'}) - end - end - - def destroy_wiki - FileUtils.rm_rf wiki_path - end - - def write_hook - is_production = Rails.env == "production" - hook = File.join(::Rails.root.to_s, 'tmp', "post-receive-hook") - FileUtils.cp(File.join(::Rails.root.to_s, 'bin', "post-receive-hook.partial"), hook) - File.open(hook, 'a') do |f| - s = "\n /bin/bash -l -c \"cd #{is_production ? '/srv/rosa_build/current' : Rails.root.to_s} && #{is_production ? 'RAILS_ENV=production' : ''} bundle exec rake hook:enqueue[$owner,$reponame,$newrev,$oldrev,$ref,$newrev_type,$oldrev_type]\"" - s << " > /dev/null 2>&1" if is_production - s << "\ndone\n" - f.write(s) - f.chmod(0755) - end - - hook_file = File.join(path, 'hooks', 'post-receive') - FileUtils.cp(hook, hook_file) - FileUtils.rm_rf(hook) - - rescue Exception # FIXME - end end diff --git a/app/views/admin/flash_notifies/_form.html.haml b/app/views/admin/flash_notifies/_form.html.haml new file mode 100644 index 000000000..c609dd20b --- /dev/null +++ b/app/views/admin/flash_notifies/_form.html.haml @@ -0,0 +1,21 @@ +.leftlist= f.label :body_ru, t("activerecord.attributes.flash_notify.body_ru"), :class => :label +.rightlist= f.text_area :body_ru, :class => 'text_field' +.both + +.leftlist= f.label :body_en, t("activerecord.attributes.flash_notify.body_en"), :class => :label +.rightlist= f.text_area :body_en, :class => 'text_field' +.both + +.leftlist= f.label :status, t("activerecord.attributes.flash_notify.status"), :class => :label +.rightlist= f.select :status, FlashNotify::STATUSES +.both + +.leftlist= f.label :published, t("activerecord.attributes.flash_notify.published"), :class => :label +.rightlist= f.check_box :published +.both + +.button_block + = submit_tag t("layout.save") + %span.text_button_padding= t("layout.or") + = link_to t("layout.cancel"), admin_flash_notifies_path, :class => "button" + diff --git a/app/views/admin/flash_notifies/edit.html.haml b/app/views/admin/flash_notifies/edit.html.haml new file mode 100644 index 000000000..a1f10e1cd --- /dev/null +++ b/app/views/admin/flash_notifies/edit.html.haml @@ -0,0 +1,6 @@ +%h3= t("layout.flash_notifies.edit_header") + += form_for @flash_notify, :url => admin_flash_notify_path(@flash_notify), :html => { :class => :form } do |f| + = render "form", :f => f + += render 'submenu' diff --git a/app/views/admin/flash_notifies/index.html.haml b/app/views/admin/flash_notifies/index.html.haml new file mode 100644 index 000000000..9578d1a0e --- /dev/null +++ b/app/views/admin/flash_notifies/index.html.haml @@ -0,0 +1,22 @@ += link_to t("layout.flash_notifies.new"), new_admin_flash_notify_path, :class => 'button' if can? :create, FlashNotify + +%table#myTable.tablesorter.flash_notifys{:cellspacing => "0", :cellpadding => "0"} + %thead + %tr + %th.th1= t("activerecord.attributes.flash_notify.body_en") + %th.th2= t("activerecord.attributes.flash_notify.body_ru") + %th.th3= t("activerecord.attributes.flash_notify.published") + %th.th3= t("layout.flash_notifies.actions") + %tbody + - @flash_notifies.each do |flash_notify| + %tr{:class => cycle("odd", "even")} + %td= flash_notify.body_en.truncate 18 + %td= flash_notify.body_ru.truncate 18 + %td= flash_notify.published + %td + = link_to t("layout.flash_notifies.edit"), edit_admin_flash_notify_path(flash_notify) + = link_to t("layout.flash_notifies.delete"), admin_flash_notify_path(flash_notify), :method => :delete, :confirm => t("layout.mass_builds.cancel_confirm") if can?(:delete, flash_notify) + += will_paginate @flash_notifies + += render 'submenu' diff --git a/app/views/admin/flash_notifies/new.html.haml b/app/views/admin/flash_notifies/new.html.haml new file mode 100644 index 000000000..0177e384e --- /dev/null +++ b/app/views/admin/flash_notifies/new.html.haml @@ -0,0 +1,6 @@ +%h3= t("layout.flash_notifies.new_header") + += form_for @flash_notify, :url => admin_flash_notifies_path, :html => { :class => :form } do |f| + = render "form", :f => f + += render 'submenu' diff --git a/app/views/admin/users/_users_ajax.js.erb b/app/views/admin/users/_users_ajax.js.erb deleted file mode 100644 index 76db767ec..000000000 --- a/app/views/admin/users/_users_ajax.js.erb +++ /dev/null @@ -1,19 +0,0 @@ -{ - "sEcho": <%=h params[:sEcho].to_i || -1 %>, - "iTotalRecords": <%= @total_users %>, - "iTotalDisplayRecords": <%= @total_user %>, - "aaData": [ - <% @users.each do |user| %> - [ - "<%= user.name %>", - "<%= user.uname %>", - "<%= user.email %>", - "'><%= user.role %>", - "<%= j raw [(link_to t('layout.show'), user if can? :read, user), - (link_to t('layout.edit'), edit_admin_user_path(user) if can? :edit, user), - (link_to t('layout.delete'), admin_user_path(user), :method => :delete, :confirm => t('layout.users.confirm_delete') if can? :destroy, user) - ].compact.join(' | ') %>" - ]<%= user == @users.last ? '' : ',' %> - <% end %> - ] -} diff --git a/app/views/admin/users/_users_ajax.json.jbuilder b/app/views/admin/users/_users_ajax.json.jbuilder new file mode 100644 index 000000000..f595d528d --- /dev/null +++ b/app/views/admin/users/_users_ajax.json.jbuilder @@ -0,0 +1,21 @@ +users = @users.map do |user| + link_block = [ + (link_to t('layout.show'), user if can? :read, user), + (link_to t('layout.edit'), edit_admin_user_path(user) if can? :edit, user), + (link_to t('layout.delete'), admin_user_path(user), :method => :delete, :confirm => t('layout.users.confirm_delete') if can? :destroy, user) + ].compact.join(' | ').html_safe + + [ + user.name, + user.uname, + user.email, + content_tag(:span, user.role, :style => user.access_locked? ? 'background: #FEDEDE' : ''), + link_block + ] +end + + +json.sEcho params[:sEcho].to_i || -1 +json.iTotalRecords @total_users +json.iTotalDisplayRecords @users.count +json.aaData users diff --git a/app/views/layouts/_notifies.html.haml b/app/views/layouts/_notifies.html.haml new file mode 100644 index 000000000..82ca70300 --- /dev/null +++ b/app/views/layouts/_notifies.html.haml @@ -0,0 +1,10 @@ +- if current_user || APP_CONFIG['anonymous_access'] + .flash_notify + - if (flash_notify = FlashNotify.published.first) && flash_notify.should_show?(cookies[:flash_notify_hash]) + .alert{:class => "alert-#{flash_notify.status}"} + = flash_notify.body I18n.locale + %a.close#close-alert{:'data-dismiss'=>"alert", :href=>"#"} × + + :javascript + var FLASH_HASH_ID = "#{flash_notify.hash_id}"; + var FLASH_EXPIRES_AT = "#{Date.today + 1.year}"; diff --git a/app/views/layouts/application.html.haml b/app/views/layouts/application.html.haml index 642d9b82e..9f62ca9a2 100644 --- a/app/views/layouts/application.html.haml +++ b/app/views/layouts/application.html.haml @@ -47,6 +47,7 @@ = yield :feed_tabs .both = render "layouts/flashes" + = render "layouts/notifies" %article - if content_for?(:sidebar) %aside= yield :sidebar @@ -54,4 +55,4 @@ .both %footer= render "layouts/menu/bottom" - = render 'layouts/counters' unless current_user.try(:admin?) + = render 'layouts/counters' if !current_user.try(:admin?) && Rails.env.production? diff --git a/app/views/platforms/repositories/_proj_ajax.js.erb b/app/views/platforms/repositories/_proj_ajax.js.erb deleted file mode 100644 index 3058ffbb2..000000000 --- a/app/views/platforms/repositories/_proj_ajax.js.erb +++ /dev/null @@ -1,15 +0,0 @@ -{ - "sEcho": <%=h params[:sEcho].to_i || -1 %>, - "iTotalRecords": <%= @total_projects %>, - "iTotalDisplayRecords": <%= @total_project %>, - "aaData": [ - <% @projects.each do |project| %> - [ - "<%=j link_to(project.name_with_owner, project) %>", - "<%= truncate(project.description || '', :length => 60).gsub(/\n|\r|\t/, ' ') %>", - "<%=j link_to t("layout.add"), url_for(:controller => :repositories, :action => :add_project, :project_id => project.id) %>" - ]<%= project == @projects.last ? '' : ',' %> - <% end %> - ] -} - diff --git a/app/views/platforms/repositories/_proj_ajax.json.jbuilder b/app/views/platforms/repositories/_proj_ajax.json.jbuilder new file mode 100644 index 000000000..39d2b7a3a --- /dev/null +++ b/app/views/platforms/repositories/_proj_ajax.json.jbuilder @@ -0,0 +1,12 @@ +projs = @projects.map do |project| + [ + link_to(project.name_with_owner, project), + truncate(project.description || '', :length => 60).gsub(/\n|\r|\t/, ' '), + link_to(t("layout.add"), url_for(:controller => :repositories, :action => :add_project, :project_id => project.id)) + ] +end + +json.sEcho params[:sEcho] || -1 +json.iTotalRecords @total_projects +json.iTotalDisplayRecords @projects.count +json.aaData projs diff --git a/app/views/platforms/repositories/_project.js.erb b/app/views/platforms/repositories/_project.js.erb deleted file mode 100644 index 2dd623397..000000000 --- a/app/views/platforms/repositories/_project.js.erb +++ /dev/null @@ -1,31 +0,0 @@ -{ - "sEcho": <%=h params[:sEcho].to_i || -1 %>, - "iTotalRecords": <%= @total_projects %>, - "iTotalDisplayRecords": <%= @total_project %>, - "aaData": [ - <% @projects.each do |project| %> - [ - "<%=( - "
" + - j(image_tag(visibility_icon(project.visibility))) + - "
" + - "
" + - j(link_to("#{project.owner.respond_to?(:uname) ? project.owner.uname : project.owner.name} / #{project.name}", project)) + - "
").html_safe - %>", - "<%= truncate(project.description || '', :length => 60).gsub(/\n|\r|\t/, ' ') %>", - "<%= - if can? :remove_project, @repository - j(link_to(' '.html_safe, - remove_project_platform_repository_path(@platform, @repository, :project_id => project.id), - :method => :delete, :confirm => t("layout.confirm") - ) - ) - else - '' - end - %>" - ]<%= project == @projects.last ? '' : ',' %> - <% end %> - ] -} diff --git a/app/views/platforms/repositories/_project.json.jbuilder b/app/views/platforms/repositories/_project.json.jbuilder new file mode 100644 index 000000000..f3e1a20c2 --- /dev/null +++ b/app/views/platforms/repositories/_project.json.jbuilder @@ -0,0 +1,23 @@ + projs = @projects.map do |pr| + [ + content_tag(:div, image_tag(visibility_icon(pr.visibility)), :class => 'table-sort-left') + + content_tag(:div, link_to(pr.name_with_owner, pr), :class => 'table-sort-right'), + + truncate(pr.description || '', :length => 60).gsub(/\n|\r|\t/, ' '), + + if can? :remove_project, @repository + link_to( + remove_project_platform_repository_path(@platform, @repository, :project_id => pr.id), + :method => :delete, :confirm => t("layout.confirm")) do + content_tag(:span, " ".html_safe, :class => 'delete') + end + else + '' + end + ] + end + +json.sEcho params[:sEcho].to_i || -1 +json.iTotalRecords @total_projects +json.iTotalDisplayRecords @projects.count +json.aaData projs diff --git a/app/views/projects/base/_repo_block.html.haml b/app/views/projects/base/_repo_block.html.haml index 0870762d5..f301d63b3 100644 --- a/app/views/projects/base/_repo_block.html.haml +++ b/app/views/projects/base/_repo_block.html.haml @@ -6,8 +6,8 @@ =image_tag 'zip.png', :alt => 'ZIP' %b.caret %ul.dropdown-menu - %li=link_to "tar.gz", archive_path(project, 'tar', @treeish) - %li=link_to "zip", archive_path(project, 'zip', @treeish) + %li=link_to "tar.gz", archive_path(project, @treeish, 'tar') + %li=link_to "zip", archive_path(project, @treeish, 'zip') = text_field_tag :url, git_repo_url(project.git_repo_name), :class => 'name', :spellcheck => 'false', :readonly => true .git_help ? diff --git a/app/views/projects/base/_submenu.html.haml b/app/views/projects/base/_submenu.html.haml index c4bb613fd..8cb83b928 100644 --- a/app/views/projects/base/_submenu.html.haml +++ b/app/views/projects/base/_submenu.html.haml @@ -1,12 +1,12 @@ - content_for :submenu do - - act = action_name.to_sym; contr = controller_name.to_sym + - act = action_name.to_sym; contr = controller_name.to_sym; treeish = params[:treeish].presence || @project.default_branch .left .table-sort-left=image_tag visibility_icon(@project.visibility) .table-sort-right=@project.name %nav %ul - %li= link_to t("project_menu.project"), project_path(@project), :class => (act.in?([:show, :edit]) && contr.in?([:trees, :blobs]) ? 'active' : nil) - %li= link_to t("project_menu.commits"), commits_path(@project), :class => (act.in?([:index, :show]) && contr == :commits ? 'active' : nil) + %li= link_to t("project_menu.project"), tree_path(@project, treeish), :class => (act.in?([:show, :edit]) && contr.in?([:trees, :blobs]) ? 'active' : nil) + %li= link_to t("project_menu.commits"), commits_path(@project, treeish), :class => (act.in?([:index, :show]) && contr == :commits ? 'active' : nil) - if @project.is_package and can?(:read, @project => BuildList) %li= link_to t("project_menu.builds"), project_build_lists_path(@project), :class => (contr == :build_lists ? 'active' : nil) - if @project.has_issues diff --git a/app/views/projects/build_lists/new.html.haml b/app/views/projects/build_lists/new.html.haml index 10024025a..ccda36113 100644 --- a/app/views/projects/build_lists/new.html.haml +++ b/app/views/projects/build_lists/new.html.haml @@ -13,10 +13,7 @@ %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.project_version") - - if controller.action_name == 'new' - .lineForm= f.select :project_version, @project.versions_for_group_select, :selected => "latest_" + @project.default_branch - - else - .lineForm= f.select :project_version, @project.versions_for_group_select + .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") - Arch.recent.each do |arch| .both diff --git a/app/views/projects/build_lists/show.html.haml b/app/views/projects/build_lists/show.html.haml index f061efcf3..f0f3f1d19 100644 --- a/app/views/projects/build_lists/show.html.haml +++ b/app/views/projects/build_lists/show.html.haml @@ -35,7 +35,7 @@ .both .leftlist= t("activerecord.attributes.build_list.update_type") .rightlist - - if @build_list.can_publish? and can?(:publish, @build_list) + - if @build_list.can_publish? && can?(:publish, @build_list) = f.select :update_type, options_for_select(build_list_classified_update_types, @build_list.update_type) - else = @build_list.update_type @@ -81,11 +81,11 @@ = "#{@build_list.human_current_duration} / #{@build_list.project.human_average_build_time}" .both - - if @build_list.can_cancel? and can?(:cancel, @build_list) + - if @build_list.can_cancel? && can?(:cancel, @build_list) = link_to t("layout.build_lists.cancel"), cancel_build_list_path(@build_list), :method => :put, :confirm => t("layout.confirm"), :class => 'button' - - if @build_list.can_publish? and @build_list.save_to_platform.released and @build_list.advisory.nil? + - if @build_list.can_publish? && @build_list.save_to_platform.released && @build_list.advisory.nil? && can?(:publish, @build_list) #advisory_block .leftlist= label_tag :attach_advisory, t("layout.build_lists.attached_advisory") .rightlist @@ -123,8 +123,8 @@ var r = new Rosa.Routers.BuildListsAdvisoriesRouter(); }); - = submit_tag t("layout.publish"), :confirm => t("layout.confirm"), :name => 'publish' if @build_list.can_publish? and can?(:publish, @build_list) - = submit_tag t("layout.reject_publish"), :confirm => t("layout.confirm"), :name => 'reject_publish' if @build_list.can_reject_publish? and can?(:reject_publish, @build_list) + = submit_tag t("layout.publish"), :confirm => t("layout.confirm"), :name => 'publish' if @build_list.can_publish? && can?(:publish, @build_list) + = submit_tag t("layout.reject_publish"), :confirm => t("layout.confirm"), :name => 'reject_publish' if @build_list.can_reject_publish? && can?(:reject_publish, @build_list) .hr %h3= t("layout.build_lists.items_header") diff --git a/app/views/projects/git/base/_fork.html.haml b/app/views/projects/git/base/_fork.html.haml index ccb928bff..1e733798f 100644 --- a/app/views/projects/git/base/_fork.html.haml +++ b/app/views/projects/git/base/_fork.html.haml @@ -1,11 +1,14 @@ - if can? :fork, @project .r#fork-and-edit= link_to t('layout.projects.fork_and_edit'), '#forkModal', :class => 'button', 'data-toggle' => 'modal' - #forkModal.modal{:style => 'display: none;'} + #forkModal.modal.fork-modal{:style => 'display: none;'} .modal-header %a.close{"data-dismiss" => "modal"} × %h3=t 'layout.projects.fork_modal_header' - .modal-footer=render 'choose_fork', :owner => current_user - - Group.can_own_project(current_user).each do |group| - .modal-footer=render 'choose_fork', :owner => group + .modal-body.modal-body-fork + =render 'choose_fork', :owner => current_user + %hr.bootstrap + - Group.can_own_project(current_user).each do |group| + =render 'choose_fork', :owner => group + %hr.bootstrap - if can? :create, @project.build_lists.new .r{:style => "display: block"}= link_to t('layout.projects.new_build_list'), new_project_build_list_path(@project), :class => 'button' diff --git a/app/views/projects/git/blobs/_editor.html.haml b/app/views/projects/git/blobs/_editor.html.haml index 874945aee..1298ff0c0 100644 --- a/app/views/projects/git/blobs/_editor.html.haml +++ b/app/views/projects/git/blobs/_editor.html.haml @@ -4,7 +4,7 @@ = render 'fork' .both -= form_tag blob_path(@project, @treeish, @path), :name => 'blob-editor', :method => :put do += form_tag edit_blob_path(@project, @treeish, @path), :name => 'blob-editor', :method => :put do .file= text_area_tag :content, @blob.data, :id => 'code' .both diff --git a/app/views/projects/git/blobs/_render_as_binary.html.haml b/app/views/projects/git/blobs/_render_as_binary.html.haml new file mode 100644 index 000000000..bd7379a10 --- /dev/null +++ b/app/views/projects/git/blobs/_render_as_binary.html.haml @@ -0,0 +1,8 @@ +%table.table.blob + %tr + %td.lines + %td.blob + :plain +
+
#{link_to @blob.basename, raw_path(@project, @treeish, @path)}
+
\ No newline at end of file diff --git a/app/views/projects/git/blobs/_render_as_image.html.haml b/app/views/projects/git/blobs/_render_as_image.html.haml new file mode 100644 index 000000000..ae1ef4884 --- /dev/null +++ b/app/views/projects/git/blobs/_render_as_image.html.haml @@ -0,0 +1,8 @@ +%table.table.blob + %tr + %td.lines + %td.blob + :plain +
+
+
\ No newline at end of file diff --git a/app/views/projects/git/blobs/_render_as_text.html.haml b/app/views/projects/git/blobs/_render_as_text.html.haml new file mode 100644 index 000000000..3105d704e --- /dev/null +++ b/app/views/projects/git/blobs/_render_as_text.html.haml @@ -0,0 +1,6 @@ +.gutter= render_line_numbers(@blob.loc) +#output.formatted.cm-s-default + %pre#code + :preserve + #{h(@blob.data).html_safe} +.both diff --git a/app/views/projects/git/blobs/_show.html.haml b/app/views/projects/git/blobs/_show.html.haml index f867189fd..b808cefc1 100644 --- a/app/views/projects/git/blobs/_show.html.haml +++ b/app/views/projects/git/blobs/_show.html.haml @@ -4,37 +4,10 @@ = render 'fork' .both -- render_way = choose_render_way(@blob) .file - .top= render 'top', :render_way => render_way - .data - - case render_way - - when :image - %table.table.blob - %tr - %td.lines - %td.blob - :plain -
-
-
- - when :text - .gutter= render_line_numbers(@text.length) - #output.formatted.cm-s-default - %pre#code - =#{render_blob(@blob)} - :preserve - #{h(@blob.data).html_safe} - .both - - when :binary - %table.table.blob - %tr - %td.lines - %td.blob - :plain -
-
#{ link_to @blob.basename, raw_path(@project, @treeish, @path) }
-
+ .top= render 'top' + .data= render "render_as_#{@blob.render_as}" + :javascript $(document).ready(function() { var text = $('#code').text().replace(/&/gi, '&'); diff --git a/app/views/projects/git/blobs/_top.html.haml b/app/views/projects/git/blobs/_top.html.haml index 8073aa9db..3fa62790b 100644 --- a/app/views/projects/git/blobs/_top.html.haml +++ b/app/views/projects/git/blobs/_top.html.haml @@ -1,20 +1,20 @@ .l = @blob.mode \| - - if render_way == :text - #{@text.length} lines (#{@text.select{|s| s.strip.length > 0}.length} sloc) + - if @blob.render_as == :text + #{@blob.loc} lines (#{@blob.sloc} sloc) \| = number_to_human_size @blob.size .r - - if render_way == :text and can? :write, @project and @treeish.in? @project.branches.map(&:name) + - if @blob.render_as == :text && can?(:write, @project) && @branch.present? = link_to "Edit", edit_blob_path(@project, @treeish, @path) \| - - if render_way == :text and params[:action] != 'show' + - if @blob.render_as == :text && params[:action] != 'show' = link_to "Normal", blob_path(@project, @treeish, @path) \| = link_to "Raw", raw_path(@project, @treeish, @path) \| - - if render_way == :text and params[:action] != 'blame' + - if @blob.render_as == :text && params[:action] != 'blame' = link_to "Blame", blame_path(@project, @treeish, @path) \| = link_to "History", commits_path(@project, @treeish, @path) diff --git a/app/views/projects/git/blobs/blame.html.haml b/app/views/projects/git/blobs/blame.html.haml index 81fef4b00..9f19328e8 100644 --- a/app/views/projects/git/blobs/blame.html.haml +++ b/app/views/projects/git/blobs/blame.html.haml @@ -20,7 +20,6 @@ .l= render 'whereami' .both - - render_way = choose_render_way(@blob) .file - .top= render 'top', :render_way => render_way + .top= render 'top' .blame_data= render 'blame_table' if @blame.first.first.present? diff --git a/app/views/projects/git/commits/_commit_diff.html.haml b/app/views/projects/git/commits/_commit_diff.html.haml index c15055706..46f639af9 100644 --- a/app/views/projects/git/commits/_commit_diff.html.haml +++ b/app/views/projects/git/commits/_commit_diff.html.haml @@ -7,4 +7,4 @@ .r= link_to "view file @ #{short_hash_id(commit_id)}", blob_path(@project, commit_id, commit_diff.b_path) .clear - .diff_data= render_diff(commit_diff) unless (@git_repository.tree(commit_id) / commit_diff.b_path).binary? \ No newline at end of file + .diff_data= render_diff(commit_diff) unless (@project.repo.tree(commit_id) / commit_diff.b_path).binary? \ No newline at end of file diff --git a/app/views/projects/git/commits/_show.html.haml b/app/views/projects/git/commits/_show.html.haml index 9e6e6a30c..9815b5e2d 100644 --- a/app/views/projects/git/commits/_show.html.haml +++ b/app/views/projects/git/commits/_show.html.haml @@ -13,7 +13,6 @@ -begin = render_commit_stats(stats) - = render :partial => 'commit_diff', :collection => @commit.diffs - rescue Grit::Git::GitTimeout %p= t 'layout.git.repositories.commit_diff_too_big' diff --git a/app/views/projects/git/commits/index.html.haml b/app/views/projects/git/commits/index.html.haml index f3f9cca11..e8221fb1e 100644 --- a/app/views/projects/git/commits/index.html.haml +++ b/app/views/projects/git/commits/index.html.haml @@ -3,4 +3,4 @@ = render 'repo_block', :project => @project = render :partial => 'commits', :object => @commits -= render 'paginate' if @render_paginate += render 'paginate' if @path.blank? diff --git a/app/views/projects/git/trees/_show.html.haml b/app/views/projects/git/trees/_show.html.haml index 2bf2868aa..35bae8bea 100644 --- a/app/views/projects/git/trees/_show.html.haml +++ b/app/views/projects/git/trees/_show.html.haml @@ -31,7 +31,7 @@ .pic= image_tag 'folder.png' .name= link_to(entry.name, tree_path(@project, @treeish, entry_path), :class => 'files-see') %td - %span{:style => "display: none;"}= commit.committed_date || commit.authored_date - = l(commit.committed_date || commit.authored_date, :format => :short) + %span{:style => "display: none;"}= date = commit.committed_date || commit.authored_date + = l(date, :format => :short) %td= commit.short_message %td= (commit.committer || commit.author).name \ No newline at end of file diff --git a/app/views/projects/projects/_form.html.haml b/app/views/projects/projects/_form.html.haml index ffede9552..9a7b90ba2 100644 --- a/app/views/projects/projects/_form.html.haml +++ b/app/views/projects/projects/_form.html.haml @@ -35,7 +35,7 @@ .both - if [:edit, :update].include? act .leftlist= t("activerecord.attributes.project.default_branch") - .rightlist= f.select :default_branch, options_from_collection_for_select(@project.branches, :name, :name, @project.default_branch), :class => 'sel80', :id => 'branch_selector' + .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 diff --git a/app/views/users/base/_form.html.haml b/app/views/users/base/_form.html.haml index d88807a92..4baa5218e 100644 --- a/app/views/users/base/_form.html.haml +++ b/app/views/users/base/_form.html.haml @@ -43,5 +43,5 @@ .both .leftlist \  -.rightlist= submit_tag t("layout.save") +.rightlist= submit_tag t("layout.save"), :data => {:"disable-with" => t("layout.saving")} .both diff --git a/config/locales/en.yml b/config/locales/en.yml index 0b8acbf02..9abd215e8 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -26,6 +26,7 @@ en: delete: Erase delete_selected: Remove selected save: Save + saving: Saving clone: Clone search_by_name: Filter by name are_you_sure: "Sure?" diff --git a/config/locales/menu.en.yml b/config/locales/menu.en.yml index b12e73c29..5b6b58ac8 100644 --- a/config/locales/menu.en.yml +++ b/config/locales/menu.en.yml @@ -37,5 +37,6 @@ en: admins_menu: users: Users register_requests: Invites + flash_notifies: Notifies event_logs: Event log resque_server: Resque diff --git a/config/locales/menu.ru.yml b/config/locales/menu.ru.yml index 6850b6b00..e4a81ad6b 100644 --- a/config/locales/menu.ru.yml +++ b/config/locales/menu.ru.yml @@ -37,5 +37,6 @@ ru: admins_menu: users: Пользователи register_requests: Инвайты + flash_notifies: Оповещения event_logs: Лог событий resque_server: Resque diff --git a/config/locales/models/flash_notify.en.yml b/config/locales/models/flash_notify.en.yml new file mode 100644 index 000000000..50f5ac06c --- /dev/null +++ b/config/locales/models/flash_notify.en.yml @@ -0,0 +1,28 @@ +en: + layout: + flash_notifies: + list_header: Notifies + new: New notify + new_header: New notify + actions: Actions + edit: Edit + edit_header: Edit notify + delete: Delete + + flash: + flash_notify: + saved: Notify added + save_error: Unable to add notify + destroyed: Notify deleted + + activerecord: + models: + flash_notify: Notify + attributes: + flash_notify: + body_ru: Body Ru + body_en: Body En + published: Published + status: Status + created_at: Created + updated_at: Updated diff --git a/config/locales/models/flash_notify.ru.yml b/config/locales/models/flash_notify.ru.yml new file mode 100644 index 000000000..b2be708c1 --- /dev/null +++ b/config/locales/models/flash_notify.ru.yml @@ -0,0 +1,28 @@ +ru: + layout: + flash_notifies: + list_header: Оповещения + new: Новое оповещение + new_header: Новое оповещение + actions: Действия + edit: Редактирование + edit_header: Редактировать оповещение + delete: Удалить + + flash: + flash_notify: + saved: Оповещение сохранено + save_error: Не получилось сохранить оповещение + destroyed: Оповещение удалено + + activerecord: + models: + flash_notify: Оповещение + attributes: + flash_notify: + body_ru: Текст Ru + body_en: Текст En + published: Опубликовано + status: Статус + created_at: Создано + updated_at: Обновлено diff --git a/config/locales/ru.yml b/config/locales/ru.yml index c2081b9f3..4b80c0c06 100644 --- a/config/locales/ru.yml +++ b/config/locales/ru.yml @@ -26,6 +26,7 @@ ru: delete: Удалить delete_selected: Удалить выбранное save: Сохранить + saving: Сохранение... clone: Клонировать search_by_name: Фильтр по имени are_you_sure: "Вы уверены?" diff --git a/config/routes.rb b/config/routes.rb index f58555f18..3540d589a 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -32,8 +32,9 @@ Rosa::Application.routes.draw do get :reject end end + resources :flash_notifies resources :event_logs, :only => :index - constraints AdminAccess do + constraints Rosa::Constraints::AdminAccess do mount Resque::Server => 'resque' end end @@ -133,7 +134,6 @@ Rosa::Application.routes.draw do end resources :projects, :only => [:index, :new, :create] - scope ':owner_name/:project_name', :constraints => {:project_name => Project::NAME_REGEXP} do # project scope :as => 'project' do resources :wiki do @@ -177,7 +177,7 @@ Rosa::Application.routes.draw do end end # Resource - get '/edit' => 'projects#edit', :as => :edit_project + get '/modify' => 'projects#edit', :as => :edit_project put '/' => 'projects#update' delete '/' => 'projects#destroy' # Member @@ -185,41 +185,43 @@ Rosa::Application.routes.draw do get '/sections' => 'projects#sections', :as => :sections_project post '/sections' => 'projects#sections' delete '/remove_user' => 'projects#remove_user', :as => :remove_user_project - constraints :treeish => /[^\/]+/ do - # Tree - get '/' => "git/trees#show", :as => :project - get '/tree/:treeish(/*path)' => "git/trees#show", :defaults => {:treeish => :master}, :as => :tree, :format => false - # Commits - get '/commits/:treeish(/*path)' => "git/commits#index", :defaults => {:treeish => :master}, :as => :commits, :format => false - get '/commit/:id(.:format)' => "git/commits#show", :as => :commit - # Commit comments - post '/commit/:commit_id/comments(.:format)' => "comments#create", :as => :project_commit_comments - get '/commit/:commit_id/comments/:id(.:format)' => "comments#edit", :as => :edit_project_commit_comment - put '/commit/:commit_id/comments/:id(.:format)' => "comments#update", :as => :project_commit_comment - delete '/commit/:commit_id/comments/:id(.:format)' => "comments#destroy" - # Commit subscribes - post '/commit/:commit_id/subscribe' => "commit_subscribes#create", :as => :subscribe_commit - delete '/commit/:commit_id/unsubscribe' => "commit_subscribes#destroy", :as => :unsubscribe_commit - # Editing files - get '/blob/:treeish/*path/edit' => "git/blobs#edit", :defaults => {:treeish => :master}, :as => :edit_blob - put '/blob/:treeish/*path' => "git/blobs#update", :defaults => {:treeish => :master}, :format => false - # Blobs - get '/blob/:treeish/*path' => "git/blobs#show", :defaults => {:treeish => :master}, :as => :blob, :format => false - # Blame - get '/blame/:treeish/*path' => "git/blobs#blame", :defaults => {:treeish => :master}, :as => :blame, :format => false - # Raw - get '/raw/:treeish/*path' => "git/blobs#raw", :defaults => {:treeish => :master}, :as => :raw, :format => false - # Archive - get '/archive/:format/tree/:treeish' => "git/trees#archive", :defaults => {:treeish => :master}, :as => :archive, :format => /zip|tar/ + constraints :treeish => /.+/ do + constraints Rosa::Constraints::Treeish do + # Tree + get '/' => "git/trees#show", :as => :project + get '/tree/:treeish(/*path)' => "git/trees#show", :as => :tree, :format => false + # Commits + get '/commits/:treeish(/*path)' => "git/commits#index", :as => :commits, :format => false + get '/commit/:id(.:format)' => "git/commits#show", :as => :commit + # Commit comments + post '/commit/:commit_id/comments(.:format)' => "comments#create", :as => :project_commit_comments + get '/commit/:commit_id/comments/:id(.:format)' => "comments#edit", :as => :edit_project_commit_comment + put '/commit/:commit_id/comments/:id(.:format)' => "comments#update", :as => :project_commit_comment + delete '/commit/:commit_id/comments/:id(.:format)' => "comments#destroy" + # Commit subscribes + post '/commit/:commit_id/subscribe' => "commit_subscribes#create", :as => :subscribe_commit + delete '/commit/:commit_id/unsubscribe' => "commit_subscribes#destroy", :as => :unsubscribe_commit + # Editing files + get '/edit/:treeish/*path' => "git/blobs#edit", :as => :edit_blob, :format => false + put '/edit/:treeish/*path' => "git/blobs#update", :format => false + # Blobs + get '/blob/:treeish/*path' => "git/blobs#show", :as => :blob, :format => false + # Blame + get '/blame/:treeish/*path' => "git/blobs#blame", :as => :blame, :format => false + # Raw + get '/raw/:treeish/*path' => "git/blobs#raw", :as => :raw, :format => false + # Archive + get '/archive/:treeish.:format' => "git/trees#archive", :as => :archive, :format => /zip|tar/ + end end end end scope ':uname' do # project owner profile - constraints OwnerConstraint.new(User) do + constraints Rosa::Constraints::Owner.new(User) do get '/' => 'users/profile#show', :as => :user end - constraints OwnerConstraint.new(Group, true) do + constraints Rosa::Constraints::Owner.new(Group, true) do get '/' => 'groups/profile#show', :as => :group end end diff --git a/db/migrate/20120719045806_create_flash_notifies.rb b/db/migrate/20120719045806_create_flash_notifies.rb new file mode 100644 index 000000000..2a9f16a29 --- /dev/null +++ b/db/migrate/20120719045806_create_flash_notifies.rb @@ -0,0 +1,11 @@ +class CreateFlashNotifies < ActiveRecord::Migration + def change + create_table :flash_notifies do |t| + t.text :body_ru, :null => false + t.text :body_en, :null => false + t.string :status, :null => false + t.boolean :published, :null => false, :default => true + t.timestamps + end + end +end diff --git a/db/migrate/20120730214052_disable_null_value_for_key_pairs.rb b/db/migrate/20120730214052_disable_null_value_for_key_pairs.rb new file mode 100644 index 000000000..e1d71ec52 --- /dev/null +++ b/db/migrate/20120730214052_disable_null_value_for_key_pairs.rb @@ -0,0 +1,17 @@ +class DisableNullValueForKeyPairs < ActiveRecord::Migration + def up + change_column_null :key_pairs, :repository_id, false + change_column_null :key_pairs, :user_id, false + change_column_null :key_pairs, :key_id, false + change_column_null :key_pairs, :public, false + add_index :key_pairs, :repository_id, :unique => true + end + + def down + change_column_null :key_pairs, :repository_id, true + change_column_null :key_pairs, :user_id, true + change_column_null :key_pairs, :key_id, true + change_column_null :key_pairs, :public, true + remove_index :key_pairs, :repository_id + end +end diff --git a/db/schema.rb b/db/schema.rb index 23a83d945..9b5f06c2b 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended to check this file into your version control system. -ActiveRecord::Schema.define(:version => 20120730150317) do +ActiveRecord::Schema.define(:version => 20120730214052) do create_table "activity_feeds", :force => true do |t| t.integer "user_id", :null => false @@ -53,8 +53,8 @@ ActiveRecord::Schema.define(:version => 20120730150317) do create_table "arches", :force => true do |t| t.string "name", :null => false - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false end add_index "arches", ["name"], :name => "index_arches_on_name", :unique => true @@ -63,8 +63,8 @@ ActiveRecord::Schema.define(:version => 20120730150317) do t.integer "user_id" t.string "provider" t.string "uid" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false end add_index "authentications", ["provider", "uid"], :name => "index_authentications_on_provider_and_uid", :unique => true @@ -75,8 +75,8 @@ ActiveRecord::Schema.define(:version => 20120730150317) do t.integer "level" t.integer "status" t.integer "build_list_id" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false t.string "version" end @@ -106,9 +106,8 @@ ActiveRecord::Schema.define(:version => 20120730150317) do t.string "project_version" t.integer "project_id" t.integer "arch_id" - t.datetime "notified_at" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false t.boolean "is_circle", :default => false t.text "additional_repos" t.string "name" @@ -137,8 +136,8 @@ ActiveRecord::Schema.define(:version => 20120730150317) do t.string "commentable_type" t.integer "user_id" t.text "body" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false t.decimal "commentable_id", :precision => 50, :scale => 0 t.integer "project_id" end @@ -155,23 +154,23 @@ ActiveRecord::Schema.define(:version => 20120730150317) do t.string "controller" t.string "action" t.text "message" - t.datetime "created_at" - t.datetime "updated_at" - end - - create_table "flash_notifies", :force => true do |t| - t.text "body_ru" - t.text "body_en" - t.string "status" - t.boolean "published" t.datetime "created_at", :null => false t.datetime "updated_at", :null => false end + create_table "flash_notifies", :force => true do |t| + t.text "body_ru", :null => false + t.text "body_en", :null => false + t.string "status", :null => false + t.boolean "published", :default => true, :null => false + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + create_table "groups", :force => true do |t| t.integer "owner_id" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false t.string "uname" t.integer "own_projects_count", :default => 0, :null => false t.text "description" @@ -184,8 +183,8 @@ ActiveRecord::Schema.define(:version => 20120730150317) do t.string "title" t.text "body" t.string "status", :default => "open" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false t.integer "user_id" t.datetime "closed_at" t.integer "closed_by" @@ -194,14 +193,16 @@ ActiveRecord::Schema.define(:version => 20120730150317) do add_index "issues", ["project_id", "serial_id"], :name => "index_issues_on_project_id_and_serial_id", :unique => true create_table "key_pairs", :force => true do |t| - t.integer "repository_id" - t.integer "user_id" - t.integer "key_id" - t.text "public" + t.integer "repository_id", :null => false + t.integer "user_id", :null => false + t.string "key_id", :null => false + t.text "public", :null => false t.datetime "created_at", :null => false t.datetime "updated_at", :null => false end + add_index "key_pairs", ["repository_id"], :name => "index_key_pairs_on_repository_id", :unique => true + create_table "labelings", :force => true do |t| t.integer "label_id", :null => false t.integer "issue_id" @@ -259,16 +260,16 @@ ActiveRecord::Schema.define(:version => 20120730150317) do t.integer "platform_id" t.string "login" t.string "password" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false 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" - t.datetime "updated_at" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false end add_index "product_build_lists", ["product_id"], :name => "index_product_build_lists_on_product_id" @@ -276,8 +277,8 @@ ActiveRecord::Schema.define(:version => 20120730150317) do create_table "products", :force => true do |t| t.string "name", :null => false t.integer "platform_id", :null => false - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false t.text "build_script" t.text "counter" t.text "ks" @@ -296,8 +297,8 @@ ActiveRecord::Schema.define(:version => 20120730150317) do t.string "name" t.string "version" t.datetime "file_mtime" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false t.integer "platform_id" end @@ -306,31 +307,33 @@ ActiveRecord::Schema.define(:version => 20120730150317) do create_table "project_to_repositories", :force => true do |t| t.integer "project_id" t.integer "repository_id" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false end create_table "projects", :force => true do |t| t.string "name" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false 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.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 end + add_index "projects", ["owner_id"], :name => "index_projects_on_name_and_owner_id_and_owner_type", :unique => true, :case_sensitive => false + create_table "register_requests", :force => true do |t| t.string "name" t.string "email" @@ -351,16 +354,16 @@ ActiveRecord::Schema.define(:version => 20120730150317) do t.string "actor_type" t.integer "target_id" t.string "target_type" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false 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" - t.datetime "updated_at" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false t.string "name", :null => false end @@ -371,8 +374,8 @@ ActiveRecord::Schema.define(:version => 20120730150317) do t.boolean "new_comment_reply", :default => true t.boolean "new_issue", :default => true t.boolean "issue_assign", :default => true - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false 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 @@ -381,8 +384,8 @@ ActiveRecord::Schema.define(:version => 20120730150317) do create_table "subscribes", :force => true do |t| t.string "subscribeable_type" t.integer "user_id" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false t.boolean "status", :default => true t.integer "project_id" t.decimal "subscribeable_id", :precision => 50, :scale => 0 @@ -392,19 +395,15 @@ ActiveRecord::Schema.define(:version => 20120730150317) do t.string "name" t.string "email", :default => "", :null => false t.string "encrypted_password", :limit => 128, :default => "", :null => false - t.string "password_salt", :default => "", :null => false t.string "reset_password_token" t.datetime "remember_created_at" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false t.string "uname" t.string "role" t.string "language", :default => "en" - t.string "confirmation_token" - t.datetime "confirmed_at" - t.datetime "confirmation_sent_at" - t.integer "own_projects_count", :default => 0, :null => false t.datetime "reset_password_sent_at" + t.integer "own_projects_count", :default => 0, :null => false t.text "professional_experience" t.string "site" t.string "company" @@ -416,6 +415,9 @@ ActiveRecord::Schema.define(:version => 20120730150317) do 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 end diff --git a/doc/README_FOR_APP b/doc/README_FOR_APP index 8458ee4f1..cd837c6bc 100644 --- a/doc/README_FOR_APP +++ b/doc/README_FOR_APP @@ -21,4 +21,10 @@ Add to /etc/rc.d/rc.sysinit sudo urpmi lib64icu-devel # mandriva gem install charlock_holmes -- --with-icu-dir=/opt/local # macports +sudo urpmi lib64magic-devel # mandriva +brew install libmagic; brew link libmagic # brew +gem install ruby-filemagic + +sudo urpmi python-devel + git config --global core.quotepath false diff --git a/lib/ext/core/string.rb b/lib/ext/core/string.rb index a8640324f..9ff9bde77 100644 --- a/lib/ext/core/string.rb +++ b/lib/ext/core/string.rb @@ -1,27 +1,24 @@ # -*- encoding : utf-8 -*- require 'charlock_holmes/string' -# require 'iconv' class String def default_encoding! - if ascii_only? - force_encoding(Encoding.default_internal || Encoding::UTF_8) - else - force_encoding((detected = detect_encoding and detected[:encoding]) || Encoding.default_internal || Encoding::UTF_8).encode! + default_encoding = Encoding.default_internal || Encoding::UTF_8 + if ascii_only? # no need to encode if ascii + force_encoding(default_encoding) + else # should encode + options = {:invalid => :replace, :undef => :replace, :replace => ''} + if (detected = detect_encoding) && detected[:encoding] + force_encoding(detected[:encoding]).encode!(default_encoding, detected[:encoding], options) + end + # re-encode through UTF-16 to filter incorrect symbols + encode!(Encoding::UTF_16, default_encoding, options).encode!(default_encoding, Encoding::UTF_16) + raise unless valid_encoding? # check result end + self + rescue + replace "--broken encoding: #{detect_encoding[:encoding] || 'unknown'}" + # ensure + # return self end - - # def enforce_utf8(from = nil) - # begin - # is_utf8? ? self : ::Iconv.iconv('utf8', from, self).first - # rescue - # converter = ::Iconv.new('UTF-8//IGNORE//TRANSLIT', 'ASCII//IGNORE//TRANSLIT') - # # If Ruby 1.9, else another RubyEngine (ree, Ruby 1.8) - # begin - # converter.iconv(self).unpack('U*').select{|cp| cp < 127}.pack('U*').force_encoding('utf-8') - # rescue - # converter.iconv(self).unpack('U*').select{|cp| cp < 127}.pack('U*') - # end - # end - # end end diff --git a/lib/ext/git/grit.rb b/lib/ext/git/grit.rb index 1fbc50109..4fa2f11f3 100644 --- a/lib/ext/git/grit.rb +++ b/lib/ext/git/grit.rb @@ -1,11 +1,49 @@ # -*- encoding : utf-8 -*- module Grit class Blob + include Linguist::BlobHelper + + MAX_VIEW_SIZE = 2.megabytes + MAX_DATA_SIZE = 50.megabytes + + def data_with_limit + size <= MAX_DATA_SIZE ? data_without_limit : nil # 'Error: blob is too big' + end + alias_method_chain :data, :limit + + def large? + size.to_i > MAX_VIEW_SIZE + end + + def render_as + @render_as ||= case + when large?; :binary + when image?; :image + when text?; :text + else + :binary + end + end + + # def file_mime_type + # @file_mime_type ||= data.file_type(:mime_type) + # end + # + # def text? + # file_mime_type =~ /^text\// # not binary? + # end + # + # def binary? + # not text? # file_mime_type !~ /^text\// + # # s = data.split(//); ((s.size - s.grep(" ".."~").size) / s.size.to_f) > 0.30 # works only for latin chars + # end + # + # def image? + # mime_type.match(/image/) + # end DEFAULT_RAW_MIME_TYPE = MIME::Types[DEFAULT_MIME_TYPE].first - delegate :binary?, :ascii?, :encoding, :to => :raw_mime_type - def mime_type_with_class_store set_associated_mimes @associated_mimes.first.simplified @@ -25,29 +63,35 @@ module Grit protected - # store all associated MIME::Types inside class - def set_associated_mimes - @associated_mimes ||= [] - if @associated_mimes.empty? - guesses = MIME::Types.type_for(self.name) rescue [DEFAULT_RAW_MIME_TYPE] - guesses = [DEFAULT_RAW_MIME_TYPE] if guesses.empty? + # store all associated MIME::Types inside class + def set_associated_mimes + @associated_mimes ||= [] + if @associated_mimes.empty? + guesses = MIME::Types.type_for(self.name) rescue [DEFAULT_RAW_MIME_TYPE] + guesses = [DEFAULT_RAW_MIME_TYPE] if guesses.empty? - @associated_mimes = guesses.sort{|a,b| mime_sort(a, b)} - end - @associated_mimes + @associated_mimes = guesses.sort{|a,b| mime_sort(a, b)} end + @associated_mimes + end - # TODO make more clever function - def mime_sort(a,b) - return 0 if a.media_type == b.media_type and a.registered? == b.registered? - return -1 if a.media_type == 'text' and !a.registered? - return 1 - end + # TODO make more clever function + def mime_sort(a,b) + return 0 if a.media_type == b.media_type and a.registered? == b.registered? + return -1 if a.media_type == 'text' and !a.registered? + return 1 + end + end + class Repo + def branches_and_tags + branches + tags # @branches_and_tags ||= # ??? + end end end Grit::Git.git_timeout = 60 +# Grit::Git.git_max_size = 5.megabytes # Grit.debug = true GAP_REPO_PATH = '/tmp/gap_repo.git' unless File.directory? GAP_REPO_PATH diff --git a/lib/ext/rails/constraints.rb b/lib/ext/rails/constraints.rb deleted file mode 100644 index 2ec8ef342..000000000 --- a/lib/ext/rails/constraints.rb +++ /dev/null @@ -1,18 +0,0 @@ -# -*- encoding : utf-8 -*- -class OwnerConstraint - def initialize(class_name, bang = false) - @class_name = class_name - @finder = 'find_by_insensitive_uname' - @finder << '!' if bang - end - - def matches?(request) - @class_name.send(@finder, request.params[:uname]).present? - end -end - -class AdminAccess - def self.matches?(request) - !!request.env['warden'].user.try(:admin?) - end -end diff --git a/lib/ext/rosa/constraints.rb b/lib/ext/rosa/constraints.rb new file mode 100644 index 000000000..54e9e6191 --- /dev/null +++ b/lib/ext/rosa/constraints.rb @@ -0,0 +1,40 @@ +# -*- encoding : utf-8 -*- +module Rosa + module Constraints + class Owner + def initialize(class_name, bang = false) + @class_name = class_name + @finder = 'find_by_insensitive_uname' + @finder << '!' if bang + end + + def matches?(request) + @class_name.send(@finder, request.params[:uname]).present? + end + end + + class AdminAccess + def self.matches?(request) + !!request.env['warden'].user.try(:admin?) + end + end + + class Treeish + def self.matches?(request) + params = request.path_parameters + if params[:treeish] # parse existing branch (tag) and path + branch_or_tag = begin + (p = Project.find_by_owner_and_name params[:owner_name], params[:project_name]) && + p.repo.branches_and_tags.detect{|t| params[:treeish].start_with?(t.name)}.try(:name) || + params[:treeish].split('/').first + end + if path = params[:treeish].sub(branch_or_tag, '')[1..-1] and path.present? + params[:path] = File.join([path, params[:path]].compact) + end + params[:treeish] = branch_or_tag + end + true + end + end + end +end diff --git a/lib/modules/models/git.rb b/lib/modules/models/git.rb new file mode 100644 index 000000000..4cf2baafc --- /dev/null +++ b/lib/modules/models/git.rb @@ -0,0 +1,171 @@ +# -*- encoding : utf-8 -*- +module Modules + module Models + module Git + extend ActiveSupport::Concern + + included do + validates_attachment_size :srpm, :less_than => 500.megabytes + validates_attachment_content_type :srpm, :content_type => ['application/octet-stream', "application/x-rpm", "application/x-redhat-package-manager"], :message => I18n.t('layout.invalid_content_type') + + has_attached_file :srpm + # attr_accessible :srpm + + after_create :create_git_repo + after_commit(:on => :create) {|p| p.fork_git_repo unless p.is_root?} # later with resque + after_commit(:on => :create) {|p| p.import_attached_srpm if p.srpm?} # later with resque # should be after create_git_repo + after_destroy :destroy_git_repo + # after_rollback lambda { destroy_git_repo rescue true if new_record? } + + later :import_attached_srpm, :queue => :fork_import + later :fork_git_repo, :queue => :fork_import + end + + def repo + @repo ||= Grit::Repo.new(path) rescue Grit::Repo.new(GAP_REPO_PATH) + end + + def path + build_path(git_repo_name) + end + + def git_repo_name + File.join owner.uname, name + end + + def versions + repo.tags.map(&:name) + repo.branches.map{|b| "latest_#{b.name}"} + end + + def update_file(path, data, options = {}) + head = options[:head].to_s || default_branch + actor = get_actor(options[:actor]) + filename = File.split(path).last + message = options[:message] + message = "Updated file #{filename}" if message.nil? or message.empty? + + # can not write to unexisted branch + return false if repo.branches.select{|b| b.name == head}.size != 1 + + parent = repo.commits(head).first + + index = repo.index + index.read_tree(parent.tree.id) + + # can not create new file + return false if (index.current_tree / path).nil? + + index.add(path, data) + index.commit(message, :parents => [parent], :actor => actor, :last_tree => parent.tree.id, :head => head) + end + + def paginate_commits(treeish, options = {}) + options[:page] = options[:page].try(:to_i) || 1 + options[:per_page] = options[:per_page].try(:to_i) || 20 + + skip = options[:per_page] * (options[:page] - 1) + last_page = (skip + options[:per_page]) >= repo.commit_count(treeish) + + [repo.commits(treeish, options[:per_page], skip), options[:page], last_page] + end + + def tree_info(tree, treeish = nil, path = nil) + treeish ||= tree.id + # initialize result as hash of => nil + res = (tree.trees.sort + tree.blobs.sort).inject({}){|h, e| h.merge!({e => nil})} + # fills result vith commits that describes this file + res = res.inject(res) do |h, (entry, commit)| + if commit.nil? and entry.respond_to?(:name) # only if commit == nil + # ... find last commit corresponds to this file ... + c = repo.log(treeish, File.join([path, entry.name].compact), :max_count => 1).first + # ... and add it to result. + h[entry] = c + # find another files, that linked to this commit and set them their commit + # c.diffs.map{|diff| diff.b_path.split(File::SEPARATOR, 2).first}.each do |name| + # h.each_pair do |k, v| + # h[k] = c if k.name == name and v.nil? + # end + # end + end + h + end + end + + def import_srpm(srpm_path = srpm.path, branch_name = 'import') + system("#{Rails.root.join('bin', 'import_srpm.sh')} #{srpm_path} #{path} #{branch_name} >> /dev/null 2>&1") + end + + protected + + def build_path(dir) + File.join(APP_CONFIG['root_path'], 'git_projects', "#{dir}.git") + end + + def import_attached_srpm + if srpm? + import_srpm # srpm.path + self.srpm = nil; save # clear srpm + end + end + + def create_git_repo + if is_root? + Grit::Repo.init_bare(path) + write_hook + end + end + + def fork_git_repo + dummy = Grit::Repo.new(path) rescue parent.repo.fork_bare(path) + write_hook + end + + def destroy_git_repo + FileUtils.rm_rf path + end + + def write_hook + is_production = Rails.env == "production" + hook = File.join(::Rails.root.to_s, 'tmp', "post-receive-hook") + FileUtils.cp(File.join(::Rails.root.to_s, 'bin', "post-receive-hook.partial"), hook) + File.open(hook, 'a') do |f| + s = "\n /bin/bash -l -c \"cd #{is_production ? '/srv/rosa_build/current' : Rails.root.to_s} && #{is_production ? 'RAILS_ENV=production' : ''} bundle exec rake hook:enqueue[$owner,$reponame,$newrev,$oldrev,$ref,$newrev_type,$oldrev_type]\"" + s << " > /dev/null 2>&1" if is_production + s << "\ndone\n" + f.write(s) + f.chmod(0755) + end + + hook_file = File.join(path, 'hooks', 'post-receive') + FileUtils.cp(hook, hook_file) + FileUtils.rm_rf(hook) + + rescue Exception # FIXME + end + + def get_actor(actor = nil) + @last_actor = case actor.class.to_s + when 'Grit::Actor' then options[:actor] + when 'Hash' then Grit::Actor.new(actor[:name], actor[:email]) + when 'String' then Grit::Actor.from_stirng(actor) + else begin + if actor.respond_to?(:name) and actor.respond_to?(:email) + Grit::Actor.new(actor.name, actor.email) + else + config = Grit::Config.new(repo) + Grit::Actor.new(config['user.name'], config['user.email']) + end + end + end + @last_actor + end + + module ClassMethods + def process_hook(owner_uname, repo, newrev, oldrev, ref, newrev_type, oldrev_type) + rec = GitHook.new(owner_uname, repo, newrev, oldrev, ref, newrev_type, oldrev_type) + ActivityFeedObserver.instance.after_create rec + end + end + end + end +end diff --git a/lib/modules/models/owner.rb b/lib/modules/models/owner.rb index 182682e18..e88ac3f5f 100644 --- a/lib/modules/models/owner.rb +++ b/lib/modules/models/owner.rb @@ -8,15 +8,8 @@ module Modules after_create lambda { relations.create :actor_id => owner.id, :actor_type => owner.class.to_s, :role => 'admin' } end - module ClassMethods - end - - module InstanceMethods - - def name_with_owner - "#{owner.respond_to?(:uname) ? owner.uname : owner.name}/#{self.name}" - end - + def name_with_owner + "#{owner.respond_to?(:uname) ? owner.uname : owner.name}/#{self.name}" end end end diff --git a/lib/modules/models/personal_repository.rb b/lib/modules/models/personal_repository.rb index b821ce750..b5ca7bdb2 100644 --- a/lib/modules/models/personal_repository.rb +++ b/lib/modules/models/personal_repository.rb @@ -9,19 +9,25 @@ module Modules end def create_personal_repository - pl = own_platforms.build - pl.owner = self - pl.name = "#{self.uname}_personal" - pl.description = "#{self.uname}_personal" - pl.platform_type = 'personal' - pl.distrib_type = APP_CONFIG['distr_types'].first - pl.visibility = 'open' - pl.save! + begin + pl = own_platforms.build + pl.owner = self + pl.name = "#{self.uname}_personal" + pl.description = "#{self.uname}_personal" + pl.platform_type = 'personal' + pl.distrib_type = APP_CONFIG['distr_types'].first + pl.visibility = 'open' + pl.save! - rep = pl.repositories.build - rep.name = 'main' - rep.description = 'main' - rep.save! + rep = pl.repositories.build + rep.name = 'main' + rep.description = 'main' + rep.save! + rescue Exception => e + pl.now_destroy rescue false + raise e + end + return true end def personal_platform diff --git a/lib/modules/models/wiki.rb b/lib/modules/models/wiki.rb new file mode 100644 index 000000000..1f13446b9 --- /dev/null +++ b/lib/modules/models/wiki.rb @@ -0,0 +1,39 @@ +# -*- encoding : utf-8 -*- +module Modules + module Models + module Wiki + extend ActiveSupport::Concern + + included do + after_create :create_wiki + after_destroy :destroy_wiki + end + + def wiki_path + build_path(wiki_repo_name) + end + + def wiki_repo_name + File.join owner.uname, "#{name}.wiki" + end + + protected + + def create_wiki + if has_wiki && !FileTest.exist?(wiki_path) + Grit::Repo.init_bare(wiki_path) + wiki = Gollum::Wiki.new(wiki_path, {:base_path => Rails.application.routes.url_helpers.project_wiki_index_path(owner, self)}) + wiki.write_page('Home', :markdown, I18n.t("wiki.seed.welcome_content"), + {:name => owner.name, :email => owner.email, :message => 'Initial commit'}) + end + end + + def destroy_wiki + FileUtils.rm_rf wiki_path + end + + module ClassMethods + end + end + end +end diff --git a/lib/plugins/grack/base.rb b/lib/plugins/grack/base.rb index b464f44ee..99b2d160b 100644 --- a/lib/plugins/grack/base.rb +++ b/lib/plugins/grack/base.rb @@ -35,7 +35,7 @@ module Grack def project @project ||= begin uname, name = @env['PATH_INFO'].split('/')[1,2] - name.gsub!(/\.git$/, '').gsub!(/\.wiki$/, '') + name.gsub!(/(\.wiki)?\.git$/, '') Project.find_by_owner_and_name uname, name end end diff --git a/lib/tasks/add_branch.rake b/lib/tasks/add_branch.rake index c8d7cf48d..1857cb7c9 100644 --- a/lib/tasks/add_branch.rake +++ b/lib/tasks/add_branch.rake @@ -9,7 +9,7 @@ task :add_branch => :environment do Platform.find_by_name(dst_branch).repositories.each do |r| say "=== Process #{r.name} repo" r.projects.find_each do |p| - next if p.branches.map(&:name).include?(dst_branch) + next if p.repo.branches.map(&:name).include?(dst_branch) say "===== Process #{p.name} project" tmp_path = Rails.root.join('tmp', p.name) system("git clone #{p.path} #{tmp_path}") diff --git a/spec/controllers/admin/flash_notifies_controller_spec.rb b/spec/controllers/admin/flash_notifies_controller_spec.rb new file mode 100644 index 000000000..ad7494fda --- /dev/null +++ b/spec/controllers/admin/flash_notifies_controller_spec.rb @@ -0,0 +1,124 @@ +require 'spec_helper' + +describe Admin::FlashNotifiesController do + before(:each) do + stub_symlink_methods + + @user = FactoryGirl.create(:user) + @create_params = { + :flash_notify => { + :body_ru => "Hello! I`m ru body", + :body_en => "Hello! I`m en body", + :status => "error", + :published => true + } + } + + @flash_notify = FactoryGirl.create(:flash_notify) + @flash_notify2 = FactoryGirl.create(:flash_notify) + + @update_params = { + :id => @flash_notify, + :flash_notify => { + :body_ru => "updated!" + } + } + end + + context 'for guest' do + [:index, :create, :update, :edit, :new, :destroy].each do |action| + it "should not be able to perform #{ action } action" do + get action, :id => @flash_notify + response.should redirect_to(new_user_session_path) + end + end + + it 'should not change objects count on create' do + lambda { post :create, @create_params }.should change{ FlashNotify.count }.by(0) + end + + it 'should not change objects count on destroy' do + lambda { delete :destroy, :id => @flash_notify }.should change{ FlashNotify.count }.by(0) + end + + it 'should not change flash notify body on update' do + put :update, @update_params + @flash_notify.reload.body_ru.should_not == "updated!" + end + end + + context 'for global admin' do + before(:each) do + @admin = FactoryGirl.create(:admin) + @user = FactoryGirl.create(:user) + set_session_for(@admin) + end + + it 'should load 2 flash notifies objects on index' do + get :index + assigns[:flash_notifies].count.should == 2 + end + + [:index, :new, :edit].each do |action| + it "should be able to perform #{action} action" do + get action, :id => @flash_notify + response.should render_template(action) + end + end + + it 'should be able to perform create action' do + post :create, @create_params + response.should redirect_to(admin_flash_notifies_path) + end + + it 'should change objects count on create' do + lambda { post :create, @create_params }.should change{ FlashNotify.count }.by(1) + end + + it 'should be able to perform destroy action' do + delete :destroy, :id => @flash_notify + response.should redirect_to(admin_flash_notifies_path) + end + + it 'should change objects count on destroy' do + lambda { delete :destroy, :id => @flash_notify }.should change{ FlashNotify.count }.by(-1) + end + + it 'should be able to perform update action' do + put :update, @update_params + response.should redirect_to(admin_flash_notifies_path) + end + + it 'should change flash notify body on update' do + put :update, @update_params + @flash_notify.reload.body_ru.should == "updated!" + end + end + + context 'for simple user' do + before(:each) do + @user = FactoryGirl.create(:user) + set_session_for(@user) + end + + [:index, :create, :update, :edit, :new, :destroy].each do |action| + it "should not be able to perform #{ action } action" do + get action, :id => @flash_notify + response.should redirect_to(forbidden_path) + end + end + + it 'should not change objects count on create' do + lambda { post :create, @create_params }.should change{ FlashNotify.count }.by(0) + end + + it 'should not change objects count on destroy' do + lambda { delete :destroy, :id => @flash_notify }.should change{ FlashNotify.count }.by(0) + end + + it 'should not change flash notify body on update' do + put :update, @update_params + @flash_notify.reload.body_ru.should_not == "updated!" + end + end +end diff --git a/spec/controllers/groups/profile_controller_spec.rb b/spec/controllers/groups/profile_controller_spec.rb index 21c62b7df..a0e29c31b 100644 --- a/spec/controllers/groups/profile_controller_spec.rb +++ b/spec/controllers/groups/profile_controller_spec.rb @@ -144,6 +144,15 @@ describe Groups::ProfileController do @group.actors.create(:actor_type => 'User', :actor_id => @user.id, :role => 'reader') end + it "should remove user from groups" do + delete :remove_user, :id => @group + response.should redirect_to(groups_path) + end + + it "should change relations count" do + lambda { delete :remove_user, :id => @group }.should change{ Relation.count }.by(-1) + end + it_should_behave_like 'no group user' it_should_behave_like 'group user without destroy rights' it_should_behave_like 'group user without update rights' diff --git a/spec/controllers/platforms/mass_builds_controller_spec.rb b/spec/controllers/platforms/mass_builds_controller_spec.rb index 6a85981f9..1cd611d72 100644 --- a/spec/controllers/platforms/mass_builds_controller_spec.rb +++ b/spec/controllers/platforms/mass_builds_controller_spec.rb @@ -76,6 +76,7 @@ describe Platforms::MassBuildsController do before(:each) do stub_symlink_methods + FactoryGirl.create(:arch) @platform = FactoryGirl.create(:platform) @repository = FactoryGirl.create(:repository, :platform => @platform) @personal_platform = FactoryGirl.create(:platform, :platform_type => 'personal') @@ -91,13 +92,23 @@ describe Platforms::MassBuildsController do end context 'for guest' do - [:index, :create, :cancel, :failed_builds_list].each do |action| + [:index, :create].each do |action| it "should not be able to perform #{ action } action" do get action, :platform_id => @platform response.should redirect_to(new_user_session_path) end end + it "should not be able to perform failed_builds_list action" do + get :failed_builds_list, :platform_id => @platform, :id => @mass_build + response.should redirect_to(new_user_session_path) + end + + it "should not be able to perform cancel action" do + post :cancel, :platform_id => @platform, :id => @mass_build + response.should redirect_to(new_user_session_path) + end + it 'should not change objects count on create success' do lambda { post :create, @create_params }.should change{ MassBuild.count }.by(0) end diff --git a/spec/controllers/platforms/repositories_controller_spec.rb b/spec/controllers/platforms/repositories_controller_spec.rb index 35120683d..82c4a5712 100644 --- a/spec/controllers/platforms/repositories_controller_spec.rb +++ b/spec/controllers/platforms/repositories_controller_spec.rb @@ -32,7 +32,7 @@ end shared_examples_for 'registered user' do it 'should be able to perform index action' do - get :index + get :index, :platform_id => @platform.id response.should render_template(:index) end @@ -80,7 +80,7 @@ describe Platforms::RepositoriesController do context 'for guest' do [:index, :create].each do |action| it "should not be able to perform #{ action } action" do - get action + get action, :platform_id => @platform response.should redirect_to(new_user_session_path) end end diff --git a/spec/controllers/projects/build_lists_controller_spec.rb b/spec/controllers/projects/build_lists_controller_spec.rb index 1431004eb..ef95a4cf7 100644 --- a/spec/controllers/projects/build_lists_controller_spec.rb +++ b/spec/controllers/projects/build_lists_controller_spec.rb @@ -42,13 +42,13 @@ describe Projects::BuildListsController do it 'should save correct commit_hash for branch based build' do post :create, {:owner_name => @project.owner.uname, :project_name => @project.name}.merge(@create_params).deep_merge(:build_list => {:project_version => "latest_master"}) - @project.build_lists.last.commit_hash.should == @project.git_repository.commits('master').last.id + @project.build_lists.last.commit_hash.should == @project.repo.commits('master').last.id end it 'should save correct commit_hash for tag based build' do - system("cd #{@project.git_repository.path} && git tag 4.7.5.3") # TODO REDO through grit + system("cd #{@project.repo.path} && git tag 4.7.5.3") # TODO REDO through grit post :create, {:owner_name => @project.owner.uname, :project_name => @project.name}.merge(@create_params).deep_merge(:build_list => {:project_version => "4.7.5.3"}) - @project.build_lists.last.commit_hash.should == @project.git_repository.commits('4.7.5.3').last.id + @project.build_lists.last.commit_hash.should == @project.repo.commits('4.7.5.3').last.id end end @@ -283,7 +283,7 @@ describe Projects::BuildListsController do @build_list1 = FactoryGirl.create(:build_list_core) @build_list2 = FactoryGirl.create(:build_list_core) @build_list3 = FactoryGirl.create(:build_list_core) - @build_list4 = FactoryGirl.create(:build_list_core, :created_at => (Time.now - 1.day), + @build_list4 = FactoryGirl.create(:build_list_core, :updated_at => (Time.now - 1.day), :project => @build_list3.project, :save_to_platform => @build_list3.save_to_platform, :arch => @build_list3.arch) end @@ -305,9 +305,9 @@ describe Projects::BuildListsController do it 'should filter by project_name and start_date' do get :index, :filter => {:project_name => @build_list3.project.name, :ownership => 'index', - "created_at_start(1i)" => @build_list3.created_at.year.to_s, - "created_at_start(2i)" => @build_list3.created_at.month.to_s, - "created_at_start(3i)" => @build_list3.created_at.day.to_s} + :"updated_at_start(1i)" => @build_list3.updated_at.year.to_s, + :"updated_at_start(2i)" => @build_list3.updated_at.month.to_s, + :"updated_at_start(3i)" => @build_list3.updated_at.day.to_s} assigns[:build_lists].should_not include(@build_list1) assigns[:build_lists].should_not include(@build_list2) assigns[:build_lists].should include(@build_list3) @@ -326,7 +326,7 @@ describe Projects::BuildListsController do describe 'publish_build' do before { test_git_commit(build_list.project) - build_list.update_attribute :commit_hash, build_list.project.git_repository.commits('master').last.id + build_list.update_attribute :commit_hash, build_list.project.repo.commits('master').last.id build_list.update_attribute(:status, BuildList::BUILD_PUBLISH) build_list_package } @@ -343,8 +343,8 @@ describe Projects::BuildListsController do } it 'should create correct git tag for correct commit' do do_get(BuildServer::SUCCESS) - build_list.project.git_repository.tags.last.name.should == build_list.package_version - build_list.project.git_repository.commits(build_list.package_version).last.id.should == build_list.commit_hash + build_list.project.repo.tags.last.name.should == build_list.package_version + build_list.project.repo.commits(build_list.package_version).last.id.should == build_list.commit_hash end it(:passes) { lambda{ do_get(BuildServer::SUCCESS) }.should change(build_list, :status).to(BuildList::BUILD_PUBLISHED) } it(:passes) { lambda{ do_get(BuildServer::SUCCESS) }.should change(build_list, :package_version).to("#{ build_list_package.platform.name }-4.7.5.3-1") } diff --git a/spec/controllers/projects/comments_controller_for_commit_spec.rb b/spec/controllers/projects/comments_controller_for_commit_spec.rb index 3ddce850e..7555d5a79 100644 --- a/spec/controllers/projects/comments_controller_for_commit_spec.rb +++ b/spec/controllers/projects/comments_controller_for_commit_spec.rb @@ -78,8 +78,8 @@ describe Projects::CommentsController do before(:each) do stub_symlink_methods @project = FactoryGirl.create(:project) - %x(cp -Rf #{Rails.root}/spec/tests.git/* #{@project.git_repository.path}) # maybe FIXME ? - @commit = @project.git_repository.commits.first + %x(cp -Rf #{Rails.root}/spec/tests.git/* #{@project.repo.path}) # maybe FIXME ? + @commit = @project.repo.commits.first @create_params = {:comment => {:body => 'I am a comment!'}, :owner_name => @project.owner.uname, :project_name => @project.name, :commit_id => @commit.id} @update_params = {:comment => {:body => 'updated'}, :owner_name => @project.owner.uname, :project_name => @project.name, :commit_id => @commit.id} diff --git a/spec/controllers/projects/git/git_trees_controller_spec.rb b/spec/controllers/projects/git/git_trees_controller_spec.rb index ce9884232..f2baf5020 100644 --- a/spec/controllers/projects/git/git_trees_controller_spec.rb +++ b/spec/controllers/projects/git/git_trees_controller_spec.rb @@ -4,7 +4,7 @@ require 'spec_helper' describe Projects::Git::TreesController do def fill_project - %x(cp -Rf #{Rails.root}/spec/tests.git/* #{@project.git_repository.path}) # maybe FIXME ? + %x(cp -Rf #{Rails.root}/spec/tests.git/* #{@project.repo.path}) # maybe FIXME ? end before(:each) do @@ -12,7 +12,7 @@ describe Projects::Git::TreesController do @project = FactoryGirl.create(:project) @another_user = FactoryGirl.create(:user) - @params = {:owner_name => @project.owner.uname, :project_name => @project.name} + @params = {:owner_name => @project.owner.uname, :project_name => @project.name, :treeish => 'master'} end context 'for guest' do @@ -35,21 +35,21 @@ describe Projects::Git::TreesController do it 'should not be able to archive empty project' do @user = FactoryGirl.create(:user) set_session_for(@user) - expect { get :archive, @params.merge(:format => 'tar') }.to raise_error(ActiveRecord::RecordNotFound) + expect { get :archive, @params.merge(:format => 'tar') }.to raise_error(ActionController::RoutingError) end it 'should not be able to injection code with format' do @user = FactoryGirl.create(:user) set_session_for(@user) fill_project - expect { get :archive, @params.merge(:format => "tar master > /dev/null; echo 'I am hacker!';\#") }.to raise_error(ActiveRecord::RecordNotFound) + expect { get :archive, @params.merge(:format => "tar master > /dev/null; echo 'I am hacker!';\#") }.to raise_error(ActionController::RoutingError) end it 'should not be able to injection code with treeish' do @user = FactoryGirl.create(:user) set_session_for(@user) fill_project - expect { get :archive, @params.merge(:treeish => "master > /dev/null; echo 'I am hacker!';\#") }.to raise_error(ActiveRecord::RecordNotFound) + expect { get :archive, @params.merge(:treeish => "master > /dev/null; echo 'I am hacker!';\#") }.to raise_error(ActionController::RoutingError) end it 'should be able to perform archive action' do diff --git a/spec/controllers/users/profile_controller_spec.rb b/spec/controllers/users/profile_controller_spec.rb index 0451de6a8..76617cf8d 100644 --- a/spec/controllers/users/profile_controller_spec.rb +++ b/spec/controllers/users/profile_controller_spec.rb @@ -16,7 +16,7 @@ describe Users::ProfileController do context 'for guest' do it 'should not be able to view profile' do - get :show, :owner_name => @simple_user.uname + get :show, :uname => @simple_user.uname response.should redirect_to(new_user_session_path) end end diff --git a/spec/factories/flash_notify.rb b/spec/factories/flash_notify.rb new file mode 100644 index 000000000..b3f239540 --- /dev/null +++ b/spec/factories/flash_notify.rb @@ -0,0 +1,10 @@ +# -*- encoding : utf-8 -*- +FactoryGirl.define do + factory :flash_notify do + body_ru { FactoryGirl.generate(:string) } + body_en { FactoryGirl.generate(:string) } + status "error" + published true + end +end + diff --git a/spec/factories/platforms.rb b/spec/factories/platforms.rb index e8d6aad69..6877fb58c 100644 --- a/spec/factories/platforms.rb +++ b/spec/factories/platforms.rb @@ -8,7 +8,7 @@ FactoryGirl.define do association :owner, :factory => :user factory :platform_with_repos do - after_create {|p| FactoryGirl.create_list(:repository, 1, platform: p)} + after(:create) {|p| FactoryGirl.create_list(:repository, 1, platform: p)} end factory :personal_platform do diff --git a/spec/models/comment_for_commit_spec.rb b/spec/models/comment_for_commit_spec.rb index e4ad33f74..6e51eb1fa 100644 --- a/spec/models/comment_for_commit_spec.rb +++ b/spec/models/comment_for_commit_spec.rb @@ -10,8 +10,8 @@ def set_comments_data_for_commit @ability = Ability.new(@user) @project = FactoryGirl.create(:project, :owner => @user) - %x(cp -Rf #{Rails.root}/spec/tests.git/* #{@project.git_repository.path}) # maybe FIXME ? - @commit = @project.git_repository.commits.first + %x(cp -Rf #{Rails.root}/spec/tests.git/* #{@project.repo.path}) # maybe FIXME ? + @commit = @project.repo.commits.first @comment = create_comment(@user) @stranger_comment = create_comment(@stranger) diff --git a/spec/models/flash_notify_spec.rb b/spec/models/flash_notify_spec.rb new file mode 100644 index 000000000..8501d64a4 --- /dev/null +++ b/spec/models/flash_notify_spec.rb @@ -0,0 +1,5 @@ +require 'spec_helper' + +describe FlashNotify do + pending "add some examples to (or delete) #{__FILE__}" +end diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb index 572af1b76..b50c1e6a4 100644 --- a/spec/models/project_spec.rb +++ b/spec/models/project_spec.rb @@ -1,6 +1,41 @@ # -*- encoding : utf-8 -*- require 'spec_helper' -#describe Project do -# pending "add some examples to (or delete) #{__FILE__}" -#end +describe Project do + before(:each) do + stub_symlink_methods + @root_project = FactoryGirl.create(:project) + @child_project = @root_project.fork(FactoryGirl.create(:user)) + @child_child_project = @child_project.fork(FactoryGirl.create(:user)) + end + + context 'for destroy root' do + before(:each) do + @root_project.destroy + end + + it "should not be delete child" do + Project.where(:id => @child_project).count.should == 1 + end + + it "should not be delete child of the child" do + Project.where(:id => @child_child_project).count.should == 1 + end + end + + # uncommit when will be available :orphan_strategy => :adopt + + #context 'for destroy middle node' do + # before(:each) do + # @child_project.destroy + # end + + # it "should set root project as a parent for orphan child" do + # Project.find(@child_child_project).ancestry == @root_project + # end + + # it "should not be delete child of the child" do + # Project.where(:id => @child_child_project).count.should == 1 + # end + #end +end \ No newline at end of file diff --git a/spec/routing/projects_routing_spec.rb.rb b/spec/routing/projects_routing_spec.rb.rb index 5bcc65d06..caa2042ee 100644 --- a/spec/routing/projects_routing_spec.rb.rb +++ b/spec/routing/projects_routing_spec.rb.rb @@ -13,7 +13,7 @@ describe Projects::ProjectsController do end it "routes to #edit" do - get("/import/glib2.0-mib/edit").should route_to("projects/projects#edit", :owner_name => 'import', :project_name => 'glib2.0-mib') + get("/import/glib2.0-mib/modify").should route_to("projects/projects#edit", :owner_name => 'import', :project_name => 'glib2.0-mib') end it "routes to #create" do @@ -39,6 +39,8 @@ describe Projects::Git::TreesController do get("/import/glib2.0-mib/tree/lib2safe-0.03").should route_to("projects/git/trees#show", :owner_name => 'import', :project_name => 'glib2.0-mib', :treeish => 'lib2safe-0.03') get("/import/glib2.0-mib/tree/branch-with.dot/folder_with.dot/path-with.dot").should route_to("projects/git/trees#show", :owner_name => 'import', :project_name => 'glib2.0-mib', :treeish => 'branch-with.dot', :path => 'folder_with.dot/path-with.dot') # get("/import/glib2.0-mib/tree/ветка-с.точкой/папка_с.точкой/путь-с.точкой").should route_to("projects/git/trees#show", :owner_name => 'import', :project_name => 'glib2.0-mib', :treeish => 'ветка-с.точкой', :path => 'папка_с.точкой/путь-с.точкой') + get("/import/glib2.0-mib/tree/branch-with/slash.dot/folder_with.dot/path-with.dot").should route_to("projects/git/trees#show", :owner_name => 'import', :project_name => 'glib2.0-mib', :treeish => 'branch-with/slash.dot', :path => 'folder_with.dot/path-with.dot') + get("/import/glib2.0-mib/tree/tag13.52-5").should route_to("projects/git/trees#show", :owner_name => 'import', :project_name => 'glib2.0-mib', :treeish => 'tag13.52-5') end # TODO write more specs also with slash in branch name! diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 843efa51f..72f943b66 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -39,8 +39,8 @@ def stub_symlink_methods end def test_git_commit(project) - project.git_repository.repo.index.add('test', 'TEST') - project.git_repository.repo.index.commit('Test commit') + project.repo.index.add('test', 'TEST') + project.repo.index.commit('Test commit') end Resque.inline = true diff --git a/vendor/assets/javascripts/bootstrap-alert.js b/vendor/assets/javascripts/bootstrap-alert.js new file mode 100644 index 000000000..57890a9a2 --- /dev/null +++ b/vendor/assets/javascripts/bootstrap-alert.js @@ -0,0 +1,90 @@ +/* ========================================================== + * bootstrap-alert.js v2.0.4 + * http://twitter.github.com/bootstrap/javascript.html#alerts + * ========================================================== + * Copyright 2012 Twitter, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ========================================================== */ + + +!function ($) { + + "use strict"; // jshint ;_; + + + /* ALERT CLASS DEFINITION + * ====================== */ + + var dismiss = '[data-dismiss="alert"]' + , Alert = function (el) { + $(el).on('click', dismiss, this.close) + } + + Alert.prototype.close = function (e) { + var $this = $(this) + , selector = $this.attr('data-target') + , $parent + + if (!selector) { + selector = $this.attr('href') + selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7 + } + + $parent = $(selector) + + e && e.preventDefault() + + $parent.length || ($parent = $this.hasClass('alert') ? $this : $this.parent()) + + $parent.trigger(e = $.Event('close')) + + if (e.isDefaultPrevented()) return + + $parent.removeClass('in') + + function removeElement() { + $parent + .trigger('closed') + .remove() + } + + $.support.transition && $parent.hasClass('fade') ? + $parent.on($.support.transition.end, removeElement) : + removeElement() + } + + + /* ALERT PLUGIN DEFINITION + * ======================= */ + + $.fn.alert = function (option) { + return this.each(function () { + var $this = $(this) + , data = $this.data('alert') + if (!data) $this.data('alert', (data = new Alert(this))) + if (typeof option == 'string') data[option].call($this) + }) + } + + $.fn.alert.Constructor = Alert + + + /* ALERT DATA-API + * ============== */ + + $(function () { + $('body').on('click.alert.data-api', dismiss, Alert.prototype.close) + }) + +}(window.jQuery); \ No newline at end of file diff --git a/vendor/assets/javascripts/vendor.js b/vendor/assets/javascripts/vendor.js index 9d833de06..a4d1ebcfb 100644 --- a/vendor/assets/javascripts/vendor.js +++ b/vendor/assets/javascripts/vendor.js @@ -12,6 +12,7 @@ //= require bootstrap-dropdown // require bootstrap-tooltip // require bootstrap-popover +//= require bootstrap-alert //= require chosen.jquery // require html5shiv // require_tree .