Merge pull request #365 from abf/rosa-build:345-update_to_rails4

#345: Update to rails 4
This commit is contained in:
avm 2014-03-27 12:12:48 +04:00
commit 93dd8dc48e
285 changed files with 2806 additions and 2870 deletions

View File

@ -1,6 +1,6 @@
language: ruby language: ruby
rvm: rvm:
- 2.1.0 - 2.1.1
bundler_args: --without development bundler_args: --without development
env: env:
- SPEC_GROUP=controllers - SPEC_GROUP=controllers
@ -18,7 +18,7 @@ before_install:
before_script: before_script:
- cp config/database.yml.sample config/database.yml - cp config/database.yml.sample config/database.yml
- cp config/application.yml.travis config/application.yml - cp config/application.yml.travis config/application.yml
- bundle exec rake db:create db:structure:load db:migrate - bundle exec rake db:create db:schema:load db:migrate
script: "./travis.sh" script: "./travis.sh"
branches: branches:
only: only:

107
Gemfile
View File

@ -1,71 +1,69 @@
source 'https://rubygems.org' source 'https://rubygems.org'
gem 'rails', '3.2.17' gem 'rails', '4.0.4'
gem 'redhillonrails_core', git: 'git://github.com/rosa-abf/redhillonrails_core.git', branch: 'rails31' # '~> 2.0.0.pre' # deprecated
gem 'pg', '~> 0.14.0' gem 'pg', '~> 0.17.1'
gem 'activerecord-postgres-hstore' gem 'schema_plus', '~> 1.4.0'
########
gem 'devise', '~> 2.2.3' gem 'protected_attributes'
########
gem 'devise', '~> 3.2.3'
gem 'omniauth' gem 'omniauth'
gem 'omniauth-facebook' gem 'omniauth-facebook'
gem 'omniauth-google-oauth2' gem 'omniauth-google-oauth2'
gem 'omniauth-github' gem 'omniauth-github'
# gem 'omniauth-openid', '~> 1.0.1' # gem 'omniauth-openid', '~> 1.0.1'
gem 'cancan', '1.6.7' # 1.6.8 fail specs with strange error # gem 'cancan', '1.6.10'
gem 'cancan', git: 'git://github.com/rosa-abf/cancan.git', tag: '1.6.10-abf'
gem 'ancestry', '~> 1.3.0' gem 'ancestry', '~> 2.0.0'
gem 'paperclip', '~> 4.1.0' gem 'paperclip', '~> 4.1.1'
gem 'resque', '~> 1.24' gem 'resque', '~> 1.25'
gem 'resque-status', '~> 0.3.3' gem 'resque-status', '~> 0.4.2'
gem 'resque_mailer', '~> 2.2' gem 'resque_mailer', '~> 2.2'
gem 'resque-scheduler' gem 'resque-scheduler', '~> 2.5.4'
# gem 'perform_later', '~> 1.3.0' # should be after resque_mailer
gem 'perform_later', git: 'git://github.com/KensoDev/perform_later.git' # should be after resque_mailer gem 'perform_later', git: 'git://github.com/KensoDev/perform_later.git' # should be after resque_mailer
gem 'russian', '~> 0.6.0' gem 'russian', '~> 0.6.0'
gem 'highline', '~> 1.6.11' gem 'highline', '~> 1.6.20'
gem 'state_machine' gem 'state_machine', '~> 1.2'
gem 'redis-rails' gem 'redis-rails', '~> 4.0'
gem 'grack', git: 'git://github.com/rosa-abf/grack.git', require: 'git_http' gem 'grack', git: 'git://github.com/rosa-abf/grack.git', require: 'git_http'
gem 'grit', git: 'git://github.com/rosa-abf/grit.git' gem 'grit', git: 'git://github.com/rosa-abf/grit.git'
gem 'charlock_holmes', '~> 0.6.9' gem 'charlock_holmes', '~> 0.6.9'
gem 'github-linguist', '~> 2.3.4', require: 'linguist' gem 'github-linguist', '~> 2.10', require: 'linguist'
gem 'diff-display', '~> 0.0.1' gem 'diff-display', '~> 0.0.1'
# Wiki # Wiki
gem "gollum", '~> 2.1.3' gem "gollum-lib", '~> 2.0'
gem "redcarpet", '~> 2.2.2' gem "redcarpet", '~> 3.1.1'
gem 'creole' gem 'creole'
gem 'rdiscount' gem 'rdiscount'
# gem 'org-ruby' # gem 'org-ruby'
gem 'RedCloth' gem 'RedCloth'
gem 'wikicloth' gem 'wikicloth'
# gem 'unicorn', '~> 4.3.1', platforms: [:mri, :rbx]
gem 'trinidad', '~> 1.0.2', platforms: :jruby
gem 'newrelic_rpm' gem 'newrelic_rpm'
# gem 'whenever', '~> 0.7.3', require: false
gem 'whenever', '~> 0.9.0', require: false gem 'whenever', '~> 0.9.0', require: false
gem 'jbuilder', '~> 1.4.2' gem 'jbuilder', '~> 2.0.3'
gem 'rails3-jquery-autocomplete', '~> 1.0.7' gem 'rails3-jquery-autocomplete', '~> 1.0'
gem 'will_paginate', '~> 3.0.3' gem 'will_paginate', '~> 3.0.5'
gem 'meta-tags', '~> 1.2.5', require: 'meta_tags' gem 'meta-tags', '~> 1.5', require: 'meta_tags'
gem "haml-rails", '~> 0.3.4' gem "haml-rails", '~> 0.5'
gem 'jquery-rails', '~> 2.0.2' gem 'jquery-rails', '~> 2.3.0'
gem 'ruby-haml-js', '~> 0.0.3' gem 'jquery-migrate-rails'
gem 'friendly_id' gem 'ruby-haml-js', '~> 0.0.5'
gem 'friendly_id', '~> 5.0.3'
gem 'rack-throttle' gem 'rack-throttle', '~> 0.3.0'
gem 'rest-client', '~> 1.6.6' gem 'rest-client', '~> 1.6.7'
gem 'ohm' gem 'ohm', '~> 1.3.2'
gem 'ohm-expire' gem 'ohm-expire', '~> 0.1.3'
gem 'ffi' gem 'ffi', '~> 1.9.3'
gem 'attr_encrypted', '1.2.1' gem 'attr_encrypted', '~> 1.3.2'
gem "gemoji", "~> 1.2.1", require: 'emoji/railtie' gem "gemoji", "~> 1.2.1", require: 'emoji/railtie'
# AngularJS related stuff # AngularJS related stuff
@ -79,15 +77,13 @@ gem 'soundmanager-rails'
gem 'time_diff' gem 'time_diff'
group :assets do gem 'sass-rails', '~> 4.0.1'
gem 'sass-rails', '~> 3.2.5' gem 'coffee-rails', '~> 4.0.1'
gem 'coffee-rails', '~> 3.2.2' gem 'compass-rails', '~> 1.1.6'
gem 'compass-rails', '~> 1.0.3' gem 'uglifier', '~> 2.4'
gem 'uglifier', '~> 1.2.4' gem 'therubyracer', '~> 0.12.1', platforms: [:mri, :rbx]
gem 'therubyracer', '~> 0.12.1', platforms: [:mri, :rbx] gem 'therubyrhino', '~> 1.73.1', platforms: :jruby
gem 'therubyrhino', '~> 1.73.1', platforms: :jruby
gem 'turbo-sprockets-rails3'
end
group :production do group :production do
gem "airbrake", '~> 3.1.2' gem "airbrake", '~> 3.1.2'
@ -116,11 +112,16 @@ group :development do
#gem 'ruby-dbus' if RUBY_PLATFORM =~ /linux/i # Error at deploy #gem 'ruby-dbus' if RUBY_PLATFORM =~ /linux/i # Error at deploy
end end
group :test do group :development, :test do
gem 'rspec-rails', '~> 2.11.0', group: 'development' gem 'rspec-rails', '~> 2.14.1'
gem 'factory_girl_rails', '~> 4.0.0' end
gem 'rr', '~> 1.0.4'
gem 'shoulda' group :test do
gem 'mock_redis', '0.6.2' gem 'factory_girl_rails', '~> 4.4.1'
gem 'rake' gem 'rr', '~> 1.1.2'
gem 'shoulda'
gem 'shoulda-matchers'
gem 'mock_redis', '~> 0.11'
gem 'rake'
gem 'test_after_commit'
end end

View File

@ -8,6 +8,13 @@ GIT
resque (> 1.25) resque (> 1.25)
resque-scheduler resque-scheduler
GIT
remote: git://github.com/rosa-abf/cancan.git
revision: fe1089b70c08d3ed11bac4f8e69ecb3d1d9adc29
tag: 1.6.10-abf
specs:
cancan (1.6.10)
GIT GIT
remote: git://github.com/rosa-abf/grack.git remote: git://github.com/rosa-abf/grack.git
revision: 020be3fef3fb308b9d214252522aa5945bf6584a revision: 020be3fef3fb308b9d214252522aa5945bf6584a
@ -23,74 +30,60 @@ GIT
mime-types (~> 1.15) mime-types (~> 1.15)
posix-spawn (~> 0.3.6) posix-spawn (~> 0.3.6)
GIT
remote: git://github.com/rosa-abf/redhillonrails_core.git
revision: c0945a4c6ad4bae4ca2750b105efcff162408b15
branch: rails31
specs:
redhillonrails_core (2.0.0.pre)
activerecord (>= 3.1.0.rc)
GEM GEM
remote: https://rubygems.org/ remote: https://rubygems.org/
specs: specs:
RedCloth (4.2.9) RedCloth (4.2.9)
actionmailer (3.2.17) actionmailer (4.0.4)
actionpack (= 3.2.17) actionpack (= 4.0.4)
mail (~> 2.5.4) mail (~> 2.5.4)
actionpack (3.2.17) actionpack (4.0.4)
activemodel (= 3.2.17) activesupport (= 4.0.4)
activesupport (= 3.2.17) builder (~> 3.1.0)
builder (~> 3.0.0)
erubis (~> 2.7.0) erubis (~> 2.7.0)
journey (~> 1.0.4) rack (~> 1.5.2)
rack (~> 1.4.5) rack-test (~> 0.6.2)
rack-cache (~> 1.2) activemodel (4.0.4)
rack-test (~> 0.6.1) activesupport (= 4.0.4)
sprockets (~> 2.2.1) builder (~> 3.1.0)
activemodel (3.2.17) activerecord (4.0.4)
activesupport (= 3.2.17) activemodel (= 4.0.4)
builder (~> 3.0.0) activerecord-deprecated_finders (~> 1.0.2)
activerecord (3.2.17) activesupport (= 4.0.4)
activemodel (= 3.2.17) arel (~> 4.0.0)
activesupport (= 3.2.17) activerecord-deprecated_finders (1.0.3)
arel (~> 3.0.2) activesupport (4.0.4)
tzinfo (~> 0.3.29) i18n (~> 0.6, >= 0.6.9)
activerecord-postgres-hstore (0.7.7) minitest (~> 4.2)
activerecord (>= 3.1) multi_json (~> 1.3)
pg-hstore (>= 1.1.5) thread_safe (~> 0.1)
rake tzinfo (~> 0.3.37)
activeresource (3.2.17) airbrake (3.1.16)
activemodel (= 3.2.17)
activesupport (= 3.2.17)
activesupport (3.2.17)
i18n (~> 0.6, >= 0.6.4)
multi_json (~> 1.0)
airbrake (3.1.15)
builder builder
multi_json multi_json
ancestry (1.3.0) ancestry (2.0.0)
activerecord (>= 2.3.14) activerecord (>= 3.0.0)
angular-i18n (0.1.2) angular-i18n (0.1.2)
angularjs-rails (1.2.7) angularjs-rails (1.2.14)
arel (3.0.3) arel (4.0.2)
attr_encrypted (1.2.1) atomic (1.1.16)
encryptor (>= 1.1.1) attr_encrypted (1.3.2)
bcrypt-ruby (3.1.2) encryptor (>= 1.3.0)
bcrypt (3.1.7)
bcrypt-ruby (3.1.5)
bcrypt (>= 3.1.3)
better_errors (1.1.0) better_errors (1.1.0)
coderay (>= 1.0.0) coderay (>= 1.0.0)
erubis (>= 2.6.6) erubis (>= 2.6.6)
binding_of_caller (0.7.2) binding_of_caller (0.7.2)
debug_inspector (>= 0.0.1) debug_inspector (>= 0.0.1)
blankslate (3.1.2) bluepill (0.0.64)
bluepill (0.0.66) activesupport (>= 3.0.0)
activesupport (>= 3.0.0, < 4.0.0)
daemons (~> 1.1.4) daemons (~> 1.1.4)
i18n (>= 0.5.0) i18n (>= 0.5.0)
state_machine (~> 1.1) state_machine (~> 1.1)
builder (3.0.4) builder (3.1.4)
callsite (0.0.11) callsite (0.0.11)
cancan (1.6.7)
cape (1.8.0) cape (1.8.0)
capistrano (2.15.5) capistrano (2.15.5)
highline highline
@ -101,99 +94,100 @@ GEM
capistrano_colors (0.5.5) capistrano_colors (0.5.5)
charlock_holmes (0.6.9.4) charlock_holmes (0.6.9.4)
chronic (0.10.2) chronic (0.10.2)
chunky_png (1.2.9) chunky_png (1.3.0)
climate_control (0.0.3) climate_control (0.0.3)
activesupport (>= 3.0) activesupport (>= 3.0)
cocaine (0.5.3) cocaine (0.5.3)
climate_control (>= 0.0.3, < 1.0) climate_control (>= 0.0.3, < 1.0)
coderay (1.1.0) coderay (1.1.0)
coffee-rails (3.2.2) coffee-rails (4.0.1)
coffee-script (>= 2.2.0) coffee-script (>= 2.2.0)
railties (~> 3.2.0) railties (>= 4.0.0, < 5.0)
coffee-script (2.2.0) coffee-script (2.2.0)
coffee-script-source coffee-script-source
execjs execjs
coffee-script-source (1.6.3) coffee-script-source (1.7.0)
compass (0.12.2) compass (0.12.3)
chunky_png (~> 1.2) chunky_png (~> 1.2)
fssm (>= 0.2.7) fssm (>= 0.2.7)
sass (~> 3.1) sass (= 3.2.14)
compass-rails (1.0.3) compass-rails (1.1.6)
compass (>= 0.12.2, < 0.14) compass (>= 0.12.2)
creole (0.5.0) creole (0.5.0)
daemons (1.1.9) daemons (1.1.9)
debug_inspector (0.0.2) debug_inspector (0.0.2)
devise (2.2.8) devise (3.2.3)
bcrypt-ruby (~> 3.0) bcrypt-ruby (~> 3.0)
orm_adapter (~> 0.1) orm_adapter (~> 0.1)
railties (~> 3.1) railties (>= 3.2.6, < 5)
warden (~> 1.2.1) thread_safe (~> 0.1)
warden (~> 1.2.3)
diff-display (0.0.1) diff-display (0.0.1)
diff-lcs (1.1.3) diff-lcs (1.2.5)
encryptor (1.3.0) encryptor (1.3.0)
erubis (2.7.0) erubis (2.7.0)
escape_utils (0.2.4) escape_utils (1.0.1)
eventmachine (1.0.3) eventmachine (1.0.3)
execjs (2.0.2) execjs (2.0.2)
expression_parser (0.9.0) expression_parser (0.9.0)
factory_girl (4.0.0) factory_girl (4.4.0)
activesupport (>= 3.0.0) activesupport (>= 3.0.0)
factory_girl_rails (4.0.0) factory_girl_rails (4.4.1)
factory_girl (~> 4.0.0) factory_girl (~> 4.4.0)
railties (>= 3.0.0) railties (>= 3.0.0)
faraday (0.8.9) faraday (0.9.0)
multipart-post (~> 1.2.0) multipart-post (>= 1.2, < 3)
ffi (1.0.11) ffi (1.9.3)
friendly_id (4.0.10.1) friendly_id (5.0.3)
activerecord (>= 3.0, < 4.0) activerecord (>= 4.0.0)
fssm (0.2.10) fssm (0.2.10)
gemoji (1.2.1) gemoji (1.2.1)
github-linguist (2.3.4) github-linguist (2.10.9)
charlock_holmes (~> 0.6.6) charlock_holmes (~> 0.6.6)
escape_utils (~> 0.2.3) escape_utils (>= 0.3.1)
mime-types (~> 1.19) mime-types (~> 1.19)
pygments.rb (>= 0.2.13) pygments.rb (~> 0.5.4)
github-markdown (0.6.3)
github-markup (0.7.5) github-markup (0.7.5)
gli (2.8.1) gitlab-grit (2.6.0)
gollum (2.1.10) charlock_holmes (~> 0.6.9)
github-markdown diff-lcs (~> 1.1)
github-markup (>= 0.7.0, < 1.0.0) mime-types (~> 1.15)
grit (~> 2.5.0) posix-spawn (~> 0.3.6)
mustache (>= 0.11.2, < 1.0.0) gli (2.9.0)
nokogiri (~> 1.4) gollum-lib (2.0.0)
posix-spawn (~> 0.3.0) github-markup (>= 0.7.5, < 1.0.0)
pygments.rb (~> 0.2.0) gitlab-grit (= 2.6.0)
sanitize (~> 2.0.0) nokogiri (~> 1.6.0)
sinatra (~> 1.0) rouge (~> 1.3.1)
stringex (~> 1.4.0) sanitize (~> 2.0.6)
useragent (~> 0.4.9) stringex (~> 2.1.0)
haml (3.1.8) haml (4.0.5)
haml-rails (0.3.5) tilt
actionpack (>= 3.1, < 4.1) haml-rails (0.5.3)
activesupport (>= 3.1, < 4.1) actionpack (>= 4.0.1)
haml (~> 3.1) activesupport (>= 4.0.1)
railties (>= 3.1, < 4.1) haml (>= 3.1, < 5.0)
railties (>= 4.0.1)
hashie (2.0.5) hashie (2.0.5)
highline (1.6.20) highline (1.6.21)
hike (1.2.3) hike (1.2.3)
hirb (0.7.1) hirb (0.7.1)
httpauth (0.2.0)
i18n (0.6.9) i18n (0.6.9)
jbuilder (1.4.2) jbuilder (2.0.4)
activesupport (>= 3.0.0) activesupport (>= 3.0.0)
multi_json (>= 1.2.0) multi_json (>= 1.2.0)
journey (1.0.4) jquery-migrate-rails (1.2.1)
jquery-rails (2.0.3) jquery-rails (2.3.0)
railties (>= 3.1.0, < 5.0) railties (>= 3.0, < 5.0)
thor (~> 0.14) thor (>= 0.14, < 2.0)
js-routes (0.9.6) js-routes (0.9.7)
rails (>= 3.2) railties (>= 3.2)
sprockets-rails
json (1.8.1) json (1.8.1)
jwt (0.1.10) jwt (0.1.11)
multi_json (>= 1.5) multi_json (>= 1.5)
libv8 (3.16.14.3) libv8 (3.16.14.3)
localeapp (0.6.14) localeapp (0.7.1)
gli gli
i18n i18n
json json
@ -201,21 +195,20 @@ GEM
rest-client rest-client
ya2yaml ya2yaml
logglier (0.2.11) logglier (0.2.11)
macaddr (1.6.1)
systemu (~> 2.5.0)
mail (2.5.4) mail (2.5.4)
mime-types (~> 1.16) mime-types (~> 1.16)
treetop (~> 1.4.8) treetop (~> 1.4.8)
mailcatcher (0.5.12) mailcatcher (0.2.4)
activesupport (~> 3.0) eventmachine
eventmachine (~> 1.0.0) haml
haml (>= 3.1, < 5) i18n
mail (~> 2.3) json
sinatra (~> 1.2) mail
skinny (~> 0.2.3) sinatra
sqlite3 (~> 1.3) skinny (>= 0.1.2)
thin (~> 1.5.0) sqlite3-ruby
meta-tags (1.2.6) thin
meta-tags (1.5.0)
actionpack actionpack
meta_request (0.2.8) meta_request (0.2.8)
callsite callsite
@ -223,31 +216,32 @@ GEM
railties railties
mime-types (1.25.1) mime-types (1.25.1)
mini_portile (0.5.2) mini_portile (0.5.2)
mock_redis (0.6.2) minitest (4.7.5)
momentjs-rails (2.5.0) mock_redis (0.11.0)
momentjs-rails (2.5.1)
railties (>= 3.1) railties (>= 3.1)
mono_logger (1.1.0) mono_logger (1.1.0)
multi_json (1.8.4) multi_json (1.9.0)
multipart-post (1.2.0) multi_xml (0.5.5)
mustache (0.99.5) multipart-post (2.0.0)
nest (1.1.2) nest (1.1.2)
redis redis
net-scp (1.1.2) net-scp (1.1.2)
net-ssh (>= 2.6.5) net-ssh (>= 2.6.5)
net-sftp (2.1.2) net-sftp (2.1.2)
net-ssh (>= 2.6.5) net-ssh (>= 2.6.5)
net-ssh (2.7.0) net-ssh (2.8.0)
net-ssh-gateway (1.2.0) net-ssh-gateway (1.2.0)
net-ssh (>= 2.6.5) net-ssh (>= 2.6.5)
newrelic_rpm (3.7.1.182) newrelic_rpm (3.7.3.204)
ng-rails-csrf (0.1.0) ng-rails-csrf (0.1.0)
nokogiri (1.6.1) nokogiri (1.6.1)
mini_portile (~> 0.5.0) mini_portile (~> 0.5.0)
oauth2 (0.8.1) oauth2 (0.9.3)
faraday (~> 0.8) faraday (>= 0.8, < 0.10)
httpauth (~> 0.1) jwt (~> 0.1.8)
jwt (~> 0.1.4) multi_json (~> 1.3)
multi_json (~> 1.0) multi_xml (~> 0.5)
rack (~> 1.2) rack (~> 1.2)
ohm (1.3.2) ohm (1.3.2)
nest (~> 1.0) nest (~> 1.0)
@ -255,9 +249,9 @@ GEM
scrivener (~> 0.0.3) scrivener (~> 0.0.3)
ohm-expire (0.1.3.2) ohm-expire (0.1.3.2)
ohm (>= 0.1.5) ohm (>= 0.1.5)
omniauth (1.1.4) omniauth (1.2.1)
hashie (>= 1.2, < 3) hashie (>= 1.2, < 3)
rack rack (~> 1.0)
omniauth-facebook (1.6.0) omniauth-facebook (1.6.0)
omniauth-oauth2 (~> 1.1) omniauth-oauth2 (~> 1.1)
omniauth-github (1.1.1) omniauth-github (1.1.1)
@ -266,122 +260,111 @@ GEM
omniauth-google-oauth2 (0.2.2) omniauth-google-oauth2 (0.2.2)
omniauth (~> 1.0) omniauth (~> 1.0)
omniauth-oauth2 omniauth-oauth2
omniauth-oauth2 (1.1.1) omniauth-oauth2 (1.1.2)
oauth2 (~> 0.8.0) faraday (>= 0.8, < 0.10)
omniauth (~> 1.0) multi_json (~> 1.3)
oauth2 (~> 0.9.3)
omniauth (~> 1.2)
orm_adapter (0.5.0) orm_adapter (0.5.0)
paperclip (4.1.0) paperclip (4.1.1)
activemodel (>= 3.0.0) activemodel (>= 3.0.0)
activesupport (>= 3.0.0) activesupport (>= 3.0.0)
cocaine (~> 0.5.3) cocaine (~> 0.5.3)
mime-types mime-types
pg (0.14.1) pg (0.17.1)
pg-hstore (1.2.0)
polyglot (0.3.4) polyglot (0.3.4)
posix-spawn (0.3.8) posix-spawn (0.3.8)
puma (2.7.1) protected_attributes (1.0.7)
activemodel (>= 4.0.1, < 5.0)
puma (2.8.1)
rack (>= 1.1, < 2.0) rack (>= 1.1, < 2.0)
pygments.rb (0.2.13) pygments.rb (0.5.4)
rubypython (~> 0.5.3) posix-spawn (~> 0.3.6)
rack (1.4.5) yajl-ruby (~> 1.1.0)
rack-cache (1.2) rack (1.5.2)
rack (>= 0.4)
rack-contrib (1.1.0) rack-contrib (1.1.0)
rack (>= 0.9.1) rack (>= 0.9.1)
rack-protection (1.5.2) rack-protection (1.5.2)
rack rack
rack-ssl (1.3.3)
rack
rack-test (0.6.2) rack-test (0.6.2)
rack (>= 1.0) rack (>= 1.0)
rack-throttle (0.3.0) rack-throttle (0.3.0)
rack (>= 1.0.0) rack (>= 1.0.0)
rails (3.2.17) rails (4.0.4)
actionmailer (= 3.2.17) actionmailer (= 4.0.4)
actionpack (= 3.2.17) actionpack (= 4.0.4)
activerecord (= 3.2.17) activerecord (= 4.0.4)
activeresource (= 3.2.17) activesupport (= 4.0.4)
activesupport (= 3.2.17) bundler (>= 1.3.0, < 2.0)
bundler (~> 1.0) railties (= 4.0.4)
railties (= 3.2.17) sprockets-rails (~> 2.0.0)
rails3-generators (1.0.0) rails3-generators (1.0.0)
railties (>= 3.0.0) railties (>= 3.0.0)
rails3-jquery-autocomplete (1.0.12) rails3-jquery-autocomplete (1.0.12)
rails (>= 3.0) rails (>= 3.0)
railties (3.2.17) railties (4.0.4)
actionpack (= 3.2.17) actionpack (= 4.0.4)
activesupport (= 3.2.17) activesupport (= 4.0.4)
rack-ssl (~> 1.3.2)
rake (>= 0.8.7) rake (>= 0.8.7)
rdoc (~> 3.4) thor (>= 0.18.1, < 2.0)
thor (>= 0.14.6, < 2.0)
rake (10.1.1) rake (10.1.1)
rdiscount (2.1.7) rdiscount (2.1.7)
rdoc (3.12.2) redcarpet (3.1.1)
json (~> 1.4)
redcarpet (2.2.2)
redis (3.0.7) redis (3.0.7)
redis-actionpack (3.2.4) redis-actionpack (4.0.0)
actionpack (~> 3.2.0) actionpack (~> 4)
redis-rack (~> 1.4.4) redis-rack (~> 1.5.0)
redis-store (~> 1.1.4) redis-store (~> 1.1.0)
redis-activesupport (3.2.5) redis-activesupport (4.0.0)
activesupport (~> 3.2.0) activesupport (~> 4)
redis-store (~> 1.1.0) redis-store (~> 1.1.0)
redis-namespace (1.4.1) redis-namespace (1.4.1)
redis (~> 3.0.4) redis (~> 3.0.4)
redis-rack (1.4.4) redis-rack (1.5.0)
rack (~> 1.4.0) rack (~> 1.5)
redis-store (~> 1.1.4) redis-store (~> 1.1.0)
redis-rails (3.2.4) redis-rails (4.0.0)
redis-actionpack (~> 3.2.4) redis-actionpack (~> 4)
redis-activesupport (~> 3.2.4) redis-activesupport (~> 4)
redis-store (~> 1.1.4) redis-store (~> 1.1.0)
redis-store (1.1.4) redis-store (1.1.4)
redis (>= 2.2) redis (>= 2.2)
redisk (0.2.2)
redis (>= 0.1.1)
redis-namespace (>= 0.1.0)
ref (1.0.5) ref (1.0.5)
resque (1.25.1) resque (1.25.2)
mono_logger (~> 1.0) mono_logger (~> 1.0)
multi_json (~> 1.0) multi_json (~> 1.0)
redis-namespace (~> 1.2) redis-namespace (~> 1.3)
sinatra (>= 0.9.2) sinatra (>= 0.9.2)
vegas (~> 0.1.2) vegas (~> 0.1.2)
resque-scheduler (2.5.4) resque-scheduler (2.5.5)
mono_logger (~> 1.0)
redis (~> 3.0.4) redis (~> 3.0.4)
resque (~> 1.25.1) resque (~> 1.25.1)
rufus-scheduler (~> 2.0.24) rufus-scheduler (~> 2.0.24)
resque-status (0.3.3) resque-status (0.4.2)
redisk (>= 0.2.1)
resque (~> 1.19) resque (~> 1.19)
uuid (~> 2.3)
resque_mailer (2.2.6) resque_mailer (2.2.6)
actionmailer (>= 3.0) actionmailer (>= 3.0)
rest-client (1.6.7) rest-client (1.6.7)
mime-types (>= 1.16) mime-types (>= 1.16)
rinku (1.7.3) rinku (1.7.3)
rr (1.0.5) rouge (1.3.3)
rspec (2.11.0) rr (1.1.2)
rspec-core (~> 2.11.0) rspec-core (2.14.8)
rspec-expectations (~> 2.11.0) rspec-expectations (2.14.5)
rspec-mocks (~> 2.11.0) diff-lcs (>= 1.1.3, < 2.0)
rspec-core (2.11.1) rspec-mocks (2.14.6)
rspec-expectations (2.11.3) rspec-rails (2.14.1)
diff-lcs (~> 1.1.3)
rspec-mocks (2.11.3)
rspec-rails (2.11.4)
actionpack (>= 3.0) actionpack (>= 3.0)
activemodel (>= 3.0)
activesupport (>= 3.0) activesupport (>= 3.0)
railties (>= 3.0) railties (>= 3.0)
rspec (~> 2.11.0) rspec-core (~> 2.14.0)
rspec-expectations (~> 2.14.0)
rspec-mocks (~> 2.14.0)
ruby-haml-js (0.0.5) ruby-haml-js (0.0.5)
execjs execjs
sprockets (>= 2.0.0) sprockets (>= 2.0.0)
rubypython (0.5.3)
blankslate (>= 2.1.2.3)
ffi (~> 1.0.7)
rufus-scheduler (2.0.24) rufus-scheduler (2.0.24)
tzinfo (>= 0.3.22) tzinfo (>= 0.3.22)
russian (0.6.0) russian (0.6.0)
@ -390,11 +373,15 @@ GEM
capistrano (~> 2.15.4) capistrano (~> 2.15.4)
sanitize (2.0.6) sanitize (2.0.6)
nokogiri (>= 1.4.4) nokogiri (>= 1.4.4)
sass (3.2.13) sass (3.2.14)
sass-rails (3.2.6) sass-rails (4.0.2)
railties (~> 3.2.0) railties (>= 4.0.0, < 5.0)
sass (>= 3.1.10) sass (~> 3.2.0)
tilt (~> 1.3) sprockets (~> 2.8, <= 2.11.0)
sprockets-rails (~> 2.0.0)
schema_plus (1.4.1)
rails (>= 3.2)
valuable
scrivener (0.0.3) scrivener (0.0.3)
shotgun (0.9) shotgun (0.9)
rack (>= 1.0) rack (>= 1.0)
@ -414,15 +401,21 @@ GEM
skype (0.2.7) skype (0.2.7)
tmp_cache tmp_cache
soundmanager-rails (1.0.0) soundmanager-rails (1.0.0)
sprockets (2.2.2) sprockets (2.11.0)
hike (~> 1.2) hike (~> 1.2)
multi_json (~> 1.0) multi_json (~> 1.0)
rack (~> 1.0) rack (~> 1.0)
tilt (~> 1.1, != 1.3.0) tilt (~> 1.1, != 1.3.0)
sqlite3 (1.3.8) sprockets-rails (2.0.1)
actionpack (>= 3.0)
activesupport (>= 3.0)
sprockets (~> 2.8)
sqlite3 (1.3.9)
sqlite3-ruby (1.3.3)
sqlite3 (>= 1.3.3)
state_machine (1.2.0) state_machine (1.2.0)
stringex (1.4.0) stringex (2.1.2)
systemu (2.5.2) test_after_commit (0.2.3)
therubyracer (0.12.1) therubyracer (0.12.1)
libv8 (~> 3.16.14.0) libv8 (~> 3.16.14.0)
ref ref
@ -431,6 +424,8 @@ GEM
eventmachine (>= 0.12.6) eventmachine (>= 0.12.6)
rack (>= 1.0.0) rack (>= 1.0.0)
thor (0.18.1) thor (0.18.1)
thread_safe (0.2.0)
atomic (>= 1.1.7, < 2)
tilt (1.4.1) tilt (1.4.1)
time_diff (0.3.0) time_diff (0.3.0)
activesupport activesupport
@ -439,22 +434,17 @@ GEM
treetop (1.4.15) treetop (1.4.15)
polyglot polyglot
polyglot (>= 0.3.1) polyglot (>= 0.3.1)
turbo-sprockets-rails3 (0.3.11) tzinfo (0.3.39)
railties (> 3.2.8, < 4.0.0) uglifier (2.4.0)
sprockets (>= 2.2.0)
tzinfo (0.3.38)
uglifier (1.2.7)
execjs (>= 0.3.0) execjs (>= 0.3.0)
multi_json (~> 1.3) json (>= 1.8.0)
underscore-rails (1.5.2) underscore-rails (1.6.0)
useragent (0.4.16) valuable (0.9.8)
uuid (2.3.7)
macaddr (~> 1.0)
vegas (0.1.11) vegas (0.1.11)
rack (>= 1.0.0) rack (>= 1.0.0)
warden (1.2.3) warden (1.2.3)
rack (>= 1.0) rack (>= 1.0)
whenever (0.9.0) whenever (0.9.2)
activesupport (>= 2.3.4) activesupport (>= 2.3.4)
chronic (>= 0.6.3) chronic (>= 0.6.3)
wikicloth (0.8.1) wikicloth (0.8.1)
@ -463,96 +453,98 @@ GEM
rinku rinku
will_paginate (3.0.5) will_paginate (3.0.5)
ya2yaml (0.31) ya2yaml (0.31)
yajl-ruby (1.1.0)
PLATFORMS PLATFORMS
ruby ruby
DEPENDENCIES DEPENDENCIES
RedCloth RedCloth
activerecord-postgres-hstore
airbrake (~> 3.1.2) airbrake (~> 3.1.2)
ancestry (~> 1.3.0) ancestry (~> 2.0.0)
angular-i18n (= 0.1.2) angular-i18n (= 0.1.2)
angularjs-rails angularjs-rails
attr_encrypted (= 1.2.1) attr_encrypted (~> 1.3.2)
better_errors better_errors
binding_of_caller binding_of_caller
bluepill (~> 0.0.60) bluepill (~> 0.0.60)
cancan (= 1.6.7) cancan!
cape cape
capistrano capistrano
capistrano_colors capistrano_colors
charlock_holmes (~> 0.6.9) charlock_holmes (~> 0.6.9)
coffee-rails (~> 3.2.2) coffee-rails (~> 4.0.1)
compass-rails (~> 1.0.3) compass-rails (~> 1.1.6)
creole creole
devise (~> 2.2.3) devise (~> 3.2.3)
diff-display (~> 0.0.1) diff-display (~> 0.0.1)
factory_girl_rails (~> 4.0.0) factory_girl_rails (~> 4.4.1)
ffi ffi (~> 1.9.3)
friendly_id friendly_id (~> 5.0.3)
gemoji (~> 1.2.1) gemoji (~> 1.2.1)
github-linguist (~> 2.3.4) github-linguist (~> 2.10)
gollum (~> 2.1.3) gollum-lib (~> 2.0)
grack! grack!
grit! grit!
haml-rails (~> 0.3.4) haml-rails (~> 0.5)
highline (~> 1.6.11) highline (~> 1.6.20)
hirb hirb
jbuilder (~> 1.4.2) jbuilder (~> 2.0.3)
jquery-rails (~> 2.0.2) jquery-migrate-rails
jquery-rails (~> 2.3.0)
js-routes js-routes
localeapp localeapp
logglier logglier
mailcatcher mailcatcher
meta-tags (~> 1.2.5) meta-tags (~> 1.5)
meta_request meta_request
mock_redis (= 0.6.2) mock_redis (~> 0.11)
momentjs-rails momentjs-rails
newrelic_rpm newrelic_rpm
ng-rails-csrf ng-rails-csrf
ohm ohm (~> 1.3.2)
ohm-expire ohm-expire (~> 0.1.3)
omniauth omniauth
omniauth-facebook omniauth-facebook
omniauth-github omniauth-github
omniauth-google-oauth2 omniauth-google-oauth2
paperclip (~> 4.1.0) paperclip (~> 4.1.1)
perform_later! perform_later!
pg (~> 0.14.0) pg (~> 0.17.1)
protected_attributes
puma puma
rack-throttle rack-throttle (~> 0.3.0)
rails (= 3.2.17) rails (= 4.0.4)
rails3-generators rails3-generators
rails3-jquery-autocomplete (~> 1.0.7) rails3-jquery-autocomplete (~> 1.0)
rake rake
rdiscount rdiscount
redcarpet (~> 2.2.2) redcarpet (~> 3.1.1)
redhillonrails_core! redis-rails (~> 4.0)
redis-rails resque (~> 1.25)
resque (~> 1.24) resque-scheduler (~> 2.5.4)
resque-scheduler resque-status (~> 0.4.2)
resque-status (~> 0.3.3)
resque_mailer (~> 2.2) resque_mailer (~> 2.2)
rest-client (~> 1.6.6) rest-client (~> 1.6.7)
rr (~> 1.0.4) rr (~> 1.1.2)
rspec-rails (~> 2.11.0) rspec-rails (~> 2.14.1)
ruby-haml-js (~> 0.0.3) ruby-haml-js (~> 0.0.5)
russian (~> 0.6.0) russian (~> 0.6.0)
rvm-capistrano rvm-capistrano
sass-rails (~> 3.2.5) sass-rails (~> 4.0.1)
schema_plus (~> 1.4.0)
shotgun shotgun
shoulda shoulda
shoulda-matchers
skype skype
soundmanager-rails soundmanager-rails
state_machine state_machine (~> 1.2)
test_after_commit
therubyracer (~> 0.12.1) therubyracer (~> 0.12.1)
therubyrhino (~> 1.73.1) therubyrhino (~> 1.73.1)
time_diff time_diff
trinidad (~> 1.0.2) uglifier (~> 2.4)
turbo-sprockets-rails3
uglifier (~> 1.2.4)
underscore-rails underscore-rails
whenever (~> 0.9.0) whenever (~> 0.9.0)
wikicloth wikicloth
will_paginate (~> 3.0.3) will_paginate (~> 3.0.5)

View File

@ -1,34 +1,24 @@
RosaABF.controller('ProjectScheduleController', ['$scope', '$http', function($scope, $http) { RosaABF.controller('ProjectScheduleController', ['$scope', '$http', function($scope, $http) {
// See: Modules::Models::Autostart::AUTOSTART_STATUSES // See: Autostart::AUTOSTART_STATUSES
$scope.statuses = { $scope.statuses = {
'0': 'autostart_statuses.0', '0': 'autostart_statuses.0',
'1': 'autostart_statuses.1', '1': 'autostart_statuses.1',
'2': 'autostart_statuses.2' '2': 'autostart_statuses.2'
}; };
$scope.project = null;
$scope.owner = null;
$scope.items = []; $scope.items = [];
$scope.init = function(name_with_owner) {
var arr = name_with_owner.split('/');
$scope.owner = arr[0];
$scope.project = arr[1];
}
$scope.updateStatus = function() { $scope.updateStatus = function() {
$http.put( $http.put(
Routes.project_path($scope.owner, $scope.project), Routes.project_path($scope.name_with_owner),
{project: {autostart_status: $scope.autostart_status}, format: 'json'} {project: {autostart_status: $scope.autostart_status}, format: 'json'}
); );
} }
$scope.updateSchedule = function(obj) { $scope.updateSchedule = function(obj) {
$http.put( $http.put(
Routes.project_schedule_path($scope.owner, $scope.project), Routes.project_schedule_path($scope.name_with_owner),
{enabled: obj.enabled, auto_publish: obj.auto_publish, repository_id: obj.repository_id, format: 'json'} {enabled: obj.enabled, auto_publish: obj.auto_publish, repository_id: obj.repository_id, format: 'json'}
); );
} }
}]); }]);

View File

@ -28,15 +28,15 @@ var BuildList = function(atts, dictionary) {
} }
if (self.project) { if (self.project) {
self.project.name_with_owner = self.project.owner + '/' + self.project.name;
if (self.last_published_commit_hash) { if (self.last_published_commit_hash) {
self.version_link_text = self.last_published_commit_hash + '...' + self.commit_hash; self.version_link_text = self.last_published_commit_hash + '...' + self.commit_hash;
self.version_link_url = Routes.diff_path(self.project.owner, self.project.name, self.version_link_text); self.version_link_url = Routes.diff_path(self.project.name_with_owner, self.version_link_text);
} else { } else {
self.version_link_text = self.commit_hash || self.project_version; self.version_link_text = self.commit_hash || self.project_version;
self.version_link_url = Routes.commit_path(self.project.owner, self.project.name, self.version_link_text); self.version_link_url = Routes.commit_path(self.project.name_with_owner, self.version_link_text);
} }
self.project.url = Routes.project_path(self.project.owner, self.project.name); self.project.url = Routes.project_path(self.project.name_with_owner);
self.project.name_with_owner = self.project.owner + '/' + self.project.name;
} }
if (self.user) if (self.user)

View File

@ -14,15 +14,15 @@ var ProjectRef = function(atts) {
self.ui_container = false; self.ui_container = false;
self.path = function(project) { self.path = function(project) {
return Routes.tree_path(project.owner.uname, project.name, self.ref); return Routes.tree_path(project.fullname, self.ref);
} }
self.diff_path = function(project, current_ref) { self.diff_path = function(project, current_ref) {
return Routes.diff_path(project.owner.uname, project.name, current_ref + '...' + self.ref); return Routes.diff_path(project.fullname, current_ref + '...' + self.ref);
} }
self.archive_path = function(project, type) { self.archive_path = function(project, type) {
return Routes.archive_path(project.owner.uname, project.name, project.name + '-' + self.ref, {format: type}); return Routes.archive_path(project.fullname, project.name + '-' + self.ref, {format: type});
} }
//return the scope-safe instance //return the scope-safe instance

View File

@ -13,7 +13,8 @@ RosaABF.factory('ApiCollaborator', ['$resource', function($resource) {
isArray : false isArray : false
}, },
find: { find: {
url: '/:owner/:project/collaborators/find.json', url: '/:owner/:project/collaborators/find',
format: 'json',
method: 'GET', method: 'GET',
isArray : true isArray : true
} }

View File

@ -5,27 +5,32 @@ RosaABF.factory("ApiProject", ['$resource', function($resource) {
{owner: '@project.owner.uname', project: '@project.name'}, {owner: '@project.owner.uname', project: '@project.name'},
{ {
tags: { tags: {
url: '/:owner/:project/tags.json', url: '/:owner/:project/tags',
format: 'json',
method: 'GET', method: 'GET',
isArray : false isArray : false
}, },
branches: { branches: {
url: '/:owner/:project/branches.json', url: '/:owner/:project/branches',
format: 'json',
method: 'GET', method: 'GET',
isArray : false isArray : false
}, },
delete_branch: { delete_branch: {
url: '/:owner/:project/branches/:ref.json', url: '/:owner/:project/branches/:ref',
format: 'json',
method: 'DELETE', method: 'DELETE',
isArray : false isArray : false
}, },
restore_branch: { restore_branch: {
url: '/:owner/:project/branches/:ref.json', // ?sha=<sha> url: '/:owner/:project/branches/:ref', // ?sha=<sha>
format: 'json',
method: 'PUT', method: 'PUT',
isArray : false isArray : false
}, },
create_branch: { create_branch: {
url: '/:owner/:project/branches.json', // ?new_ref=<new_ref>&from_ref=<from_ref> url: '/:owner/:project/branches', // ?new_ref=<new_ref>&from_ref=<from_ref>
format: 'json',
method: 'POST', method: 'POST',
isArray : false isArray : false
} }

View File

@ -1,7 +1,7 @@
RosaABF.factory("ApiPullRequest", ['$resource', function($resource) { RosaABF.factory("ApiPullRequest", ['$resource', function($resource) {
var PullRequestResource = $resource( var PullRequestResource = $resource(
'/:owner/:project/pull_requests/:serial_id.json', '/:owner/:project/pull_requests/:serial_id?format=json',
{ {
owner: '@pull_request.to_ref.project.owner_uname', owner: '@pull_request.to_ref.project.owner_uname',
project: '@pull_request.to_ref.project.name', project: '@pull_request.to_ref.project.name',
@ -13,7 +13,8 @@ RosaABF.factory("ApiPullRequest", ['$resource', function($resource) {
isArray : false isArray : false
}, },
merge: { merge: {
url: '/:owner/:project/pull_requests/:serial_id/merge.json', url: '/:owner/:project/pull_requests/:serial_id/merge',
format: 'json',
method: 'PUT', method: 'PUT',
isArray: false isArray: false
} }

View File

@ -1,4 +1,5 @@
//= require jquery //= require jquery
//= require jquery-migrate-min
//= require jquery_ujs //= require jquery_ujs
//= require jquery-ui //= require jquery-ui
//= require autocomplete-rails //= require autocomplete-rails

View File

@ -1,6 +1,7 @@
//= require jquery //= require jquery
//= require jquery_ujs //= require jquery_ujs
//= require jquery-ui //= require jquery-ui
//= require jquery-migrate-min
//= require pirobox_extended_min //= require pirobox_extended_min
//= require ./design/all //= require ./design/all

View File

@ -87,6 +87,6 @@ class Admin::UsersController < Admin::BaseController
protected protected
def find_user def find_user
@user = User.find_by_uname!(params[:id]) if params[:id] @user = User.find_by!(uname: params[:id]) if params[:id].present?
end end
end end

View File

@ -6,7 +6,7 @@ class Api::V1::AdvisoriesController < Api::V1::BaseController
authorize_resource :build_list, only: [:create, :update] authorize_resource :build_list, only: [:create, :update]
def index def index
@advisories = @advisories.scoped(include: [:platforms, :projects]). @advisories = @advisories.includes(:platforms, :projects).
paginate(paginate_params) paginate(paginate_params)
end end

View File

@ -13,6 +13,34 @@ class Api::V1::BaseController < ApplicationController
protected protected
# For this example, we are simply using token authentication
# via parameters. However, anyone could use Rails's token
# authentication features to get the token from a header.
def authenticate_user!
user_token = params[:authentication_token].presence
unless user_token
credentials = decode_credentials.select(&:present?)
user_token = credentials.first if credentials.size == 1
end
user = user_token && User.find_by_authentication_token(user_token.to_s)
if user
# Notice we are passing store false, so the user is not
# actually stored in the session and a token is needed
# for every request. If you want the token to work as a
# sign in token, you can simply remove store: false.
sign_in user, store: false
else
super
end
end
# Helper to decode credentials from HTTP.
def decode_credentials
return [] unless request.authorization && request.authorization =~ /^Basic (.*)/m
Base64.decode64($1).split(/:/, 2)
end
def set_csv_file_headers(file_name) def set_csv_file_headers(file_name)
headers['Content-Type'] = 'text/csv' headers['Content-Type'] = 'text/csv'
headers['Content-disposition'] = "attachment; filename=\"#{file_name}.csv\"" headers['Content-disposition'] = "attachment; filename=\"#{file_name}.csv\""

View File

@ -3,12 +3,13 @@ class Api::V1::BuildListsController < Api::V1::BaseController
before_filter :authenticate_user! before_filter :authenticate_user!
skip_before_filter :authenticate_user!, only: [:show, :index] if APP_CONFIG['anonymous_access'] skip_before_filter :authenticate_user!, only: [:show, :index] if APP_CONFIG['anonymous_access']
load_and_authorize_resource :project, only: :index load_resource :project, only: :index, parent: false
load_and_authorize_resource :build_list, only: [:show, :create, :cancel, :publish, :reject_publish, :create_container, :publish_into_testing] load_and_authorize_resource :build_list, only: [:show, :create, :cancel, :publish, :reject_publish, :create_container, :publish_into_testing]
def index def index
authorize!(:show, @project) if @project
filter = BuildList::Filter.new(@project, current_user, current_ability, params[:filter] || {}) filter = BuildList::Filter.new(@project, current_user, current_ability, params[:filter] || {})
@build_lists = filter.find.scoped(include: [:save_to_platform, :project, :user, :arch]) @build_lists = filter.find.includes(:save_to_platform, :project, :user, :arch)
@build_lists = @build_lists.recent.paginate(paginate_params) @build_lists = @build_lists.recent.paginate(paginate_params)
end end

View File

@ -6,6 +6,7 @@ class Api::V1::IssuesController < Api::V1::BaseController
load_and_authorize_resource :group, only: :group_index, find_by: :id, parent: false load_and_authorize_resource :group, only: :group_index, find_by: :id, parent: false
load_and_authorize_resource :project load_and_authorize_resource :project
skip_load_and_authorize_resource :project, only: [:all_index, :user_index, :group_index]
load_and_authorize_resource :issue, through: :project, find_by: :serial_id, only: [:show, :update, :create, :index] load_and_authorize_resource :issue, through: :project, find_by: :serial_id, only: [:show, :update, :create, :index]
def index def index
@ -60,7 +61,7 @@ class Api::V1::IssuesController < Api::V1::BaseController
private private
def render_issues_list def render_issues_list
@issues = @issues.includes(:user, :assignee, :labels).without_pull_requests @issues = @issues.preload(:user, :assignee, :labels, :project).without_pull_requests
if params[:status] == 'closed' if params[:status] == 'closed'
@issues = @issues.closed @issues = @issues.closed
else else

View File

@ -58,7 +58,7 @@ class Api::V1::JobsController < Api::V1::BaseController
def status def status
if params[:key] =~ /\Aabfworker::(rpm|iso)-worker-[\d]+::live-inspector\z/ if params[:key] =~ /\Aabfworker::(rpm|iso)-worker-[\d]+::live-inspector\z/
status = Resque.redis.get(params[:key]) status = Redis.current.get(params[:key])
end end
render json: { status: status }.to_json render json: { status: status }.to_json
end end

View File

@ -7,12 +7,12 @@ class ApplicationController < ActionController::Base
layout :layout_by_resource layout :layout_by_resource
# Hack to prevent token auth on all pages except atom feed: # Hack to prevent token auth on all pages except atom feed:
prepend_before_filter lambda { redirect_to(new_user_session_path) if params[:token] && params[:token].is_a?(String) && params[:format] != 'atom'} prepend_before_filter -> { redirect_to(new_user_session_path) if params[:token] && params[:token].is_a?(String) && params[:format] != 'atom'}
before_filter :set_locale before_filter :set_locale
before_filter lambda { EventLog.current_controller = self }, before_filter -> { EventLog.current_controller = self },
only: [:create, :destroy, :open_id, :cancel, :publish, :change_visibility] # :update only: [:create, :destroy, :open_id, :cancel, :publish, :change_visibility] # :update
after_filter lambda { EventLog.current_controller = nil } after_filter -> { EventLog.current_controller = nil }
helper_method :get_owner helper_method :get_owner
@ -48,10 +48,15 @@ class ApplicationController < ActionController::Base
def render_error(status) def render_error(status)
respond_to do |format| respond_to do |format|
format.json { render json: {status: status, message: t("flash.#{status}_message")}.to_json, status: status } format.json { render json: {status: status, message: t("flash.#{status}_message")}.to_json, status: status }
format.html { redirect_to "/#{status}.html", alert: t("flash.#{status}_message") } format.all { redirect_to "/#{status}.html", alert: t("flash.#{status}_message") }
end end
end end
# Helper method for all controllers
def permit_params(param_name, *accessible)
(params[param_name] || ActionController::Parameters.new).permit(*accessible.flatten)
end
def set_locale def set_locale
I18n.locale = check_locale( get_user_locale || I18n.locale = check_locale( get_user_locale ||
(request.env['HTTP_ACCEPT_LANGUAGE'] ? request.env['HTTP_ACCEPT_LANGUAGE'][0,2].downcase : nil )) (request.env['HTTP_ACCEPT_LANGUAGE'] ? request.env['HTTP_ACCEPT_LANGUAGE'][0,2].downcase : nil ))
@ -73,8 +78,8 @@ class ApplicationController < ActionController::Base
return current_user return current_user
end end
else else
params['user_id'] && User.find_by_id(params['user_id']) || params['user_id'] && User.find(params['user_id']) ||
params['group_id'] && Group.find_by_id(params['group_id']) || current_user params['group_id'] && Group.find(params['group_id']) || current_user
end end
end end

View File

@ -1,13 +1,14 @@
class Groups::MembersController < Groups::BaseController class Groups::MembersController < Groups::BaseController
before_filter lambda { authorize! :manage_members, @group } before_filter -> { authorize! :manage_members, @group }
def index def index
@members = @group.members.order(:uname) - [@group.owner]
end end
def update def update
params['user'].keys.each do |user_id| params['user'].keys.each do |user_id|
role = params['user'][user_id] role = params['user'][user_id]
if relation = @group.actors.where(actor_id: user_id, actor_type: 'User') #find_by_actor_id_and_actor_type(user_id, 'User') if relation = @group.actors.where(actor_id: user_id, actor_type: 'User')
relation.update_all(role: role) if @group.owner.id.to_s != user_id relation.update_all(role: role) if @group.owner.id.to_s != user_id
else else
relation = @group.actors.build(actor_id: user_id, actor_type: 'User', role: role) relation = @group.actors.build(actor_id: user_id, actor_type: 'User', role: role)
@ -34,7 +35,7 @@ class Groups::MembersController < Groups::BaseController
end end
def add def add
@user = User.find_by_uname(params[:user_uname]) @user = User.find_by uname: params[:user_uname]
if !@user if !@user
flash[:error] = t("flash.collaborators.wrong_user", uname: params[:user_uname]) flash[:error] = t("flash.collaborators.wrong_user", uname: params[:user_uname])
elsif @group.add_member(@user, params[:role]) elsif @group.add_member(@user, params[:role])

View File

@ -9,8 +9,8 @@ class Groups::ProfileController < Groups::BaseController
end end
def show def show
@path, page = group_path, params[:page].to_i @path, page = group_path(@group), params[:page].to_i
@projects = @group.own_projects.opened.search(params[:search]).recent @projects = @group.own_projects.search(params[:search]).recent
if request.xhr? if request.xhr?
if params[:visibility] != 'hidden' if params[:visibility] != 'hidden'
@projects = @projects.opened @projects = @projects.opened
@ -20,6 +20,7 @@ class Groups::ProfileController < Groups::BaseController
end end
render partial: 'shared/profile_projects', layout: nil, locals: {projects: paginate_projects(page)} render partial: 'shared/profile_projects', layout: nil, locals: {projects: paginate_projects(page)}
else else
@projects = @projects.opened
@projects = paginate_projects(page) @projects = paginate_projects(page)
end end
end end

View File

@ -112,7 +112,7 @@ class Platforms::PlatformsController < Platforms::BaseController
end end
def members def members
@members = @platform.members.order('name') @members = @platform.members.order(:uname)
end end
def remove_members def remove_members

View File

@ -67,8 +67,6 @@ class Platforms::ProductsController < Platforms::BaseController
protected protected
def set_project def set_project
args = params[:src_project].try(:split, '/') || [] @product.project = Project.find_by_owner_and_name params[:src_project]
@product.project = (args.length == 2) ?
Project.find_by_owner_and_name(*args) : nil
end end
end end

View File

@ -12,7 +12,7 @@ class Projects::BaseController < ApplicationController
end end
def find_project def find_project
@project = Project.find_by_owner_and_name!(params[:owner_name], params[:project_name]) if params[:owner_name].present? && params[:project_name].present? @project = Project.find_by_owner_and_name! params[:name_with_owner] if params[:name_with_owner].present?
end end
def init_statistics def init_statistics

View File

@ -8,13 +8,15 @@ class Projects::BuildListsController < Projects::BaseController
before_filter :find_build_list, only: [:show, :publish, :cancel, :update, :log, :create_container] before_filter :find_build_list, only: [:show, :publish, :cancel, :update, :log, :create_container]
load_and_authorize_resource :project, only: NESTED_ACTIONS load_and_authorize_resource :project, only: [:new, :create]
load_resource :project, only: :index, parent: false
load_and_authorize_resource :build_list, through: :project, only: NESTED_ACTIONS, shallow: true load_and_authorize_resource :build_list, through: :project, only: NESTED_ACTIONS, shallow: true
load_and_authorize_resource except: NESTED_ACTIONS load_and_authorize_resource except: NESTED_ACTIONS
before_filter :create_from_build_list, only: :new before_filter :create_from_build_list, only: :new
def index def index
authorize!(:show, @project) if @project
params[:filter].each{|k,v| params[:filter].delete(k) if v.blank? } if params[:filter] params[:filter].each{|k,v| params[:filter].delete(k) if v.blank? } if params[:filter]
respond_to do |format| respond_to do |format|

View File

@ -47,7 +47,7 @@ class Projects::CommentsController < Projects::BaseController
protected protected
def find_commentable def find_commentable
@commentable = params[:issue_id].present? && @project.issues.find_by_serial_id(params[:issue_id]) || @commentable = params[:issue_id].present? && @project.issues.find_by(serial_id: params[:issue_id]) ||
params[:commit_id].present? && @project.repo.commit(params[:commit_id]) params[:commit_id].present? && @project.repo.commit(params[:commit_id])
end end

View File

@ -1,6 +1,6 @@
class Projects::Git::BlobsController < Projects::Git::BaseController class Projects::Git::BlobsController < Projects::Git::BaseController
before_filter :set_blob before_filter :set_blob
before_filter lambda {authorize! :write, @project}, only: [:edit, :update] before_filter -> {authorize! :write, @project}, only: [:edit, :update]
def show def show
end end

View File

@ -1,10 +1,10 @@
class Projects::Git::TreesController < Projects::Git::BaseController 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 before_filter -> {redirect_to @project if params[:treeish] == @project.default_branch and params[:path].blank?}, only: :show
skip_before_filter :set_branch_and_tree, :set_treeish_and_path, only: :archive skip_before_filter :set_branch_and_tree, :set_treeish_and_path, only: :archive
before_filter lambda { raise Grit::NoSuchPathError if params[:treeish] != @branch.try(:name) }, only: [:branch, :destroy] before_filter -> { raise Grit::NoSuchPathError if params[:treeish] != @branch.try(:name) }, only: [:branch, :destroy]
skip_authorize_resource :project, only: [:destroy, :restore_branch, :create] skip_authorize_resource :project, only: [:destroy, :restore_branch, :create]
before_filter lambda { authorize!(:write, @project) }, only: [:destroy, :restore_branch, :create] before_filter -> { authorize!(:write, @project) }, only: [:destroy, :restore_branch, :create]
def show def show
unless request.xhr? unless request.xhr?

View File

@ -24,7 +24,7 @@ class Projects::IssuesController < Projects::BaseController
@sort = params[:sort] == 'updated' ? :updated : :created @sort = params[:sort] == 'updated' ? :updated : :created
@direction = params[:direction] == 'asc' ? :asc : :desc @direction = params[:direction] == 'asc' ? :asc : :desc
@issues = @issues.order("issues.#{@sort}_at #{@direction}") @issues = @issues.order("issues.#{@sort}_at #{@direction}")
@issues = @issues.includes(:assignee, :user, :pull_request).uniq @issues = @issues.preload(:assignee, :user, :pull_request).uniq
.paginate per_page: 20, page: params[:page] .paginate per_page: 20, page: params[:page]
if status == 200 if status == 200
render 'index', layout: request.xhr? ? 'with_sidebar' : 'application' render 'index', layout: request.xhr? ? 'with_sidebar' : 'application'
@ -81,11 +81,11 @@ class Projects::IssuesController < Projects::BaseController
end end
end end
def destroy # def destroy
@issue.destroy # @issue.destroy
flash[:notice] = t("flash.issue.destroyed") # flash[:notice] = t("flash.issue.destroyed")
redirect_to root_path # redirect_to root_path
end # end
def create_label def create_label
index(@project.labels.create!(name: params[:name], color: params[:color]) ? 200 : 500) index(@project.labels.create!(name: params[:name], color: params[:color]) ? 200 : 500)

View File

@ -1,7 +1,7 @@
class Projects::ProjectsController < Projects::BaseController class Projects::ProjectsController < Projects::BaseController
include ProjectsHelper include ProjectsHelper
before_filter :authenticate_user! before_filter :authenticate_user!
load_and_authorize_resource id_param: :project_name # to force member actions load load_and_authorize_resource id_param: :name_with_owner # to force member actions load
before_filter :who_owns, only: [:new, :create, :mass_import, :run_mass_import] before_filter :who_owns, only: [:new, :create, :mass_import, :run_mass_import]
def index def index

View File

@ -152,8 +152,7 @@ class Projects::PullRequestsController < Projects::BaseController
end end
def find_destination_project bang=true def find_destination_project bang=true
args = params[:to_project].try(:split, '/') || [] project = Project.find_by_owner_and_name params[:to_project]
project = (args.length == 2) ? Project.find_by_owner_and_name(*args) : nil
raise ActiveRecord::RecordNotFound if bang && !project raise ActiveRecord::RecordNotFound if bang && !project
project || @project project || @project
end end

View File

@ -45,7 +45,7 @@ class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
else else
raise 'Provider #{provider} not handled' raise 'Provider #{provider} not handled'
end end
user = User.find_or_initialize_by_email(auth['info']['email']) user = User.find_or_initialize_by email: auth['info']['email']
if user.new_record? if user.new_record?
user.name = name user.name = name
user.uname = name.gsub(/\s/, '').underscore user.uname = name.gsub(/\s/, '').underscore

View File

@ -13,6 +13,7 @@ class Users::ProfileController < Users::BaseController
end end
render partial: 'shared/profile_projects', layout: nil, locals: {projects: paginate_projects(page)} render partial: 'shared/profile_projects', layout: nil, locals: {projects: paginate_projects(page)}
else else
@projects = @projects.opened
@projects = paginate_projects(page) @projects = paginate_projects(page)
end end
end end

View File

@ -3,7 +3,7 @@ class Users::SettingsController < Users::BaseController
before_filter :set_current_user before_filter :set_current_user
def profile def profile
if request.put? if request.patch?
send_confirmation = params[:user][:email] != @user.email send_confirmation = params[:user][:email] != @user.email
if @user.update_without_password(params[:user]) if @user.update_without_password(params[:user])
update_avatar(@user, params) update_avatar(@user, params)
@ -27,7 +27,7 @@ class Users::SettingsController < Users::BaseController
end end
def private def private
if request.put? if request.patch?
if @user.update_with_password(params[:user]) if @user.update_with_password(params[:user])
flash[:notice] = t('flash.user.saved') flash[:notice] = t('flash.user.saved')
redirect_to private_settings_path redirect_to private_settings_path
@ -40,7 +40,7 @@ class Users::SettingsController < Users::BaseController
end end
def notifiers def notifiers
if request.put? if request.patch?
if @user.notifier.update_attributes(params[:settings_notifier]) if @user.notifier.update_attributes(params[:settings_notifier])
flash[:notice] = I18n.t("flash.settings.saved") flash[:notice] = I18n.t("flash.settings.saved")
redirect_to notifiers_settings_path redirect_to notifiers_settings_path
@ -49,4 +49,5 @@ class Users::SettingsController < Users::BaseController
end end
end end
end end
end end

View File

@ -3,8 +3,7 @@ class Users::UsersController < Users::BaseController
before_filter :find_user_by_key, only: [:allowed, :discover] before_filter :find_user_by_key, only: [:allowed, :discover]
def allowed def allowed
owner_name, project_name = params[:project].split '/' project = Project.find_by_owner_and_name! params[:project]
project = Project.find_by_owner_and_name!(owner_name, project_name ? project_name : '!')
action = case params[:action_type] action = case params[:action_type]
when 'git-upload-pack' when 'git-upload-pack'
then :read then :read

View File

@ -87,7 +87,7 @@ module BuildListsHelper
bl = item.build_list bl = item.build_list
{ {
text: str_version ? "#{shortest_hash_id item.version, hash_size}" : shortest_hash_id(item.version, hash_size), text: str_version ? "#{shortest_hash_id item.version, hash_size}" : shortest_hash_id(item.version, hash_size),
href: commit_path(bl.project.owner, bl.project, item.version) href: commit_path(bl.project, item.version)
} }
else else
{} {}
@ -99,10 +99,10 @@ module BuildListsHelper
if bl.commit_hash.present? if bl.commit_hash.present?
if bl.last_published_commit_hash.present? && bl.last_published_commit_hash != bl.commit_hash if bl.last_published_commit_hash.present? && bl.last_published_commit_hash != bl.commit_hash
link_to "#{shortest_hash_id bl.last_published_commit_hash, hash_size}...#{shortest_hash_id bl.commit_hash, hash_size}", link_to "#{shortest_hash_id bl.last_published_commit_hash, hash_size}...#{shortest_hash_id bl.commit_hash, hash_size}",
diff_path(bl.project.owner, bl.project, bl.last_published_commit_hash) + "...#{bl.commit_hash}" diff_path(bl.project, bl.last_published_commit_hash) + "...#{bl.commit_hash}"
else else
link_to str_version ? "#{shortest_hash_id bl.commit_hash, hash_size}" : shortest_hash_id(bl.commit_hash, hash_size), link_to str_version ? "#{shortest_hash_id bl.commit_hash, hash_size}" : shortest_hash_id(bl.commit_hash, hash_size),
commit_path(bl.project.owner, bl.project, bl.commit_hash) commit_path(bl.project, bl.commit_hash)
end end
else else
bl.project_version bl.project_version
@ -112,7 +112,7 @@ module BuildListsHelper
def product_build_list_version_link(bl, str_version = false) def product_build_list_version_link(bl, str_version = false)
if bl.commit_hash.present? if bl.commit_hash.present?
link_to str_version ? "#{shortest_hash_id bl.commit_hash} ( #{bl.project_version} )" : shortest_hash_id(bl.commit_hash), link_to str_version ? "#{shortest_hash_id bl.commit_hash} ( #{bl.project_version} )" : shortest_hash_id(bl.commit_hash),
commit_path(bl.project.owner, bl.project, bl.commit_hash) commit_path(bl.project, bl.commit_hash)
else else
bl.project_version bl.project_version
end end

View File

@ -1,7 +1,7 @@
# This module is based on # This module is based on
# https://github.com/gitlabhq/gitlabhq/blob/7665b1de7eed4addd7b94786c84e6674710e6377/app/helpers/gitlab_markdown_helper.rb # https://github.com/gitlabhq/gitlabhq/blob/7665b1de7eed4addd7b94786c84e6674710e6377/app/helpers/gitlab_markdown_helper.rb
module GitlabMarkdownHelper module GitlabMarkdownHelper
include Modules::Models::Markdown include MarkdownHelper
# Use this in places where you would normally use link_to(gfm(...), ...). # Use this in places where you would normally use link_to(gfm(...), ...).
# #

View File

@ -0,0 +1,190 @@
# This module is based on
# https://github.com/gitlabhq/gitlabhq/blob/397c3da9758c03a215a308c011f94261d9c61cfa/lib/gitlab/markdown.rb
# Custom parser for GitLab-flavored Markdown
#
# It replaces references in the text with links to the appropriate items in
# GitLab.
#
# Supported reference formats are:
# * @foo for team members
# * for issues & pull requests:
# * #123
# * abf#123
# * abf/rosa-build#123
# * 123456 for commits
#
# It also parses Emoji codes to insert images. See
# http://www.emoji-cheat-sheet.com/ for a list of the supported icons.
#
# Examples
#
# >> gfm("Hey @david, can you fix this?")
# => "Hey <a href="/users/david">@david</a>, can you fix this?"
#
# >> gfm("Commit 35d5f7c closes #1234")
# => "Commit <a href="/gitlab/commits/35d5f7c">35d5f7c</a> closes <a href="/gitlab/issues/1234">#1234</a>"
#
# >> gfm(":trollface:")
# => "<img alt=\":trollface:\" class=\"emoji\" src=\"/images/trollface.png" title=\":trollface:\" />
module MarkdownHelper
include IssuesHelper
attr_reader :html_options
# Public: Parse the provided text with GitLab-Flavored Markdown
#
# text - the source text
# html_options - extra options for the reference links as given to link_to
#
# Note: reference links will only be generated if @project is set
def gfm(text, html_options = {})
return text if text.nil?
# Duplicate the string so we don't alter the original, then call to_str
# to cast it back to a String instead of a SafeBuffer. This is required
# for gsub calls to work as we need them to.
text = text.dup.to_str
@html_options = html_options
# Extract pre blocks so they are not altered
# from http://github.github.com/github-flavored-markdown/
text.gsub!(%r{<pre>.*?</pre>|<code>.*?</code>}m) { |match| extract_piece(match) }
# Extract links with probably parsable hrefs
text.gsub!(%r{<a.*?>.*?</a>}m) { |match| extract_piece(match) }
# Extract images with probably parsable src
text.gsub!(%r{<img.*?>}m) { |match| extract_piece(match) }
# TODO: add popups with additional information
text = parse(text)
# Insert pre block extractions
text.gsub!(/\{gfm-extraction-(\h{32})\}/) do
insert_piece($1)
end
sanitize text.html_safe, attributes: ActionView::Base.sanitized_allowed_attributes + %w(id class)
end
private
def extract_piece(text)
@extractions ||= {}
md5 = Digest::MD5.hexdigest(text)
@extractions[md5] = text
"{gfm-extraction-#{md5}}"
end
def insert_piece(id)
@extractions[id]
end
# Private: Parses text for references and emoji
#
# text - Text to parse
#
# Note: reference links will only be generated if @project is set
#
# Returns parsed text
def parse(text)
parse_references(text) if @project
parse_emoji(text)
text
end
REFERENCE_PATTERN = %r{
(?<prefix>[\W\/])? # Prefix
( # Reference
@(?<user>[a-zA-Z][a-zA-Z0-9_\-\.]*) # User/Group uname
|(?<issue>(?:[a-zA-Z0-9\-_]*\/)?(?:[a-zA-Z0-9\-_]*)?\#[0-9]+) # Issue ID
|(?<commit>[\h]{6,40}) # Commit ID
)
(?<suffix>\W)? # Suffix
}x.freeze
TYPES = [:user, :issue, :commit].freeze
def parse_references(text)
# parse reference links
text.gsub!(REFERENCE_PATTERN) do |match|
prefix = $~[:prefix]
suffix = $~[:suffix]
type = TYPES.select{|t| !$~[t].nil?}.first
identifier = $~[type]
# Avoid HTML entities
if prefix && suffix && prefix[0] == '&' && suffix[-1] == ';'
match
elsif ref_link = reference_link(type, identifier)
"#{prefix}#{ref_link}#{suffix}"
else
match
end
end
end
EMOJI_PATTERN = %r{(:(\S+):)}.freeze
def parse_emoji(text)
# parse emoji
text.gsub!(EMOJI_PATTERN) do |match|
if valid_emoji?($2)
image_tag(image_path("emoji/#{$2}.png"), class: 'emoji', title: $1, alt: $1, size: "20x20")
else
match
end
end
end
# Private: Checks if an emoji icon exists in the image asset directory
#
# emoji - Identifier of the emoji as a string (e.g., "+1", "heart")
#
# Returns boolean
def valid_emoji?(emoji)
Emoji.names.include? emoji
end
# Private: Dispatches to a dedicated processing method based on reference
#
# reference - Object reference ("@1234", "!567", etc.)
# identifier - Object identifier (Issue ID, SHA hash, etc.)
#
# Returns string rendered by the processing method
def reference_link(type, identifier)
send("reference_#{type}", identifier)
end
def reference_user(identifier)
member = User.where(uname: identifier).first || Group.where(uname: identifier).first
if member
link_to("@#{identifier}", "/#{identifier}", html_options.merge(title: member.fullname, class: "gfm gfm-member #{html_options[:class]}"))
end
end
def reference_issue(identifier)
if issue = Issue.find_by_hash_tag(identifier, current_ability, @project)
if issue.pull_request
title = "#{PullRequest.model_name.human}: #{issue.title}"
url = project_pull_request_path(issue.project, issue.pull_request)
else
title = "#{Issue.model_name.human}: #{issue.title}"
url = project_issue_path(issue.project, issue.serial_id)
end
link_to(identifier, url, html_options.merge(title: title, class: "gfm gfm-issue #{html_options[:class]}"))
end
end
def reference_commit(identifier)
if commit = @project.repo.commit(identifier)
link_to shortest_hash_id(commit.id), commit_path(@project, commit.id)
title = GitPresenters::CommitAsMessagePresenter.present(commit, project: @project) do |presenter|
link_to(identifier, commit_path(@project, commit), html_options.merge(title: presenter.caption, class: "gfm gfm-commit #{html_options[:class]}"))
end
end
end
end

View File

@ -2,13 +2,13 @@ class BuildListsQueuesMonitoringJob
@queue = :hook @queue = :hook
def self.perform def self.perform
redis.smembers('queues').each do |key| Redis.current.smembers('resque:queues').each do |key|
next if key !~ /(user|mass)_build_/ next if key !~ /(user|mass)_build_/
queue = "queue:#{key}" queue = "resque:queue:#{key}"
id = key.gsub(/[^\d]/, '') id = key.gsub(/[^\d]/, '')
if redis.llen(queue) == 0 if Redis.current.llen(queue) == 0
if key =~ /^user/ if key =~ /^user/
last_updated_at = BuildList.select(:updated_at). last_updated_at = BuildList.select(:updated_at).
where(user_id: id).order('updated_at DESC').first where(user_id: id).order('updated_at DESC').first
@ -21,29 +21,25 @@ class BuildListsQueuesMonitoringJob
else else
# ensures that user/mass-build in the set from which we select next jobs # ensures that user/mass-build in the set from which we select next jobs
set_key = key =~ /^user/ ? BuildList::USER_BUILDS_SET : BuildList::MASS_BUILDS_SET set_key = key =~ /^user/ ? BuildList::USER_BUILDS_SET : BuildList::MASS_BUILDS_SET
redis.sadd set_key, id Redis.current.sadd set_key, id
end end
end end
end end
def self.clean(key) def self.clean(key)
queue = "queue:#{key}" queue = "resque:queue:#{key}"
# See [#watch]: https://github.com/redis/redis-rb/blob/master/lib/redis.rb#L2012 # See [#watch]: https://github.com/redis/redis-rb/blob/master/lib/redis.rb#L2012
redis.watch(queue) do Redis.current.watch(queue) do
if redis.llen(queue) == 0 if Redis.current.llen(queue) == 0
redis.multi do |multi| Redis.current.multi do |multi|
multi.del queue multi.del queue
multi.srem 'queues', key multi.srem 'resque:queues', key
end end
else else
redis.unwatch Redis.current.unwatch
end end
end end
end end
def self.redis
@redis ||= Resque.redis
end
end end

View File

@ -18,12 +18,12 @@ class UserMailer < ActionMailer::Base
end end
end end
def new_comment_notification(comment, user) def new_comment_notification(comment, user_id)
@user, @comment = user, comment @user, @comment = User.find(user_id), comment
subject = @comment.issue_comment? ? subject_for_issue(@comment.commentable) : subject = @comment.issue_comment? ? subject_for_issue(@comment.commentable) :
I18n.t('notifications.subjects.new_commit_comment_notification') I18n.t('notifications.subjects.new_commit_comment_notification')
mail( mail(
to: email_with_name(user, user.email), to: email_with_name(@user, @user.email),
subject: subject, subject: subject,
from: email_with_name(comment.user) from: email_with_name(comment.user)
) do |format| ) do |format|

View File

@ -15,7 +15,7 @@ class Ability
can [:show, :archive], Project, visibility: 'open' can [:show, :archive], Project, visibility: 'open'
can :get_id, Project, visibility: 'open' # api can :get_id, Project, visibility: 'open' # api
can(:refs_list, Project) {|project| can? :show, project} can(:refs_list, Project) {|project| can? :show, project}
can :read, Issue, project: {visibility: 'open'} can :read, Issue, project: { visibility: 'open' }
can [:read, :commits, :files], PullRequest, to_project: {visibility: 'open'} can [:read, :commits, :files], PullRequest, to_project: {visibility: 'open'}
can [:read, :log, :everything], BuildList, project: {visibility: 'open'} can [:read, :log, :everything], BuildList, project: {visibility: 'open'}
can [:read, :log], ProductBuildList#, product: {platform: {visibility: 'open'}} # double nested hash don't work can [:read, :log], ProductBuildList#, product: {platform: {visibility: 'open'}} # double nested hash don't work

View File

@ -1,20 +1,21 @@
class ActivityFeed < ActiveRecord::Base class ActivityFeed < ActiveRecord::Base
CODE = ['git_delete_branch_notification', 'git_new_push_notification', 'new_comment_commit_notification'] CODE = %w(git_delete_branch_notification git_new_push_notification new_comment_commit_notification)
TRACKER = ['issue_assign_notification', 'new_comment_notification', 'new_issue_notification'] TRACKER = %w(issue_assign_notification new_comment_notification new_issue_notification)
BUILD = ['build_list_notification'] BUILD = %w(build_list_notification)
WIKI = ['wiki_new_commit_notification'] WIKI = %w(wiki_new_commit_notification)
belongs_to :user belongs_to :user
serialize :data serialize :data
default_scope order("#{table_name}.created_at DESC") attr_accessible :user, :kind, :data
scope :outdated, offset(100)
default_scope { order created_at: :desc }
scope :outdated, -> { offset(100) }
self.per_page = 10 self.per_page = 10
def partial def partial
'home/partials/' + self.kind 'home/partials/' + self.kind
end end
end end

View File

@ -1,4 +1,6 @@
class Advisory < ActiveRecord::Base class Advisory < ActiveRecord::Base
self.include_root_in_json = false
has_and_belongs_to_many :platforms has_and_belongs_to_many :platforms
has_and_belongs_to_many :projects has_and_belongs_to_many :projects
has_many :build_lists has_many :build_lists
@ -9,18 +11,20 @@ class Advisory < ActiveRecord::Base
after_create :generate_advisory_id after_create :generate_advisory_id
before_save :normalize_references, if: :references_changed? before_save :normalize_references, if: :references_changed?
attr_accessible :description
ID_TEMPLATE = 'ROSA-%<type>s-%<year>d:%<id>04d' ID_TEMPLATE = 'ROSA-%<type>s-%<year>d:%<id>04d'
ID_STRING_TEMPLATE = 'ROSA-%<type>s-%<year>04s:%<id>04s' ID_STRING_TEMPLATE = 'ROSA-%<type>s-%<year>04s:%<id>04s'
TYPES = {'security' => 'SA', 'bugfix' => 'A'} TYPES = {'security' => 'SA', 'bugfix' => 'A'}
scope :search, lambda { |q| scope :search, ->(q) {
q = q.to_s.strip q = q.to_s.strip
where("#{table_name}.advisory_id ILIKE :q OR #{table_name}.description ILIKE :q OR build_list_packages.fullname ILIKE :q", q: "%#{q}%"). where("#{table_name}.advisory_id ILIKE :q OR #{table_name}.description ILIKE :q OR build_list_packages.fullname ILIKE :q", q: "%#{q}%").
joins(build_lists: :packages) if q.present? joins(build_lists: :packages) if q.present?
} }
scope :search_by_id, lambda { |aid| where("#{table_name}.advisory_id ILIKE ?", "%#{aid.to_s.strip}%") } scope :search_by_id, ->(aid) { where("#{table_name}.advisory_id ILIKE ?", "%#{aid.to_s.strip}%") }
scope :by_update_type, lambda { |ut| where(update_type: ut) } scope :by_update_type, ->(ut) { where(update_type: ut) }
default_scope order("#{table_name}.created_at DESC") default_scope { order(created_at: :desc) }
def to_param def to_param
advisory_id advisory_id
@ -37,7 +41,7 @@ class Advisory < ActiveRecord::Base
# this method fetches and structurize packages attached to current advisory. # this method fetches and structurize packages attached to current advisory.
def fetch_packages_info def fetch_packages_info
packages_info = Hash.new { |h, k| h[k] = {} } # maaagic, it's maaagic ;) packages_info = Hash.new { |h, k| h[k] = {} } # maaagic, it's maaagic ;)
build_lists.find_in_batches(include: [:save_to_platform, :packages, :project]) do |batch| build_lists.includes(:save_to_platform, :packages, :project).find_in_batches do |batch|
batch.each do |build_list| batch.each do |build_list|
tmp = build_list.packages.inject({srpm: nil, rpm: []}) do |h, p| tmp = build_list.packages.inject({srpm: nil, rpm: []}) do |h, p|
p.package_type == 'binary' ? h[:rpm] << p.fullname : h[:srpm] = p.fullname p.package_type == 'binary' ? h[:rpm] << p.fullname : h[:srpm] = p.fullname
@ -69,4 +73,3 @@ class Advisory < ActiveRecord::Base
end end
end end
Advisory.include_root_in_json = false

View File

@ -5,5 +5,5 @@ class Arch < ActiveRecord::Base
validates :name, presence: true, uniqueness: true validates :name, presence: true, uniqueness: true
scope :recent, order("#{table_name}.name ASC") scope :recent, -> { order(:name) }
end end

View File

@ -2,5 +2,5 @@ class Authentication < ActiveRecord::Base
belongs_to :user belongs_to :user
validates :provider, :uid, :user_id, presence: true validates :provider, :uid, :user_id, presence: true
validates :uid, uniqueness: {scope: :provider, case_sensitive: false} validates :uid, uniqueness: { scope: :provider, case_sensitive: false }
end end

View File

@ -2,18 +2,19 @@ class Avatar < ActiveRecord::Base
self.abstract_class = true self.abstract_class = true
MAX_AVATAR_SIZE = 5.megabyte MAX_AVATAR_SIZE = 5.megabyte
AVATAR_SIZES = {micro: 16, small: 30, medium: 40, big: 81} AVATAR_SIZES = { micro: 16, small: 30, medium: 40, big: 81 }
AVATAR_SIZES_HASH = {}.tap do |styles| AVATAR_SIZES_HASH = {}.tap do |styles|
AVATAR_SIZES.each do |name, size| AVATAR_SIZES.each do |name, size|
styles[name] = { geometry: "#{size}x#{size}#", format: :jpg, convert_options: '-strip -background white -flatten -quality 70'} styles[name] = { geometry: "#{size}x#{size}#", format: :jpg,
convert_options: '-strip -background white -flatten -quality 70' }
end end
end end
has_attached_file :avatar, styles: AVATAR_SIZES_HASH has_attached_file :avatar, styles: AVATAR_SIZES_HASH
validates_attachment_size :avatar, less_than_or_equal_to: MAX_AVATAR_SIZE validates_attachment_size :avatar, less_than_or_equal_to: MAX_AVATAR_SIZE
validates_attachment_content_type :avatar, content_type: /\Aimage/ validates_attachment_content_type :avatar, content_type: /\Aimage/
validates_attachment_file_name :avatar, matches: [ /(png|jpe?g|gif|bmp|tif?f)\z/i ] validates_attachment_file_name :avatar, matches: [ /(png|jpe?g|gif|bmp|tif?f)\z/i ]
attr_accessible :avatar attr_accessible :avatar
end end

View File

@ -1,8 +1,10 @@
class BuildList < ActiveRecord::Base class BuildList < ActiveRecord::Base
include Modules::Models::CommitAndVersion include CommitAndVersion
include Modules::Models::FileStoreClean include FileStoreClean
include AbfWorker::ModelHelper include AbfWorker::ModelHelper
include Modules::Observers::ActivityFeed::BuildList include Feed::BuildList
include BuildListObserver
include EventLoggable
belongs_to :project belongs_to :project
belongs_to :arch belongs_to :arch
@ -16,7 +18,7 @@ class BuildList < ActiveRecord::Base
belongs_to :mass_build, counter_cache: true, touch: true belongs_to :mass_build, counter_cache: true, touch: true
has_many :items, class_name: '::BuildList::Item', dependent: :destroy has_many :items, class_name: '::BuildList::Item', dependent: :destroy
has_many :packages, class_name: '::BuildList::Package', dependent: :destroy has_many :packages, class_name: '::BuildList::Package', dependent: :destroy
has_many :source_packages, class_name: '::BuildList::Package', conditions: {package_type: 'source'} has_many :source_packages, -> { where(package_type: 'source') }, class_name: '::BuildList::Package'
UPDATE_TYPES = %w[bugfix security enhancement recommended newpackage] UPDATE_TYPES = %w[bugfix security enhancement recommended newpackage]
RELEASE_UPDATE_TYPES = %w[bugfix security] RELEASE_UPDATE_TYPES = %w[bugfix security]
@ -31,28 +33,28 @@ class BuildList < ActiveRecord::Base
validates :project_id, :project_version, :arch, :include_repos, validates :project_id, :project_version, :arch, :include_repos,
:build_for_platform_id, :save_to_platform_id, :save_to_repository_id, presence: true :build_for_platform_id, :save_to_platform_id, :save_to_repository_id, presence: true
validates_numericality_of :priority, greater_than_or_equal_to: 0 validates_numericality_of :priority, greater_than_or_equal_to: 0
validates :external_nodes, inclusion: {in: EXTERNAL_NODES}, allow_blank: true validates :external_nodes, inclusion: { in: EXTERNAL_NODES }, allow_blank: true
validates :auto_publish_status, inclusion: {in: AUTO_PUBLISH_STATUSES} validates :auto_publish_status, inclusion: { in: AUTO_PUBLISH_STATUSES }
validates :update_type, inclusion: UPDATE_TYPES, validates :update_type, inclusion: UPDATE_TYPES,
unless: Proc.new { |b| b.advisory.present? } unless: Proc.new { |b| b.advisory.present? }
validates :update_type, inclusion: {in: RELEASE_UPDATE_TYPES, message: I18n.t('flash.build_list.frozen_platform')}, validates :update_type, inclusion: { in: RELEASE_UPDATE_TYPES, message: I18n.t('flash.build_list.frozen_platform') },
if: Proc.new { |b| b.advisory.present? } if: Proc.new { |b| b.advisory.present? }
validate lambda { validate -> {
errors.add(:build_for_platform, I18n.t('flash.build_list.wrong_platform')) if save_to_platform.main? && save_to_platform_id != build_for_platform_id errors.add(:build_for_platform, I18n.t('flash.build_list.wrong_platform')) if save_to_platform.main? && save_to_platform_id != build_for_platform_id
} }
validate lambda { validate -> {
errors.add(:build_for_platform, I18n.t('flash.build_list.wrong_build_for_platform')) unless build_for_platform.main? errors.add(:build_for_platform, I18n.t('flash.build_list.wrong_build_for_platform')) unless build_for_platform.main?
} }
validate lambda { validate -> {
errors.add(:save_to_repository, I18n.t('flash.build_list.wrong_repository')) if save_to_repository.platform_id != save_to_platform.id errors.add(:save_to_repository, I18n.t('flash.build_list.wrong_repository')) if save_to_repository.platform_id != save_to_platform.id
} }
validate lambda { validate -> {
errors.add(:save_to_repository, I18n.t('flash.build_list.wrong_include_repos')) if build_for_platform.repositories.where(id: include_repos).count != include_repos.size errors.add(:save_to_repository, I18n.t('flash.build_list.wrong_include_repos')) if build_for_platform.repositories.where(id: include_repos).count != include_repos.size
} }
validate lambda { validate -> {
errors.add(:save_to_repository, I18n.t('flash.build_list.wrong_project')) unless save_to_repository.projects.exists?(project_id) errors.add(:save_to_repository, I18n.t('flash.build_list.wrong_project')) unless save_to_repository.projects.exists?(project_id)
} }
before_validation lambda { self.include_repos = include_repos.uniq if include_repos.present? }, on: :create before_validation -> { self.include_repos = include_repos.uniq if include_repos.present? }, on: :create
before_validation :prepare_extra_repositories, on: :create before_validation :prepare_extra_repositories, on: :create
before_validation :prepare_extra_build_lists, on: :create before_validation :prepare_extra_build_lists, on: :create
before_validation :prepare_extra_params, on: :create before_validation :prepare_extra_params, on: :create
@ -95,40 +97,45 @@ class BuildList < ActiveRecord::Base
STATUSES.freeze STATUSES.freeze
HUMAN_STATUSES.freeze HUMAN_STATUSES.freeze
scope :recent, order("#{table_name}.updated_at DESC") scope :recent, -> { order(updated_at: :desc) }
scope :for_extra_build_lists, lambda {|ids, current_ability, save_to_platform| scope :for_extra_build_lists, ->(ids, current_ability, save_to_platform) {
s = scoped s = all
s = s.where(id: ids).published_container.accessible_by(current_ability, :read) s = s.where(id: ids).published_container.accessible_by(current_ability, :read)
s = s.where(save_to_platform_id: save_to_platform.id) if save_to_platform && save_to_platform.main? s = s.where(save_to_platform_id: save_to_platform.id) if save_to_platform && save_to_platform.main?
s s
} }
scope :for_status, lambda {|status| where(status: status) if status.present? } scope :for_status, ->(status) { where(status: status) if status.present? }
scope :for_user, lambda { |user| where(user_id: user.id) } scope :for_user, ->(user) { where(user_id: user.id) }
scope :not_owned_external_nodes, where("#{table_name}.external_nodes is null OR #{table_name}.external_nodes != ?", :owned) scope :not_owned_external_nodes, -> { where("#{table_name}.external_nodes is null OR #{table_name}.external_nodes != ?", :owned) }
scope :external_nodes, lambda { |type| where("#{table_name}.external_nodes = ?", type) } scope :external_nodes, ->(type) { where("#{table_name}.external_nodes = ?", type) }
scope :oldest, lambda { where("#{table_name}.updated_at < ?", Time.zone.now - 15.seconds) } scope :oldest, -> { where("#{table_name}.updated_at < ?", Time.zone.now - 15.seconds) }
scope :for_platform, lambda { |platform| where(build_for_platform_id: platform) } scope :for_platform, ->(platform) { where(build_for_platform_id: platform) }
scope :by_mass_build, lambda { |mass_build| where(mass_build_id: mass_build) } scope :by_mass_build, ->(mass_build) { where(mass_build_id: mass_build) }
scope :scoped_to_arch, lambda {|arch| where(arch_id: arch) if arch.present? } scope :scoped_to_arch, ->(arch) { where(arch_id: arch) if arch.present? }
scope :scoped_to_save_platform, lambda {|pl_id| where(save_to_platform_id: pl_id) if pl_id.present? } scope :scoped_to_save_platform, ->(pl_id) { where(save_to_platform_id: pl_id) if pl_id.present? }
scope :scoped_to_project_version, lambda {|project_version| where(project_version: project_version) if project_version.present? } scope :scoped_to_project_version, ->(pr_version) { where(project_version: pr_version) if pr_version.present? }
scope :scoped_to_is_circle, lambda {|is_circle| where(is_circle: is_circle) } scope :scoped_to_is_circle, ->(is_circle) { where(is_circle: is_circle) }
scope :for_creation_date_period, lambda{|start_date, end_date| scope :for_creation_date_period, ->(start_date, end_date) {
s = scoped s = all
s = s.where(["#{table_name}.created_at >= ?", start_date]) if start_date s = s.where(["#{table_name}.created_at >= ?", start_date]) if start_date
s = s.where(["#{table_name}.created_at <= ?", end_date]) if end_date s = s.where(["#{table_name}.created_at <= ?", end_date]) if end_date
s s
} }
scope :for_notified_date_period, lambda{|start_date, end_date| scope :for_notified_date_period, ->(start_date, end_date) {
s = scoped s = all
s = s.where("#{table_name}.updated_at >= ?", start_date) if start_date.present? s = s.where("#{table_name}.updated_at >= ?", start_date) if start_date.present?
s = s.where("#{table_name}.updated_at <= ?", end_date) if end_date.present? s = s.where("#{table_name}.updated_at <= ?", end_date) if end_date.present?
s s
} }
scope :scoped_to_project_name, lambda {|project_name| joins(:project).where('projects.name LIKE ?', "%#{project_name}%") if project_name.present? } scope :scoped_to_project_name, ->(project_name) {
scope :scoped_to_new_core, lambda {|new_core| where(new_core: new_core)} joins(:project).where('projects.name LIKE ?', "%#{project_name}%") if project_name.present?
scope :outdated, where("#{table_name}.created_at < ? AND #{table_name}.status NOT IN (?) OR #{table_name}.created_at < ?", Time.now - LIVE_TIME, [BUILD_PUBLISHED,BUILD_PUBLISHED_INTO_TESTING], Time.now - MAX_LIVE_TIME) }
scope :published_container, where(container_status: BUILD_PUBLISHED) scope :scoped_to_new_core, ->(new_core) { where(new_core: new_core) }
scope :outdated, -> {
where("#{table_name}.created_at < ? AND #{table_name}.status NOT IN (?) OR #{table_name}.created_at < ?",
Time.now - LIVE_TIME, [BUILD_PUBLISHED,BUILD_PUBLISHED_INTO_TESTING], Time.now - MAX_LIVE_TIME)
}
scope :published_container, -> { where(container_status: BUILD_PUBLISHED) }
serialize :additional_repos serialize :additional_repos
serialize :include_repos serialize :include_repos
@ -137,7 +144,7 @@ class BuildList < ActiveRecord::Base
serialize :extra_build_lists, Array serialize :extra_build_lists, Array
serialize :extra_params, Hash serialize :extra_params, Hash
after_commit :place_build, on: :create after_create :place_build
after_destroy :remove_container after_destroy :remove_container
state_machine :status, initial: :waiting_for_response do state_machine :status, initial: :waiting_for_response do
@ -157,7 +164,7 @@ class BuildList < ActiveRecord::Base
after_transition on: [:published, :fail_publish, :build_error, :tests_failed], do: :notify_users after_transition on: [:published, :fail_publish, :build_error, :tests_failed], do: :notify_users
after_transition on: :build_success, do: :notify_users, after_transition on: :build_success, do: :notify_users,
unless: lambda { |build_list| build_list.auto_publish? || build_list.auto_publish_into_testing? } unless: ->(build_list) { build_list.auto_publish? || build_list.auto_publish_into_testing? }
event :place_build do event :place_build do
transition waiting_for_response: :build_pending transition waiting_for_response: :build_pending
@ -413,7 +420,7 @@ class BuildList < ActiveRecord::Base
end end
def set_packages(pkg_hash, project_name) def set_packages(pkg_hash, project_name)
prj = Project.joins(repositories: :platform).where('platforms.id = ?', save_to_platform.id).find_by_name!(project_name) prj = Project.joins(repositories: :platform).where('platforms.id = ?', save_to_platform.id).find_by!(name: project_name)
build_package(pkg_hash['srpm'], 'source', prj) {|p| p.save!} build_package(pkg_hash['srpm'], 'source', prj) {|p| p.save!}
pkg_hash['rpm'].each do |rpm_hash| pkg_hash['rpm'].each do |rpm_hash|
build_package(rpm_hash, 'binary', prj) {|p| p.save!} build_package(rpm_hash, 'binary', prj) {|p| p.save!}
@ -425,7 +432,11 @@ class BuildList < ActiveRecord::Base
end end
def current_duration def current_duration
if started_at
(Time.now.utc - started_at.utc).to_i (Time.now.utc - started_at.utc).to_i
else
0
end
end end
def human_current_duration def human_current_duration
@ -527,17 +538,16 @@ class BuildList < ActiveRecord::Base
end end
def self.next_build def self.next_build
redis = Resque.redis kind_id = Redis.current.spop(USER_BUILDS_SET)
kind_id = redis.spop(USER_BUILDS_SET)
key = "user_build_#{kind_id}_rpm_worker_default" if kind_id key = "user_build_#{kind_id}_rpm_worker_default" if kind_id
task = Resque.pop(key) if key task = Resque.pop(key) if key
redis.sadd(USER_BUILDS_SET, kind_id) if task Redis.current.sadd(USER_BUILDS_SET, kind_id) if task
kind_id ||= redis.spop(MASS_BUILDS_SET) kind_id ||= Redis.current.spop(MASS_BUILDS_SET)
key ||= "mass_build_#{kind_id}_rpm_worker" if kind_id key ||= "mass_build_#{kind_id}_rpm_worker" if kind_id
task ||= Resque.pop(key) if key task ||= Resque.pop(key) if key
redis.sadd(MASS_BUILDS_SET, kind_id) if task && key =~ /^mass_build/ Redis.current.sadd(MASS_BUILDS_SET, kind_id) if task && key =~ /^mass_build/
if task if task
build_list = BuildList.where(id: task['args'][0]['id']).first build_list = BuildList.where(id: task['args'][0]['id']).first
@ -582,7 +592,7 @@ class BuildList < ActiveRecord::Base
users = [user, publisher].compact.uniq.select{ |u| u.notifier.can_notify? && u.notifier.new_build? } users = [user, publisher].compact.uniq.select{ |u| u.notifier.can_notify? && u.notifier.new_build? }
# find associated users # find associated users
users |= project.all_members.select do |u| users |= project.all_members(:notifier).select do |u|
u.notifier.can_notify? && u.notifier.new_associated_build? u.notifier.can_notify? && u.notifier.new_associated_build?
end if project end if project
users.each{ |u| UserMailer.build_list_notification(self, u).deliver } users.each{ |u| UserMailer.build_list_notification(self, u).deliver }

View File

@ -9,7 +9,7 @@ class BuildList::Filter
end end
def find def find
build_lists = @project ? @project.build_lists : BuildList.scoped build_lists = @project ? @project.build_lists : BuildList.all
if @options[:id] if @options[:id]
build_lists = build_lists.where(id: @options[:id]) build_lists = build_lists.where(id: @options[:id])

View File

@ -17,14 +17,12 @@ class BuildList::Item < ActiveRecord::Base
BuildList::BUILD_CANCELED => :build_canceled BuildList::BUILD_CANCELED => :build_canceled
} }
scope :recent, order("#{table_name}.level ASC, #{table_name}.name ASC") scope :recent, -> { order("#{table_name}.level ASC, #{table_name}.name ASC") }
def self.group_by_level def self.group_by_level
items = scoped({}).recent
groups = [] groups = []
current_level = -1 current_level = -1
items.each do |item| all.recent.find_each do |item|
groups << [] if current_level < item.level groups << [] if current_level < item.level
groups.last << item groups.last << item
current_level = item.level current_level = item.level

View File

@ -13,14 +13,14 @@ class BuildList::Package < ActiveRecord::Base
validates :package_type, inclusion: PACKAGE_TYPES validates :package_type, inclusion: PACKAGE_TYPES
validates :sha1, presence: true, if: Proc.new { |p| p.build_list.new_core? } validates :sha1, presence: true, if: Proc.new { |p| p.build_list.new_core? }
default_scope order("lower(#{table_name}.name) ASC, length(#{table_name}.name) ASC") default_scope { order("lower(#{table_name}.name) ASC, length(#{table_name}.name) ASC") }
# Fetches only actual (last publised) packages. # Fetches only actual (last publised) packages.
scope :actual, where(actual: true) scope :actual, -> { where(actual: true) }
scope :by_platform, lambda {|platform| where(platform_id: platform) } scope :by_platform, ->(platform) { where(platform_id: platform) }
scope :by_name, lambda {|name| where(name: name) } scope :by_name, ->(name) { where(name: name) }
scope :by_package_type, lambda {|type| where(package_type: type) } scope :by_package_type, ->(type) { where(package_type: type) }
scope :like_name, lambda {|name| where("#{table_name}.name ILIKE ?", "%#{name}%") if name.present?} scope :like_name, ->(name) { where("#{table_name}.name ILIKE ?", "%#{name}%") if name.present? }
before_create :set_epoch before_create :set_epoch

View File

@ -1,30 +0,0 @@
class BuildListObserver < ActiveRecord::Observer
observe :build_list
def before_update(record)
if record.status_changed?
record.started_at = Time.now if record.status == BuildList::BUILD_STARTED
if [BuildList::BUILD_ERROR,
BuildList::SUCCESS,
BuildList::BUILD_CANCELING,
BuildList::TESTS_FAILED,
BuildList::BUILD_CANCELED].include? record.status
# stores time interval beetwin build start and finish in seconds
record.duration = record.current_duration if record.started_at
if record.status == BuildList::SUCCESS
# Update project average build time
begin
statistic = record.project.project_statistics.find_or_create_by_arch_id(record.arch_id)
rescue ActiveRecord::RecordNotUnique
retry
end
build_count = statistic.build_count.to_i
new_av_time = ( statistic.average_build_time * build_count + record.duration.to_i ) / ( build_count + 1 )
statistic.update_attributes(average_build_time: new_av_time, build_count: build_count + 1)
end
end
end
end # before_update
end

View File

@ -1,5 +1,5 @@
class Comment < ActiveRecord::Base class Comment < ActiveRecord::Base
include Modules::Observers::ActivityFeed::Comment include Feed::Comment
# regexp take from http://code.google.com/p/concerto-platform/source/browse/v3/cms/lib/CodeMirror/mode/gfm/gfm.js?spec=svn861&r=861#71 # regexp take from http://code.google.com/p/concerto-platform/source/browse/v3/cms/lib/CodeMirror/mode/gfm/gfm.js?spec=svn861&r=861#71
# User/Project#Num # User/Project#Num
@ -7,17 +7,18 @@ class Comment < ActiveRecord::Base
# #Num # #Num
ISSUES_REGEX = /(?:[a-zA-Z0-9\-_]*\/)?(?:[a-zA-Z0-9\-_]*)?#[0-9]+/ ISSUES_REGEX = /(?:[a-zA-Z0-9\-_]*\/)?(?:[a-zA-Z0-9\-_]*)?#[0-9]+/
belongs_to :commentable, polymorphic: true, touch: true belongs_to :commentable, polymorphic: true
belongs_to :user belongs_to :user
belongs_to :project belongs_to :project
serialize :data serialize :data
validates :body, :user_id, :commentable_id, :commentable_type, :project_id, presence: true validates :body, :user_id, :commentable_id, :commentable_type, :project_id, presence: true
scope :for_commit, lambda {|c| where(commentable_id: c.id.hex, commentable_type: c.class)} scope :for_commit, ->(c) { where(commentable_id: c.id.hex, commentable_type: c.class) }
default_scope order("#{table_name}.created_at") default_scope { order(:created_at) }
after_create :subscribe_on_reply, unless: lambda {|c| c.commit_comment?} before_save :touch_commentable
after_create :subscribe_on_reply, unless: ->(c) { c.commit_comment? }
after_create :subscribe_users after_create :subscribe_users
attr_accessible :body, :data attr_accessible :body, :data
@ -186,8 +187,12 @@ class Comment < ActiveRecord::Base
protected protected
def touch_commentable
commentable.touch unless commit_comment?
end
def subscribe_on_reply def subscribe_on_reply
commentable.subscribes.create(user_id: user_id) if !commentable.subscribes.exists?(user_id: user_id) commentable.subscribes.where(user_id: user_id).first_or_create
end end
def subscribe_users def subscribe_users
@ -195,7 +200,7 @@ class Comment < ActiveRecord::Base
commentable.subscribes.create(user: user) if !commentable.subscribes.exists?(user_id: user.id) commentable.subscribes.create(user: user) if !commentable.subscribes.exists?(user_id: user.id)
elsif commit_comment? elsif commit_comment?
recipients = project.admins recipients = project.admins
recipients << user << User.where(email: commentable.try(:committer).try(:email)).first # commentor and committer recipients << user << User.find_by(email: commentable.try(:committer).try(:email)) # commentor and committer
recipients.compact.uniq.each do |user| recipients.compact.uniq.each do |user|
options = {project_id: project.id, subscribeable_id: commentable_id, subscribeable_type: commentable.class.name, user_id: user.id} options = {project_id: project.id, subscribeable_id: commentable_id, subscribeable_type: commentable.class.name, user_id: user.id}
Subscribe.subscribe_to_commit(options) if Subscribe.subscribed_to_commit?(project, user, commentable) Subscribe.subscribe_to_commit(options) if Subscribe.subscribed_to_commit?(project, user, commentable)

View File

@ -0,0 +1,37 @@
module ActsLikeMember
extend ActiveSupport::Concern
included do
scope :not_member_of, ->(item) {
where("
#{table_name}.id NOT IN (
SELECT relations.actor_id
FROM relations
WHERE (
relations.actor_type = '#{self.to_s}'
AND relations.target_type = '#{item.class.to_s}'
AND relations.target_id = #{item.id}
)
)
")
}
scope :search_order, -> { order("CHAR_LENGTH(#{table_name}.uname) ASC") }
scope :without, ->(a) { where("#{table_name}.id NOT IN (?)", a) }
scope :by_uname, ->(n) { where("#{table_name}.uname ILIKE ?", n) }
scope :search, ->(q) { by_uname("%#{q.to_s.strip}%") }
end
def to_param
uname
end
module ClassMethods
def find_by_insensitive_uname(uname)
find_by(uname: uname) || by_uname(uname).first
end
def find_by_insensitive_uname!(uname)
find_by_insensitive_uname(uname) or raise ActiveRecord::RecordNotFound
end
end
end

View File

@ -0,0 +1,31 @@
module Autostart
extend ActiveSupport::Concern
ONCE_A_12_HOURS = 0
ONCE_A_DAY = 1
ONCE_A_WEEK = 2
AUTOSTART_STATUSES = [ONCE_A_12_HOURS, ONCE_A_DAY, ONCE_A_WEEK]
HUMAN_AUTOSTART_STATUSES = {
ONCE_A_12_HOURS => :once_a_12_hours,
ONCE_A_DAY => :once_a_day,
ONCE_A_WEEK => :once_a_week
}
included do
validates :autostart_status, numericality: true,
inclusion: {in: AUTOSTART_STATUSES}, allow_blank: true
attr_accessible :autostart_status
end
def human_autostart_status
self.class.human_autostart_status(autostart_status)
end
module ClassMethods
def human_autostart_status(autostart_status)
I18n.t("layout.products.autostart_statuses.#{HUMAN_AUTOSTART_STATUSES[autostart_status]}")
end
end
end

View File

@ -0,0 +1,35 @@
module BuildListObserver
extend ActiveSupport::Concern
included do
before_update :update_average_build_time
end
private
def update_average_build_time
if status_changed?
started_at = Time.now if status == self.class::BUILD_STARTED
if [self.class::BUILD_ERROR,
self.class::SUCCESS,
self.class::BUILD_CANCELING,
self.class::TESTS_FAILED,
self.class::BUILD_CANCELED].include? status
# stores time interval beetwin build start and finish in seconds
duration = current_duration if started_at
if status == self.class::SUCCESS
# Update project average build time
begin
statistic = project.project_statistics.where(arch_id: arch_id).first_or_create
rescue ActiveRecord::RecordNotUnique
retry
end
build_count = statistic.build_count.to_i
new_av_time = ( statistic.average_build_time * build_count + duration.to_i ) / ( build_count + 1 )
statistic.update_attributes({average_build_time: new_av_time, build_count: build_count + 1}, without_protection: true)
end
end
end
end
end

View File

@ -0,0 +1,33 @@
module CommitAndVersion
extend ActiveSupport::Concern
included do
validate -> {
if project && (commit_hash.blank? || project.repo.commit(commit_hash).blank?)
errors.add :commit_hash, I18n.t('flash.build_list.wrong_commit_hash', commit_hash: commit_hash)
end
}
before_validation :set_commit_and_version
before_create :set_last_published_commit
end
protected
def set_commit_and_version
if project && project_version.present? && commit_hash.blank?
self.commit_hash = project.repo.commits(project_version).try(:first).try(:id)
elsif project_version.blank? && commit_hash.present?
self.project_version = commit_hash
end
end
def set_last_published_commit
return unless self.respond_to? :last_published_commit_hash # product?
last_commit = self.last_published.first.try :commit_hash
if last_commit && self.project.repo.commit(last_commit).present? # commit(nil) is not nil!
self.last_published_commit_hash = last_commit
end
end
end

View File

@ -0,0 +1,32 @@
module EventLoggable
extend ActiveSupport::Concern
included do
after_create :log_creation_event
after_destroy :log_destroying_event
end
private
def log_creation_event
ActiveSupport::Notifications.instrument(self.class.name, eventable: self)
end
def log_before_update
case self.class.to_s
when 'BuildList'
if status_changed? and [BuildList::BUILD_CANCELED, BuildList::BUILD_PUBLISHED].include?(status)
ActiveSupport::Notifications.instrument("event_log.observer", eventable: self)
end
when 'Platform'
if self.visibility_changed?
ActiveSupport::Notifications.instrument "event_log.observer", eventable: self,
message: I18n.t("activeself.attributes.platform.visibility_types.#{visibility}")
end
end
end
def log_destroying_event
ActiveSupport::Notifications.instrument(self.class.name, eventable: self)
end
end

View File

@ -1,4 +1,4 @@
module Modules::Observers::ActivityFeed::BuildList module Feed::BuildList
extend ActiveSupport::Concern extend ActiveSupport::Concern
included do included do

View File

@ -0,0 +1,74 @@
module Feed::Comment
extend ActiveSupport::Concern
included do
after_commit :new_comment_notifications, on: :create
# dont remove outdated issues link
after_update -> { Comment.create_link_on_issues_from_item(self) }
end
private
def new_comment_notifications
return if automatic?
if issue_comment?
commentable.subscribes.each do |subscribe|
if user_id != subscribe.user_id && can_notify_on_new_comment?(subscribe)
UserMailer.new_comment_notification(self, subscribe.user_id).deliver
ActivityFeed.create(
{
user_id: subscribe.user_id,
kind: 'new_comment_notification',
data: {
user_name: user.name,
user_email: user.email,
user_id: user_id,
comment_body: body,
issue_title: commentable.title,
issue_serial_id: commentable.serial_id,
project_id: commentable.project.id,
comment_id: id,
project_name: project.name,
project_owner: project.owner.uname
}
}, without_protection: true
)
end
end
elsif commit_comment?
Subscribe.comment_subscribes(self).where(status: true).each do |subscribe|
next if !subscribe.user_id || own_comment?(subscribe.user)
if subscribe.user.notifier.can_notify &&
( (subscribe.project.owner?(subscribe.user) && subscribe.user.notifier.new_comment_commit_repo_owner) ||
(subscribe.user.commentor?(self.commentable) && subscribe.user.notifier.new_comment_commit_commentor) ||
(subscribe.user.committer?(self.commentable) && subscribe.user.notifier.new_comment_commit_owner) )
UserMailer.new_comment_notification(self, subscribe.user_id).deliver
end
ActivityFeed.create(
{
user_id: subscribe.user_id,
kind: 'new_comment_commit_notification',
data: {
user_name: user.name,
user_email: user.email,
user_id: user_id,
comment_body: body,
commit_message: commentable.message,
commit_id: commentable.id,
project_id: project.id,
comment_id: id,
project_name: project.name,
project_owner: project.owner.uname
}
}, without_protection: true
)
end
end
Comment.create_link_on_issues_from_item(self)
end
def can_notify_on_new_comment?(subscribe)
notifier = SettingsNotifier.find_by user_id: subscribe.user_id
notifier && notifier.new_comment && notifier.can_notify
end
end

View File

@ -1,4 +1,4 @@
module Modules::Observers::ActivityFeed::Git module Feed::Git
def self.create_notifications(record) def self.create_notifications(record)
@ -49,7 +49,7 @@ module Modules::Observers::ActivityFeed::Git
end end
when 'Hash' # 'Gollum::Committer' when 'Hash' # 'Gollum::Committer'
actor = User.find_by_uname! record[:actor_name] actor = User.find_by! uname: record[:actor_name]
project = Project.find record[:project_id] project = Project.find record[:project_id]
project.admins.each do |recipient| project.admins.each do |recipient|

View File

@ -1,14 +1,14 @@
module Modules::Observers::ActivityFeed::Issue module Feed::Issue
extend ActiveSupport::Concern extend ActiveSupport::Concern
included do included do
after_commit :new_issue_notifications, on: :create after_commit :new_issue_notifications, on: :create
after_commit :send_assign_notifications, on: :create, if: Proc.new { |i| i.assignee } after_commit :send_assign_notifications, on: :create, if: ->(i) { i.assignee }
after_commit -> { send_assign_notifications(:update) }, on: :update after_update -> { send_assign_notifications(:update) }
after_commit :send_hooks, on: :create after_commit :send_hooks, on: :create
after_commit -> { send_hooks(:update) }, on: :update, if: Proc.new { |i| i.previous_changes['status'].present? } after_update -> { send_hooks(:update) }, if: ->(i) { i.previous_changes['status'].present? }
end end
private private
@ -34,7 +34,7 @@ module Modules::Observers::ActivityFeed::Issue
} }
) )
end end
Comment.create_link_on_issues_from_item(self) ::Comment.create_link_on_issues_from_item(self)
end end
def send_assign_notifications(action = :create) def send_assign_notifications(action = :create)
@ -57,7 +57,7 @@ module Modules::Observers::ActivityFeed::Issue
) )
end end
# dont remove outdated issues link # dont remove outdated issues link
Comment.create_link_on_issues_from_item(self) if previous_changes['title'].present? || previous_changes['body'].present? ::Comment.create_link_on_issues_from_item(self) if previous_changes['title'].present? || previous_changes['body'].present?
end end
def send_hooks(action = :create) def send_hooks(action = :create)

View File

@ -1,4 +1,4 @@
module Modules::Observers::ActivityFeed::User module Feed::User
extend ActiveSupport::Concern extend ActiveSupport::Concern
included do included do
@ -8,10 +8,9 @@ module Modules::Observers::ActivityFeed::User
private private
def new_user_notification def new_user_notification
ActivityFeed.create( activity_feeds.create(
user: self,
kind: 'new_user_notification', kind: 'new_user_notification',
data: {user_name: self.user_appeal, user_email: self.email} data: { user_name: user_appeal, user_email: email }
) )
end end

View File

@ -0,0 +1,49 @@
module FileStoreClean
extend ActiveSupport::Concern
included do
def destroy
destroy_files_from_file_store if Rails.env.production?
super
end
later :destroy, queue: :clone_build
def sha1_of_file_store_files
raise NotImplementedError, "You should implement this method"
end
def destroy_files_from_file_store(args = sha1_of_file_store_files)
files = *args
token = User.find_by(uname: 'file_store').authentication_token
uri = URI APP_CONFIG['file_store_url']
Net::HTTP.start(uri.host, uri.port) do |http|
files.each do |sha1|
begin
req = Net::HTTP::Delete.new("/api/v1/file_stores/#{sha1}.json")
req.basic_auth token, ''
http.request(req)
rescue # Dont care about it
end
end
end
end
def later_destroy_files_from_file_store(args)
destroy_files_from_file_store(args)
end
later :later_destroy_files_from_file_store, queue: :clone_build
end
def self.file_exist_on_file_store?(sha1)
begin
resp = JSON(RestClient.get "#{APP_CONFIG['file_store_url']}/api/v1/file_stores.json", params: {hash: sha1})
rescue # Dont care about it
resp = []
end
if resp[0].respond_to?('[]') && resp[0]['file_name'] && resp[0]['sha1_hash']
true
else
false
end
end
end

241
app/models/concerns/git.rb Normal file
View File

@ -0,0 +1,241 @@
require 'nokogiri'
require 'open-uri'
module Git
extend ActiveSupport::Concern
included do
has_attached_file :srpm
validates_attachment_size :srpm, less_than_or_equal_to: 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')
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 -> { 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(name_with_owner)
end
def versions
repo.tags.map(&:name) + repo.branches.map(&:name)
end
def create_branch(new_ref, from_ref, user)
return false if new_ref.blank? || from_ref.blank? || !(from_commit = repo.commit(from_ref))
status, out, err = repo.git.native(:branch, {process_info: true}, new_ref, from_commit.id)
if status == 0
Resque.enqueue(GitHook, owner.uname, name, from_commit.id, GitHook::ZERO, "refs/heads/#{new_ref}", 'commit', "user-#{user.id}", nil)
return true
end
return false
end
def delete_branch(branch, user)
return false if default_branch == branch.name
message = repo.git.native(:branch, {}, '-D', branch.name)
if message.present?
Resque.enqueue(GitHook, owner.uname, name, GitHook::ZERO, branch.commit.id, "refs/heads/#{branch.name}", 'commit', "user-#{user.id}", message)
end
return message.present?
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?
system "sudo chown -R rosa:rosa #{repo.path}" #FIXME Permission denied - /mnt/gitstore/git_projects/...
index.add(path, data)
if sha1 = index.commit(message, parents: [parent], actor: actor, last_tree: parent.tree.id, head: head)
Resque.enqueue(GitHook, owner.uname, name, sha1, sha1, "refs/heads/#{head}", 'commit', "user-#{options[:actor].id}", message)
end
sha1
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)
return [] unless tree
grouped = tree.contents.sort_by{|c| c.name.downcase}.group_by(&:class)
[
grouped[Grit::Tree],
grouped[Grit::Blob],
grouped[Grit::Submodule]
].compact.flatten.map do |node|
node_path = File.join([path.present? ? path : nil, node.name].compact)
[
node,
node_path,
repo.log(treeish, node_path, max_count: 1).first
]
end
end
def import_srpm(srpm_path = srpm.path, branch_name = 'import')
token = User.find_by(uname: 'rosa_system').authentication_token
opts = [srpm_path, path, branch_name, Rails.root.join('bin', 'file-store.rb'), token, APP_CONFIG['file_store_url']].join(' ')
system("#{Rails.root.join('bin', 'import_srpm.sh')} #{opts} >> /dev/null 2>&1")
end
def is_empty?
repo.branches.count == 0
end
def total_commits_count
return 0 if is_empty?
%x(cd #{path} && git rev-list --all | wc -l).to_i
end
protected
def build_path(dir)
File.join(APP_CONFIG['git_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, shared: false)
write_hook
end
def destroy_git_repo
FileUtils.rm_rf path
end
def write_hook
hook = "/home/#{APP_CONFIG['shell_user']}/gitlab-shell/hooks/post-receive"
hook_file = File.join(path, 'hooks', 'post-receive')
FileUtils.ln_sf hook, hook_file
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
MAX_SRC_SIZE = 1024*1024*256
def process_hook(owner_uname, repo, newrev, oldrev, ref, newrev_type, user = nil, message = nil)
rec = GitHook.new(owner_uname, repo, newrev, oldrev, ref, newrev_type, user, message)
Modules::Observers::ActivityFeed::Git.create_notifications rec
end
def run_mass_import(url, srpms_list, visibility, owner, add_to_repository_id)
doc = Nokogiri::HTML(open(url))
links = doc.css("a[href$='.src.rpm']")
return if links.count == 0
filter = srpms_list.lines.map(&:chomp).map(&:strip).select(&:present?)
repository = Repository.find add_to_repository_id
platform = repository.platform
dir = Dir.mktmpdir 'mass-import-', APP_CONFIG['tmpfs_path']
links.each do |link|
begin
package = link.attributes['href'].value
package.chomp!; package.strip!
next if package.size == 0 || package !~ /^[\w\.\-]+$/
next if filter.present? && !filter.include?(package)
uri = URI "#{url}/#{package}"
srpm_file = "#{dir}/#{package}"
Net::HTTP.start(uri.host) do |http|
if http.request_head(uri.path)['content-length'].to_i < MAX_SRC_SIZE
f = open(srpm_file, 'wb')
http.request_get(uri.path) do |resp|
resp.read_body{ |segment| f.write(segment) }
end
f.close
end
end
if name = `rpm -q --qf '[%{Name}]' -p #{srpm_file}` and $?.success? and name.present?
next if owner.projects.exists?(name: name)
description = `rpm -q --qf '[%{Description}]' -p #{srpm_file}`.scrub('')
project = owner.projects.build(
name: name,
description: description,
visibility: visibility,
is_package: false # See: Hook for #attach_to_personal_repository
)
project.owner = owner
if project.save
repository.projects << project rescue nil
project.update_attributes(is_package: true)
project.import_srpm srpm_file, platform.name
end
end
rescue => e
f.close if defined?(f)
Airbrake.notify_or_ignore(e, link: link.to_s, url: url, owner: owner)
ensure
File.delete srpm_file if srpm_file
end
end
rescue => e
Airbrake.notify_or_ignore(e, url: url, owner: owner)
ensure
FileUtils.remove_entry_secure dir if dir
end
end
end

View File

@ -0,0 +1,10 @@
module Owner
extend ActiveSupport::Concern
included do
validates :owner, presence: true
after_create do
relations.create(actor: owner, role: 'admin')
end
end
end

View File

@ -0,0 +1,37 @@
module PersonalRepository
extend ActiveSupport::Concern
included do
after_create :create_personal_repository, unless: :system?
end
def create_personal_repository
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!
rescue Exception => e
pl.now_destroy rescue false
raise e
end
return true
end
def personal_platform
own_platforms.personal.first
end
def personal_repository
personal_platform.repositories.first
end
end

View File

@ -0,0 +1,44 @@
module RegenerationStatus
extend ActiveSupport::Concern
READY = 0
WAITING_FOR_REGENERATION = 100
REGENERATING = 200
HUMAN_STATUSES = {
READY => :ready,
WAITING_FOR_REGENERATION => :waiting_for_regeneration,
REGENERATING => :regenerating
}
HUMAN_REGENERATION_STATUSES = {
AbfWorker::BaseObserver::COMPLETED => :completed,
AbfWorker::BaseObserver::FAILED => :failed,
AbfWorker::BaseObserver::CANCELED => :canceled
}.freeze
included do
after_update :cleanup_file_store
def sha1_of_file_store_files
files = []
files << last_regenerated_log_sha1 if last_regenerated_log_sha1.present?
files
end
def human_regeneration_status
self.class::HUMAN_REGENERATION_STATUSES[last_regenerated_status] || :no_data
end
def human_status
self.class::HUMAN_STATUSES[status] || :no_data
end
def cleanup_file_store
old_log_sha1 = last_regenerated_log_sha1_was
if old_log_sha1.present? && old_log_sha1 != last_regenerated_log_sha1
later_destroy_files_from_file_store([old_log_sha1])
end
end
end
end

View File

@ -0,0 +1,29 @@
module TimeLiving
extend ActiveSupport::Concern
included do
validates :time_living, numericality: { only_integer: true }, presence: true
validate -> {
# MIN_TIME_LIVING <= time_living <= MAX_TIME_LIVING or
# 2 min <= time_living <= 12 hours
# time_living in seconds
min = self.class.const_defined?(:MIN_TIME_LIVING) ? self.class::MIN_TIME_LIVING : 120
max = self.class.const_defined?(:MAX_TIME_LIVING) ? self.class::MAX_TIME_LIVING : 43200
if min > time_living.to_i || time_living.to_i > max
errors.add :time_living,
I18n.t('flash.time_living.numericality_error', min: (min / 60), max: (max / 60))
end
}
before_validation :convert_time_living
attr_accessible :time_living
end
protected
def convert_time_living
self.time_living = time_living.to_i * 60 if time_living_was.to_i != time_living.to_i
end
end

View File

@ -0,0 +1,31 @@
module TokenAuthenticatable
extend ActiveSupport::Concern
module ClassMethods
def find_by_authentication_token(authentication_token = nil)
if authentication_token
where(authentication_token: authentication_token).first
end
end
end
def ensure_authentication_token
if authentication_token.blank?
self.authentication_token = generate_authentication_token
end
end
def reset_authentication_token!
self.authentication_token = generate_authentication_token
save
end
private
def generate_authentication_token
loop do
token = Devise.friendly_token
break token unless self.class.unscoped.where(authentication_token: token).first
end
end
end

View File

@ -1,7 +1,7 @@
module Modules::Models::UrlHelper module UrlHelper
def default_url_options def default_url_options
host ||= EventLog.current_controller.request.host_with_port rescue ::Rosa::Application.config.action_mailer.default_url_options[:host] host ||= EventLog.current_controller.request.host_with_port rescue ::Rosa::Application.config.action_mailer.default_url_options[:host]
protocol ||= APP_CONFIG['mailer_https_url'] ? 'https' : 'http' rescue 'http' protocol ||= APP_CONFIG['mailer_https_url'] ? 'https' : 'http' rescue 'http'
{host: host, protocol: protocol} { host: host, protocol: protocol }
end end
end end

View File

@ -1,4 +1,4 @@
module Modules::Models::WebHooks module WebHooks
class << self class << self
protected protected
@ -45,10 +45,11 @@ module Modules::Models::WebHooks
password :password password :password
boolean :ssl, :message_without_join, :no_colors, :long_url, :notice boolean :ssl, :message_without_join, :no_colors, :long_url, :notice
end end
add_hook :jabber do add_hook :jabber do
string :user string :user
end end
SCHEMA.freeze SCHEMA.freeze
NAMES.freeze NAMES.freeze
end end

View File

@ -0,0 +1,31 @@
module Wiki
extend ActiveSupport::Concern
included do
after_save :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(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
end

View File

@ -4,14 +4,15 @@ class EventLog < ActiveRecord::Base
# self.per_page = 1 # self.per_page = 1
scope :eager_loading, preload(:user) scope :eager_loading, -> { preload(:user) }
scope :default_order, order("#{table_name}.id DESC") # order('created_at DESC') scope :default_order, -> { order(id: :desc) }
before_create do before_create do
self.user_name = user.try(:uname) || 'guest' self.user_name = user.try(:uname) || 'guest'
self.eventable_name ||= eventable.name if eventable.respond_to?(:name) self.eventable_name ||= eventable.name if eventable.respond_to?(:name)
end end
# after_create { self.class.current_controller = nil } # after_create { self.class.current_controller = nil }
attr_accessible :kind, :message, :eventable, :eventable_name
class << self class << self
def create_with_current_controller(attributes) def create_with_current_controller(attributes)

View File

@ -1,25 +0,0 @@
class EventLogObserver < ActiveRecord::Observer
observe :user, :platform, :repository, :project, :product, :build_list, :product_build_list
def after_create(record)
ActiveSupport::Notifications.instrument("event_log.observer", eventable: record)
end
def before_update(record)
case record.class.to_s
when 'BuildList'
if record.status_changed? and [BuildList::BUILD_CANCELED, BuildList::BUILD_PUBLISHED].include?(record.status)
ActiveSupport::Notifications.instrument("event_log.observer", eventable: record)
end
when 'Platform'
if record.visibility_changed?
ActiveSupport::Notifications.instrument "event_log.observer", eventable: record,
message: I18n.t("activerecord.attributes.platform.visibility_types.#{record.visibility}")
end
end
end
def after_destroy(record)
ActiveSupport::Notifications.instrument("event_log.observer", eventable: record)
end
end

View File

@ -8,6 +8,8 @@ class Feedback
include ActiveModel::MassAssignmentSecurity include ActiveModel::MassAssignmentSecurity
extend ActiveModel::Naming extend ActiveModel::Naming
self.include_root_in_json = false
attr_accessor :name, :email, :subject, :message attr_accessor :name, :email, :subject, :message
attr_accessible :name, :email, :subject, :message attr_accessible :name, :email, :subject, :message
@ -99,6 +101,4 @@ class Feedback
perform_validation = options[:validate] != false perform_validation = options[:validate] != false
perform_validation ? valid?(options[:context]) : true perform_validation ? valid?(options[:context]) : true
end end
end end
Feedback.include_root_in_json = false

View File

@ -8,7 +8,9 @@ class FlashNotify < ActiveRecord::Base
validates :status, inclusion: {in: STATUSES} validates :status, inclusion: {in: STATUSES}
validates :body_ru, :body_en, :status, presence: true validates :body_ru, :body_en, :status, presence: true
scope :published, where(published: true) scope :published, -> { where(published: true) }
attr_accessible :body_ru, :body_en, :status, :published
def hash_id def hash_id
@digest ||= Digest::MD5.hexdigest("#{self.id}-#{self.updated_at}") @digest ||= Digest::MD5.hexdigest("#{self.id}-#{self.updated_at}")

View File

@ -1,12 +1,13 @@
class GitHook class GitHook
include Feed::Git
include Resque::Plugins::Status
ZERO = '0000000000000000000000000000000000000000' ZERO = '0000000000000000000000000000000000000000'
@queue = :hook @queue = :hook
attr_reader :repo, :newrev, :oldrev, :newrev_type, :oldrev_type, :refname, attr_reader :repo, :newrev, :oldrev, :newrev_type, :oldrev_type, :refname,
:change_type, :rev, :rev_type, :refname_type, :owner, :project, :user, :message :change_type, :rev, :rev_type, :refname_type, :owner, :project, :user, :message
include Resque::Plugins::Status
def self.perform(*options) def self.perform(*options)
self.process(*options) self.process(*options)
end end
@ -64,19 +65,19 @@ class GitHook
end end
def self.process(*args) def self.process(*args)
Modules::Observers::ActivityFeed::Git.create_notifications(args.size > 1 ? GitHook.new(*args) : args.first) Feed::Git.create_notifications(args.size > 1 ? GitHook.new(*args) : args.first)
end end
def find_user(user) def find_user(user)
if user.blank? if user.blank?
# Local push # Local push
User.find_by_email(project.repo.commit(newrev).author.email) rescue nil User.find_by(email: project.repo.commit(newrev).author.email) rescue nil
elsif user =~ /\Auser-\d+\Z/ elsif user =~ /\Auser-\d+\Z/
# git push over http # git push over http
User.find(user.gsub('user-', '')) User.find(user.gsub('user-', ''))
elsif user =~ /\Akey-\d+\Z/ elsif user =~ /\Akey-\d+\Z/
# git push over ssh # git push over ssh
SshKey.find_by_id(user.gsub('key-', '')).try(:user) SshKey.find(user.gsub('key-', '')).try(:user)
end end
end end
end end

View File

@ -1,4 +1,7 @@
class Group < Avatar class Group < Avatar
include ActsLikeMember
include PersonalRepository
belongs_to :owner, class_name: 'User' belongs_to :owner, class_name: 'User'
has_many :relations, as: :actor, dependent: :destroy, dependent: :destroy has_many :relations, as: :actor, dependent: :destroy, dependent: :destroy
@ -15,10 +18,14 @@ class Group < Avatar
validates :uname, presence: true, uniqueness: {case_sensitive: false}, format: {with: /\A[a-z0-9_]+\z/}, reserved_name: true validates :uname, presence: true, uniqueness: {case_sensitive: false}, format: {with: /\A[a-z0-9_]+\z/}, reserved_name: true
validate { errors.add(:uname, :taken) if User.by_uname(uname).present? } validate { errors.add(:uname, :taken) if User.by_uname(uname).present? }
scope :opened, where('1=1') scope :opened, -> { all }
scope :by_owner, lambda {|owner| where(owner_id: owner.id)} scope :by_owner, ->(owner) { where(owner_id: owner.id) }
scope :by_admin, lambda {|admin| joins(:actors).where(:'relations.role' => 'admin', :'relations.actor_id' => admin.id, :'relations.actor_type' => 'User')} scope :by_admin, ->(admin) {
scope :by_admin_and_writer, lambda {|actor| joins(:actors).where(:'relations.role' => ['admin', 'writer'], :'relations.actor_id' => actor.id, :'relations.actor_type' => 'User')} joins(:actors).where('relations.role' => 'admin', 'relations.actor_id' => admin.id, 'relations.actor_type' => 'User')
}
scope :by_admin_and_writer, ->(actor) {
joins(:actors).where('relations.role' => ['admin', 'writer'], 'relations.actor_id' => actor.id, 'relations.actor_type' => 'User')
}
attr_accessible :uname, :description attr_accessible :uname, :description
attr_readonly :uname attr_readonly :uname
@ -27,10 +34,6 @@ class Group < Avatar
after_create :add_owner_to_members after_create :add_owner_to_members
include Modules::Models::ActsLikeMember
include Modules::Models::PersonalRepository
# include Modules::Models::Owner
def self.can_own_project(user) def self.can_own_project(user)
(by_owner(user) | by_admin_and_writer(user)) (by_owner(user) | by_admin_and_writer(user))
end end

View File

@ -1,7 +1,8 @@
class Hook < ActiveRecord::Base class Hook < ActiveRecord::Base
include Modules::Models::WebHooks include WebHooks
include Modules::Models::UrlHelper include UrlHelper
include Rails.application.routes.url_helpers include Rails.application.routes.url_helpers
belongs_to :project belongs_to :project
before_validation :cleanup_data before_validation :cleanup_data
@ -12,7 +13,7 @@ class Hook < ActiveRecord::Base
serialize :data, Hash serialize :data, Hash
scope :for_name, lambda {|name| where(name: name) if name.present? } scope :for_name, ->(name) { where(name: name) if name.present? }
def receive_issues(issue, action) def receive_issues(issue, action)
pull = issue.pull_request pull = issue.pull_request
@ -121,7 +122,7 @@ class Hook < ActiveRecord::Base
def cleanup_data def cleanup_data
if self.name.present? && fields = SCHEMA[self.name.to_sym] if self.name.present? && fields = SCHEMA[self.name.to_sym]
new_data = {} new_data = {}
fields.each{ |type, field| new_data[field] = self.data[field] } fields.each { |type, field| new_data[field] = self.data[field] }
self.data = new_data self.data = new_data
end end
end end
@ -140,7 +141,7 @@ class Hook < ActiveRecord::Base
modified << diff.a_path modified << diff.a_path
end end
end end
{removed: removed, added: added, modified: modified} { removed: removed, added: added, modified: modified }
end end
end end

View File

@ -1,5 +1,5 @@
class Issue < ActiveRecord::Base class Issue < ActiveRecord::Base
include Modules::Observers::ActivityFeed::Issue include Feed::Issue
STATUSES = ['open', 'closed'] STATUSES = ['open', 'closed']
belongs_to :project belongs_to :project
@ -10,8 +10,8 @@ class Issue < ActiveRecord::Base
has_many :comments, as: :commentable, dependent: :destroy has_many :comments, as: :commentable, dependent: :destroy
has_many :subscribes, as: :subscribeable, dependent: :destroy has_many :subscribes, as: :subscribeable, dependent: :destroy
has_many :labelings, dependent: :destroy has_many :labelings, dependent: :destroy
has_many :labels, through: :labelings, uniq: true has_many :labels, -> { uniq }, through: :labelings
has_one :pull_request, dependent: :destroy has_one :pull_request#, dependent: :destroy
validates :title, :body, :project_id, presence: true validates :title, :body, :project_id, presence: true
@ -22,15 +22,17 @@ class Issue < ActiveRecord::Base
attr_accessible :labelings_attributes, :title, :body, :assignee_id attr_accessible :labelings_attributes, :title, :body, :assignee_id
accepts_nested_attributes_for :labelings, allow_destroy: true accepts_nested_attributes_for :labelings, allow_destroy: true
scope :opened, where(status: 'open') scope :opened, -> { where(status: 'open') }
scope :closed, where(status: 'closed') scope :closed, -> { where(status: 'closed') }
scope :needed_checking, where(issues: {status: ['open', 'blocked', 'ready', 'already']}) scope :needed_checking, -> { where(issues: {status: ['open', 'blocked', 'ready', 'already']}) }
scope :not_closed_or_merged, needed_checking scope :not_closed_or_merged, -> { needed_checking }
scope :closed_or_merged, where(issues: {status: ['closed', 'merged']}) scope :closed_or_merged, -> { where(issues: {status: ['closed', 'merged']}) }
# Using mb_chars for correct transform to lowercase ('Русский Текст'.downcase => "Русский Текст") # Using mb_chars for correct transform to lowercase ('Русский Текст'.downcase => "Русский Текст")
scope :search, lambda {|q| where("#{table_name}.title ILIKE ?", "%#{q.mb_chars.downcase}%") if q.present?} scope :search, ->(q) { where("#{table_name}.title ILIKE ?", "%#{q.mb_chars.downcase}%") if q.present? }
scope :without_pull_requests, where('NOT EXISTS (select null from pull_requests as pr where pr.issue_id = issues.id)') scope :without_pull_requests, -> {
where('NOT EXISTS (select null from pull_requests as pr where pr.issue_id = issues.id)')
}
def assign_uname def assign_uname
assignee.uname if assignee assignee.uname if assignee

View File

@ -9,7 +9,7 @@ class KeyPair < ActiveRecord::Base
validates :repository_id, :user_id, presence: true validates :repository_id, :user_id, presence: true
validates :secret, :public, presence: true, length: { maximum: 10000 }, on: :create validates :secret, :public, presence: true, length: { maximum: 10000 }, on: :create
validates :repository_id, uniqueness: {message: I18n.t("activerecord.errors.key_pair.repo_key_exists")} validates :repository_id, uniqueness: { message: I18n.t("activerecord.errors.key_pair.repo_key_exists") }
validate :check_keys validate :check_keys
before_create { |record| record.key_id = @fingerprint } before_create { |record| record.key_id = @fingerprint }

View File

@ -3,8 +3,8 @@ class Label < ActiveRecord::Base
has_many :issues, through: :labelings has_many :issues, through: :labelings
belongs_to :project belongs_to :project
validates :name, uniqueness: {scope: :project_id} validates :name, uniqueness: { scope: :project_id }
validates :name, :color, presence: true validates :name, :color, presence: true
validates :color, format: { with: /\A([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})\z/, message: I18n.t('layout.issues.invalid_labels')} validates :color, format: { with: /\A([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})\z/, message: I18n.t('layout.issues.invalid_labels') }
end end

View File

@ -2,4 +2,5 @@ class Labeling < ActiveRecord::Base
belongs_to :issue belongs_to :issue
belongs_to :label belongs_to :label
attr_accessible :label_id
end end

View File

@ -1,5 +1,5 @@
class MassBuild < ActiveRecord::Base class MassBuild < ActiveRecord::Base
belongs_to :build_for_platform, class_name: 'Platform', conditions: {platform_type: 'main'} belongs_to :build_for_platform, -> { where(platform_type: 'main') }, class_name: 'Platform'
belongs_to :save_to_platform, class_name: 'Platform' belongs_to :save_to_platform, class_name: 'Platform'
belongs_to :user belongs_to :user
has_many :build_lists, dependent: :destroy has_many :build_lists, dependent: :destroy
@ -7,9 +7,9 @@ class MassBuild < ActiveRecord::Base
serialize :extra_repositories, Array serialize :extra_repositories, Array
serialize :extra_build_lists, Array serialize :extra_build_lists, Array
scope :recent, order("#{table_name}.created_at DESC") scope :recent, -> { order(created_at: :desc) }
scope :by_platform, lambda { |platform| where(save_to_platform_id: platform.id) } scope :by_platform, ->(platform) { where(save_to_platform_id: platform.id) }
scope :outdated, where("#{table_name}.created_at < ?", Time.now + 1.day - BuildList::MAX_LIVE_TIME) scope :outdated, -> { where("#{table_name}.created_at < ?", Time.now + 1.day - BuildList::MAX_LIVE_TIME) }
attr_accessor :arches attr_accessor :arches
attr_accessible :arches, :auto_publish, :projects_list, :build_for_platform_id, attr_accessible :arches, :auto_publish, :projects_list, :build_for_platform_id,
@ -41,7 +41,7 @@ class MassBuild < ActiveRecord::Base
next if name.blank? next if name.blank?
name.chomp!; name.strip! name.chomp!; name.strip!
if project = Project.joins(:repositories).where('repositories.id in (?)', save_to_platform.repository_ids).find_by_name(name) if project = Project.joins(:repositories).where('repositories.id in (?)', save_to_platform.repository_ids).find_by(name: name)
begin begin
return if self.reload.stop_build return if self.reload.stop_build
increase_rt = increase_release_tag? increase_rt = increase_release_tag?

View File

@ -1,9 +1,11 @@
class Platform < ActiveRecord::Base class Platform < ActiveRecord::Base
extend FriendlyId extend FriendlyId
friendly_id :name friendly_id :name, use: [:finders]
include Modules::Models::FileStoreClean include FileStoreClean
include Modules::Models::RegenerationStatus include RegenerationStatus
include Owner
include EventLoggable
AUTOMATIC_METADATA_REGENERATIONS = %w(day week) AUTOMATIC_METADATA_REGENERATIONS = %w(day week)
VISIBILITIES = %w(open hidden) VISIBILITIES = %w(open hidden)
@ -30,16 +32,16 @@ class Platform < ActiveRecord::Base
has_many :mass_builds, foreign_key: :save_to_platform_id has_many :mass_builds, foreign_key: :save_to_platform_id
validates :description, presence: true validates :description, presence: true
validates :visibility, presence: true, inclusion: {in: VISIBILITIES} validates :visibility, presence: true, inclusion: { in: VISIBILITIES }
validates :automatic_metadata_regeneration, inclusion: {in: AUTOMATIC_METADATA_REGENERATIONS}, allow_blank: true validates :automatic_metadata_regeneration, inclusion: { in: AUTOMATIC_METADATA_REGENERATIONS }, allow_blank: true
validates :name, uniqueness: {case_sensitive: false}, presence: true, format: { with: /\A#{NAME_PATTERN}\z/ } validates :name, uniqueness: {case_sensitive: false}, presence: true, format: { with: /\A#{NAME_PATTERN}\z/ }
validates :distrib_type, presence: true, inclusion: {in: APP_CONFIG['distr_types']} validates :distrib_type, presence: true, inclusion: { in: APP_CONFIG['distr_types'] }
validate lambda { validate -> {
if released_was && !released if released_was && !released
errors.add(:released, I18n.t('flash.platform.released_status_can_not_be_changed')) errors.add(:released, I18n.t('flash.platform.released_status_can_not_be_changed'))
end end
} }
validate lambda { validate -> {
if personal? && (owner_id_changed? || owner_type_changed?) if personal? && (owner_id_changed? || owner_type_changed?)
errors.add :owner, I18n.t('flash.platform.owner_can_not_be_changed') errors.add :owner, I18n.t('flash.platform.owner_can_not_be_changed')
end end
@ -51,25 +53,23 @@ class Platform < ActiveRecord::Base
after_update :freeze_platform_and_update_repos after_update :freeze_platform_and_update_repos
after_update :update_owner_relation after_update :update_owner_relation
after_create lambda { symlink_directory unless hidden? } after_create -> { symlink_directory unless hidden? }
after_destroy lambda { remove_symlink_directory unless hidden? } after_destroy -> { remove_symlink_directory unless hidden? }
scope :search_order, order("CHAR_LENGTH(#{table_name}.name) ASC") scope :search_order, -> { order(:name) }
scope :search, lambda {|q| where("#{table_name}.name ILIKE ?", "%#{q.to_s.strip}%")} scope :search, ->(q) { where("#{table_name}.name ILIKE ?", "%#{q.to_s.strip}%") }
scope :by_visibilities, lambda {|v| where(visibility: v)} scope :by_visibilities, ->(v) { where(visibility: v) }
scope :opened, where(visibility: 'open') scope :opened, -> { where(visibility: 'open') }
scope :hidden, where(visibility: 'hidden') scope :hidden, -> { where(visibility: 'hidden') }
scope :by_type, lambda {|type| where(platform_type: type) if type.present?} scope :by_type, ->(type) { where(platform_type: type) if type.present? }
scope :main, by_type('main') scope :main, -> { by_type('main') }
scope :personal, by_type('personal') scope :personal, -> { by_type('personal') }
scope :waiting_for_regeneration, where(status: WAITING_FOR_REGENERATION) scope :waiting_for_regeneration, -> { where(status: WAITING_FOR_REGENERATION) }
accepts_nested_attributes_for :platform_arch_settings, allow_destroy: true accepts_nested_attributes_for :platform_arch_settings, allow_destroy: true
attr_accessible :name, :distrib_type, :parent_platform_id, :platform_type, :owner, :visibility, :description, :released, :platform_arch_settings_attributes, :automatic_metadata_regeneration attr_accessible :name, :distrib_type, :parent_platform_id, :platform_type, :owner, :visibility, :description, :released, :platform_arch_settings_attributes, :automatic_metadata_regeneration
attr_readonly :name, :distrib_type, :parent_platform_id, :platform_type attr_readonly :name, :distrib_type, :parent_platform_id, :platform_type
include Modules::Models::Owner
state_machine :status, initial: :ready do state_machine :status, initial: :ready do
after_transition on: :ready, do: :notify_users after_transition on: :ready, do: :notify_users
@ -79,7 +79,7 @@ class Platform < ActiveRecord::Base
end end
event :regenerate do event :regenerate do
transition ready: :waiting_for_regeneration, if: lambda{ |p| p.main? } transition ready: :waiting_for_regeneration, if: ->(p) { p.main? }
end end
event :start_regeneration do event :start_regeneration do
@ -223,13 +223,13 @@ class Platform < ActiveRecord::Base
end end
Rails.cache.fetch([platform_name, token, :platform_allowed], expires_in: 2.minutes) do Rails.cache.fetch([platform_name, token, :platform_allowed], expires_in: 2.minutes) do
platform = Platform.find_by_name platform_name platform = Platform.find_by name: platform_name
next false unless platform next false unless platform
next true unless platform.hidden? next true unless platform.hidden?
next false unless token next false unless token
next true if platform.tokens.by_active.where(authentication_token: token).exists? next true if platform.tokens.by_active.where(authentication_token: token).exists?
user = User.find_by_authentication_token token user = User.find_by authentication_token: token
current_ability = Ability.new(user) current_ability = Ability.new(user)
if user && current_ability.can?(:show, platform) if user && current_ability.can?(:show, platform)
true true

View File

@ -2,21 +2,19 @@ class PlatformArchSetting < ActiveRecord::Base
DEFAULT_TIME_LIVING = 43200 # seconds, 12 hours DEFAULT_TIME_LIVING = 43200 # seconds, 12 hours
MIN_TIME_LIVING = 600 # seconds, 10 minutes MIN_TIME_LIVING = 600 # seconds, 10 minutes
MAX_TIME_LIVING = 360000 # seconds, 100 hours, 4 day and 4 hours MAX_TIME_LIVING = 360000 # seconds, 100 hours, 4 day and 4 hours
include Modules::Models::TimeLiving include TimeLiving
belongs_to :arch belongs_to :arch
belongs_to :platform belongs_to :platform
validates :arch_id, :platform_id, presence: true validates :arch_id, :platform_id, presence: true
validates :platform_id, :uniqueness => {scope: :arch_id} validates :platform_id, uniqueness: { scope: :arch_id }
validate lambda { validate lambda {
errors.add(:platform, I18n.t('flash.platform_arch_settings.wrong_platform')) unless platform.main? errors.add(:platform, I18n.t('flash.platform_arch_settings.wrong_platform')) unless platform.main?
} }
scope :by_arch, ->(arch) { where(arch_id: arch) if arch.present? }
scope :by_arch, lambda {|arch| where(arch_id: arch) if arch.present?} scope :by_default, -> { where(default: true) }
scope :by_default, where(default: true)
attr_accessible :arch_id, :platform_id, :default attr_accessible :arch_id, :platform_id, :default
end end

View File

@ -1,15 +1,7 @@
class PlatformContent class PlatformContent
# ------------------
# *** ATTRIBUTES ***
# ------------------
attr_reader :path attr_reader :path
# ---------------
# *** METHODS ***
# ---------------
def initialize(platform, path) def initialize(platform, path)
@platform, @path = platform, path @platform, @path = platform, path
end end
@ -29,7 +21,7 @@ class PlatformContent
bfp_name = @path.match(/\/#{@platform.name}\/repository\/[\w]+\//) bfp_name = @path.match(/\/#{@platform.name}\/repository\/[\w]+\//)
return nil unless bfp_name return nil unless bfp_name
bfp_name = bfp_name[0].gsub(/\/#{@platform.name}\/repository\//, '').gsub('/', '') bfp_name = bfp_name[0].gsub(/\/#{@platform.name}\/repository\//, '').gsub('/', '')
build_for_platform = Platform.main.find_by_name bfp_name build_for_platform = Platform.main.find_by name: bfp_name
return nil unless build_for_platform return nil unless build_for_platform
end end
@ -61,10 +53,6 @@ class PlatformContent
"#{APP_CONFIG['downloads_url']}/#{@platform.name}#{suffix}" "#{APP_CONFIG['downloads_url']}/#{@platform.name}#{suffix}"
end end
# ---------------------
# *** CLASS METHODS ***
# ---------------------
def self.find_by_platform(platform, path, term) def self.find_by_platform(platform, path, term)
# Strip out the non-ascii character # Strip out the non-ascii character
term = (term || '').strip.gsub(/[\\\/]+/, '') term = (term || '').strip.gsub(/[\\\/]+/, '')

View File

@ -1,16 +1,17 @@
class Product < ActiveRecord::Base class Product < ActiveRecord::Base
include Modules::Models::TimeLiving include TimeLiving
include Modules::Models::Autostart include Autostart
include EventLoggable
belongs_to :platform belongs_to :platform
belongs_to :project belongs_to :project
has_many :product_build_lists, dependent: :destroy has_many :product_build_lists, dependent: :destroy
validates :name, presence: true, uniqueness: {scope: :platform_id} validates :name, presence: true, uniqueness: { scope: :platform_id }
validates :project_id, presence: true validates :project_id, presence: true
validates :main_script, :params, length: { maximum: 255 } validates :main_script, :params, length: { maximum: 255 }
scope :recent, order("#{table_name}.name ASC") scope :recent, -> { order(:name) }
attr_accessible :name, attr_accessible :name,
:description, :description,
@ -24,7 +25,7 @@ class Product < ActiveRecord::Base
def full_clone(attrs = {}) def full_clone(attrs = {})
dup.tap do |c| dup.tap do |c|
attrs.each {|k,v| c.send("#{k}=", v)} attrs.each {|k,v| c.send("#{k}=", v)}
c.time_living = c.time_living.to_i / 60 # see: Modules::Models::TimeLiving#convert_time_living c.time_living = c.time_living.to_i / 60 # see: TimeLiving#convert_time_living
c.platform_id = nil c.platform_id = nil
c.product_build_lists = [] c.product_build_lists = []
c.updated_at = nil; c.created_at = nil c.updated_at = nil; c.created_at = nil
@ -32,7 +33,7 @@ class Product < ActiveRecord::Base
end end
class << self class << self
Modules::Models::Autostart::HUMAN_AUTOSTART_STATUSES.each do |autostart_status, human_autostart_status| Autostart::HUMAN_AUTOSTART_STATUSES.each do |autostart_status, human_autostart_status|
define_method "autostart_iso_builds_#{human_autostart_status}" do define_method "autostart_iso_builds_#{human_autostart_status}" do
autostart_iso_builds autostart_status autostart_iso_builds autostart_status
end end

View File

@ -1,9 +1,11 @@
class ProductBuildList < ActiveRecord::Base class ProductBuildList < ActiveRecord::Base
include Modules::Models::CommitAndVersion include CommitAndVersion
include Modules::Models::TimeLiving include TimeLiving
include Modules::Models::FileStoreClean include FileStoreClean
include Modules::Models::UrlHelper include UrlHelper
include AbfWorker::ModelHelper include AbfWorker::ModelHelper
include EventLoggable
delegate :url_helpers, to: 'Rails.application.routes' delegate :url_helpers, to: 'Rails.application.routes'
LIVE_TIME = 2.week # for autostart LIVE_TIME = 2.week # for autostart
@ -38,9 +40,9 @@ class ProductBuildList < ActiveRecord::Base
belongs_to :user belongs_to :user
# see: Issue #6 # see: Issue #6
before_validation lambda { self.arch_id = Arch.find_by_name('x86_64').id }, on: :create before_validation -> { self.arch_id = Arch.find_by(name: 'x86_64').id }, on: :create
# field "not_delete" can be changed only if build has been completed # field "not_delete" can be changed only if build has been completed
before_validation lambda { self.not_delete = false unless build_completed?; true } before_validation -> { self.not_delete = false unless build_completed?; true }
validates :product_id, validates :product_id,
:status, :status,
:project_id, :project_id,
@ -64,13 +66,16 @@ class ProductBuildList < ActiveRecord::Base
serialize :results, Array serialize :results, Array
scope :default_order, order("#{table_name}.updated_at DESC") scope :default_order, -> { order(updated_at: :desc) }
scope :for_status, lambda {|status| where(status: status) } scope :for_status, ->(status) { where(status: status) }
scope :for_user, lambda { |user| where(user_id: user.id) } scope :for_user, ->(user) { where(user_id: user.id) }
scope :scoped_to_product_name, lambda {|product_name| joins(:product).where('products.name LIKE ?', "%#{product_name}%")} scope :scoped_to_product_name, ->(product_name) { joins(:product).where('products.name LIKE ?', "%#{product_name}%") }
scope :recent, order("#{table_name}.updated_at DESC") scope :recent, -> { order(updated_at: :desc) }
scope :outdated, where(not_delete: false). scope :outdated, -> {
where("(#{table_name}.created_at < ? AND #{table_name}.autostarted is TRUE) OR #{table_name}.created_at < ?", Time.now - LIVE_TIME, Time.now - MAX_LIVE_TIME) where(not_delete: false).
where("(#{table_name}.created_at < ? AND #{table_name}.autostarted is TRUE) OR #{table_name}.created_at < ?",
Time.now - LIVE_TIME, Time.now - MAX_LIVE_TIME)
}
after_create :add_job_to_abf_worker_queue after_create :add_job_to_abf_worker_queue
before_destroy :can_destroy? before_destroy :can_destroy?
@ -154,8 +159,7 @@ class ProductBuildList < ActiveRecord::Base
opts = default_url_options opts = default_url_options
opts.merge!({user: user.authentication_token, password: ''}) if user.present? opts.merge!({user: user.authentication_token, password: ''}) if user.present?
srcpath = url_helpers.archive_url( srcpath = url_helpers.archive_url(
project.owner, project.name_with_owner,
project.name,
file_name, file_name,
'tar.gz', 'tar.gz',
opts opts

View File

@ -1,12 +1,20 @@
class Project < ActiveRecord::Base class Project < ActiveRecord::Base
include Modules::Models::Autostart has_ancestry orphan_strategy: :adopt # we replace a 'path' method in the Git module
include Autostart
include Owner
include Git
include Wiki
include UrlHelper
include EventLoggable
VISIBILITIES = ['open', 'hidden'] VISIBILITIES = ['open', 'hidden']
MAX_OWN_PROJECTS = 32000 MAX_OWN_PROJECTS = 32000
NAME_REGEXP = /[\w\-\+\.]+/ NAME_REGEXP = /[\w\-\+\.]+/
OWNER_AND_NAME_REGEXP = /#{User::NAME_REGEXP.source}\/#{NAME_REGEXP.source}/
belongs_to :owner, polymorphic: true, counter_cache: :own_projects_count belongs_to :owner, polymorphic: true, counter_cache: :own_projects_count
belongs_to :maintainer, class_name: "User" belongs_to :maintainer, class_name: 'User'
has_many :issues, dependent: :destroy has_many :issues, dependent: :destroy
has_many :pull_requests, dependent: :destroy, foreign_key: 'to_project_id' has_many :pull_requests, dependent: :destroy, foreign_key: 'to_project_id'
@ -25,17 +33,17 @@ class Project < ActiveRecord::Base
has_many :collaborators, through: :relations, source: :actor, source_type: 'User' has_many :collaborators, through: :relations, source: :actor, source_type: 'User'
has_many :groups, through: :relations, source: :actor, source_type: 'Group' has_many :groups, through: :relations, source: :actor, source_type: 'Group'
has_many :packages, class_name: "BuildList::Package", dependent: :destroy has_many :packages, class_name: 'BuildList::Package', dependent: :destroy
has_and_belongs_to_many :advisories # should be without dependent: :destroy has_and_belongs_to_many :advisories # should be without dependent: :destroy
validates :name, uniqueness: {scope: [:owner_id, :owner_type], case_sensitive: false}, validates :name, uniqueness: { scope: [:owner_id, :owner_type], case_sensitive: false },
presence: true, presence: true,
format: {with: /\A#{NAME_REGEXP}\z/, format: { with: /\A#{NAME_REGEXP.source}\z/,
message: I18n.t("activerecord.errors.project.uname")} message: I18n.t("activerecord.errors.project.uname") }
validates :maintainer_id, presence: true, unless: :new_record? validates :maintainer_id, presence: true, unless: :new_record?
validates :url, presence: true, format: {with: /\Ahttps?:\/\/[\S]+\z/}, if: :mass_import validates :url, presence: true, format: { with: /\Ahttps?:\/\/[\S]+\z/ }, if: :mass_import
validates :add_to_repository_id, presence: true, if: :mass_import validates :add_to_repository_id, presence: true, if: :mass_import
validates :visibility, presence: true, inclusion: {in: VISIBILITIES} validates :visibility, presence: true, inclusion: { in: VISIBILITIES }
validate { errors.add(:base, :can_have_less_or_equal, count: MAX_OWN_PROJECTS) if owner.projects.size >= MAX_OWN_PROJECTS } validate { errors.add(:base, :can_have_less_or_equal, count: MAX_OWN_PROJECTS) if owner.projects.size >= MAX_OWN_PROJECTS }
validate :check_default_branch validate :check_default_branch
# throws validation error message from ProjectToRepository model into Project model # throws validation error message from ProjectToRepository model into Project model
@ -53,57 +61,50 @@ class Project < ActiveRecord::Base
:autostart_status :autostart_status
attr_readonly :owner_id, :owner_type attr_readonly :owner_id, :owner_type
scope :recent, order("lower(#{table_name}.name) ASC") scope :recent, -> { order(:name) }
scope :search_order, order("CHAR_LENGTH(#{table_name}.name) ASC") scope :search_order, -> { order('CHAR_LENGTH(projects.name) ASC') }
scope :search, lambda {|q| scope :search, ->(q) {
q = q.to_s.strip q = q.to_s.strip
by_name("%#{q}%").search_order if q.present? by_name("%#{q}%").search_order if q.present?
} }
scope :by_name, lambda {|name| where("#{table_name}.name ILIKE ?", name) if name.present?} scope :by_name, ->(name) { where('projects.name ILIKE ?', name) if name.present? }
scope :by_owner_and_name, lambda { |*params| scope :by_owner_and_name, ->(*params) {
term = params.map(&:strip).join('/').downcase term = params.map(&:strip).join('/').downcase
where("lower(concat(owner_uname, '/', name)) ILIKE ?", "%#{term}%") if term.present? where("lower(concat(owner_uname, '/', name)) ILIKE ?", "%#{term}%") if term.present?
} }
scope :by_visibilities, lambda {|v| where(visibility: v)} scope :by_visibilities, ->(v) { where(visibility: v) }
scope :opened, where(visibility: 'open') scope :opened, -> { where(visibility: 'open') }
scope :package, where(is_package: true) scope :package, -> { where(is_package: true) }
scope :addable_to_repository, lambda { |repository_id| where %Q( scope :addable_to_repository, ->(repository_id) {
projects.id NOT IN ( where('projects.id NOT IN (
SELECT SELECT ptr.project_id
ptr.project_id FROM project_to_repositories AS ptr
FROM WHERE ptr.repository_id = ?)', repository_id)
project_to_repositories AS ptr }
WHERE (ptr.repository_id = #{ repository_id }) scope :by_owners, ->(group_owner_ids, user_owner_ids) {
) where("(projects.owner_id in (?) AND projects.owner_type = 'Group') OR
) } (projects.owner_id in (?) AND projects.owner_type = 'User')", group_owner_ids, user_owner_ids)
scope :by_owners, lambda { |group_owner_ids, user_owner_ids|
where("(#{table_name}.owner_id in (?) AND #{table_name}.owner_type = 'Group') OR (#{table_name}.owner_id in (?) AND #{table_name}.owner_type = 'User')", group_owner_ids, user_owner_ids)
} }
before_validation :truncate_name, on: :create before_validation :truncate_name, on: :create
before_save lambda { self.owner_uname = owner.uname if owner_uname.blank? || owner_id_changed? || owner_type_changed? } before_save -> { self.owner_uname = owner.uname if owner_uname.blank? || owner_id_changed? || owner_type_changed? }
before_create :set_maintainer before_create :set_maintainer
after_save :attach_to_personal_repository after_save :attach_to_personal_repository
after_update :set_new_git_head after_update :set_new_git_head
after_update lambda { update_path_to_project(name_was) }, if: :name_changed? after_update -> { update_path_to_project(name_was) }, if: :name_changed?
has_ancestry orphan_strategy: :rootify #:adopt not available yet
attr_accessor :url, :srpms_list, :mass_import, :add_to_repository_id attr_accessor :url, :srpms_list, :mass_import, :add_to_repository_id
include Modules::Models::Owner
include Modules::Models::Git
include Modules::Models::Wiki
include Modules::Models::UrlHelper
class << self class << self
def find_by_owner_and_name(owner_name, project_name) def find_by_owner_and_name(first, last = nil)
where(owner_uname: owner_name, name: project_name).first || arr = first.try(:split, '/') || []
by_owner_and_name(owner_name, project_name).first arr = (arr << last).compact
return nil if arr.length != 2
where(owner_uname: arr.first, name: arr.last).first || by_owner_and_name(*arr).first
end end
def find_by_owner_and_name!(owner_name, project_name) def find_by_owner_and_name!(first, last = nil)
find_by_owner_and_name(owner_name, project_name) or raise ActiveRecord::RecordNotFound find_by_owner_and_name(first, last) or raise ActiveRecord::RecordNotFound
end end
end end
@ -116,15 +117,15 @@ class Project < ActiveRecord::Base
end end
def to_param def to_param
name name_with_owner
end end
def all_members def all_members(*includes)
members | (owner_type == 'User' ? [owner] : owner.members) members(includes) | (owner_type == 'User' ? [owner] : owner.members.includes(includes))
end end
def members def members(*includes)
collaborators | groups.map(&:members).flatten collaborators.includes(includes) | groups.map{ |g| g.members.includes(includes) }.flatten
end end
def add_member(member, role = 'admin') def add_member(member, role = 'admin')
@ -160,11 +161,11 @@ class Project < ActiveRecord::Base
def git_project_address auth_user def git_project_address auth_user
opts = default_url_options opts = default_url_options
opts.merge!({user: auth_user.authentication_token, password: ''}) unless self.public? opts.merge!({user: auth_user.authentication_token, password: ''}) unless self.public?
Rails.application.routes.url_helpers.project_url(self.owner.uname, self.name, opts) + '.git' Rails.application.routes.url_helpers.project_url(self.name_with_owner, opts) + '.git'
#path #share by NFS #path #share by NFS
end end
def build_for(mass_build, repository_id, arch = Arch.find_by_name('i586'), priority = 0, increase_rt = false) def build_for(mass_build, repository_id, arch = Arch.find_by(name: 'i586'), priority = 0, increase_rt = false)
build_for_platform = mass_build.build_for_platform build_for_platform = mass_build.build_for_platform
save_to_platform = mass_build.save_to_platform save_to_platform = mass_build.save_to_platform
user = mass_build.user user = mass_build.user
@ -239,12 +240,12 @@ class Project < ActiveRecord::Base
format_id = ProjectTag::FORMATS["#{tag_file_format(format)}"] format_id = ProjectTag::FORMATS["#{tag_file_format(format)}"]
project_tag = project_tags.where(tag_name: tag.name, format_id: format_id).first project_tag = project_tags.where(tag_name: tag.name, format_id: format_id).first
return project_tag.sha1 if project_tag && project_tag.commit_id == tag.commit.id && Modules::Models::FileStoreClean.file_exist_on_file_store?(project_tag.sha1) return project_tag.sha1 if project_tag && project_tag.commit_id == tag.commit.id && FileStoreClean.file_exist_on_file_store?(project_tag.sha1)
archive = archive_by_treeish_and_format tag.name, format archive = archive_by_treeish_and_format tag.name, format
sha1 = Digest::SHA1.file(archive[:path]).hexdigest sha1 = Digest::SHA1.file(archive[:path]).hexdigest
unless Modules::Models::FileStoreClean.file_exist_on_file_store? sha1 unless FileStoreClean.file_exist_on_file_store? sha1
token = User.find_by_uname('rosa_system').authentication_token token = User.find_by(uname: 'rosa_system').authentication_token
begin begin
resp = JSON `curl --user #{token}: -POST -F 'file_store[file]=@#{archive[:path]};filename=#{name}-#{tag.name}.#{tag_file_format(format)}' #{APP_CONFIG['file_store_url']}/api/v1/upload` resp = JSON `curl --user #{token}: -POST -F 'file_store[file]=@#{archive[:path]};filename=#{name}-#{tag.name}.#{tag_file_format(format)}' #{APP_CONFIG['file_store_url']}/api/v1/upload`
rescue # Dont care about it rescue # Dont care about it
@ -298,7 +299,7 @@ class Project < ActiveRecord::Base
end end
class << self class << self
Modules::Models::Autostart::HUMAN_AUTOSTART_STATUSES.each do |autostart_status, human_autostart_status| Autostart::HUMAN_AUTOSTART_STATUSES.each do |autostart_status, human_autostart_status|
define_method "autostart_build_lists_#{human_autostart_status}" do define_method "autostart_build_lists_#{human_autostart_status}" do
autostart_build_lists autostart_status autostart_build_lists autostart_status
end end

View File

@ -2,10 +2,10 @@ class ProjectImport < ActiveRecord::Base
belongs_to :project belongs_to :project
belongs_to :platform belongs_to :platform
validates :name, uniqueness: {scope: :platform_id, case_sensitive: false} validates :name, uniqueness: { scope: :platform_id, case_sensitive: false }
validates :name, :platform_id, :version, presence: true validates :name, :platform_id, :version, presence: true
scope :by_name, lambda {|name| where("#{table_name}.name ILIKE ?", name)} scope :by_name, ->(name) { where("#{table_name}.name ILIKE ?", name) }
after_initialize lambda {|r| r.file_mtime ||= Time.current - 10.years } # default after_initialize ->(r) { r.file_mtime ||= Time.current - 10.years } # default
end end

View File

@ -4,7 +4,7 @@ class ProjectStatistic < ActiveRecord::Base
belongs_to :project belongs_to :project
validates :arch_id, :project_id, :average_build_time, :build_count, presence: true validates :arch_id, :project_id, :average_build_time, :build_count, presence: true
validates :project_id, uniqueness: {scope: :arch_id} validates :project_id, uniqueness: { scope: :arch_id }
attr_accessible :average_build_time, :build_count attr_accessible :average_build_time, :build_count
end end

View File

@ -1,5 +1,5 @@
class ProjectTag < ActiveRecord::Base class ProjectTag < ActiveRecord::Base
include Modules::Models::FileStoreClean include FileStoreClean
FORMATS = { FORMATS = {
'zip' => 0, 'zip' => 0,
@ -9,16 +9,11 @@ class ProjectTag < ActiveRecord::Base
belongs_to :project belongs_to :project
validates :project_id, :commit_id, :sha1, :tag_name, :format_id, presence: true validates :project_id, :commit_id, :sha1, :tag_name, :format_id, presence: true
validates :project_id, uniqueness: {scope: [:tag_name, :format_id]} validates :project_id, uniqueness: { scope: [:tag_name, :format_id] }
attr_accessible :project_id, attr_accessible :project_id, :commit_id, :sha1, :tag_name, :format_id
:commit_id,
:sha1,
:tag_name,
:format_id
def sha1_of_file_store_files def sha1_of_file_store_files
[sha1] [sha1]
end end
end end

View File

@ -6,13 +6,14 @@ class ProjectToRepository < ActiveRecord::Base
delegate :path, to: :project delegate :path, to: :project
scope :autostart_enabled, lambda { where("autostart_options -> 'enabled' = 'true'") } scope :autostart_enabled, -> { where("autostart_options -> 'enabled' = 'true'") }
after_destroy lambda { project.destroy_project_from_repository(repository) }, unless: lambda {Thread.current[:skip]} after_destroy -> { project.destroy_project_from_repository(repository) }, unless: -> { Thread.current[:skip] }
validate :one_project_in_platform_repositories, on: :create validate :one_project_in_platform_repositories, on: :create
serialize :autostart_options, ActiveRecord::Coders::Hstore attr_accessible :project, :project_id
AUTOSTART_OPTIONS.each do |field| AUTOSTART_OPTIONS.each do |field|
store_accessor :autostart_options, field store_accessor :autostart_options, field
end end
@ -28,7 +29,8 @@ class ProjectToRepository < ActiveRecord::Base
protected protected
def one_project_in_platform_repositories def one_project_in_platform_repositories
errors.add(:base, I18n.t('activerecord.errors.project_to_repository.project')) if Project.joins(repositories: :platform). if Project.joins(repositories: :platform).where('platforms.id = ?', repository.platform_id).by_name(project.name).exists?
where('platforms.id = ?', repository.platform_id).by_name(project.name).exists? errors.add(:base, I18n.t('activerecord.errors.project_to_repository.project'))
end
end end
end end

View File

@ -7,7 +7,7 @@ class PullRequest < ActiveRecord::Base
:created_at, :updated_at, :comments, :status=, to: :issue, allow_nil: true :created_at, :updated_at, :comments, :status=, to: :issue, allow_nil: true
validates :from_project, :to_project, presence: true validates :from_project, :to_project, presence: true
validate :uniq_merge, if: Proc.new { |pull| pull.to_project.present? } validate :uniq_merge, if: ->(pull) { pull.to_project.present? }
validates_each :from_ref, :to_ref do |record, attr, value| validates_each :from_ref, :to_ref do |record, attr, value|
check_ref record, attr, value check_ref record, attr, value
end end
@ -19,9 +19,9 @@ class PullRequest < ActiveRecord::Base
accepts_nested_attributes_for :issue accepts_nested_attributes_for :issue
attr_accessible :issue_attributes, :to_ref, :from_ref attr_accessible :issue_attributes, :to_ref, :from_ref
scope :needed_checking, includes(:issue).where(issues: {status: ['open', 'blocked', 'ready']}) scope :needed_checking, -> { includes(:issue).where(issues: {status: ['open', 'blocked', 'ready']}) }
scope :not_closed_or_merged, needed_checking scope :not_closed_or_merged, -> { needed_checking }
scope :closed_or_merged, where(issues: {status: ['closed', 'merged']}) scope :closed_or_merged, -> { where(issues: {status: ['closed', 'merged']}) }
state_machine :status, initial: :open do state_machine :status, initial: :open do
event :ready do event :ready do

View File

@ -1,12 +1,13 @@
class RegisterRequest < ActiveRecord::Base class RegisterRequest < ActiveRecord::Base
default_scope order('created_at ASC') default_scope { order(:created_at) }
scope :rejected, where(rejected: true) scope :rejected, -> { where(rejected: true) }
scope :approved, where(approved: true) scope :approved, -> { where(approved: true) }
scope :unprocessed, where(approved: false, rejected: false) scope :unprocessed, -> { where(approved: false, rejected: false) }
validates :email, presence: true, uniqueness: {case_sensitive: false}, format: { with: /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i } validates :email, presence: true, uniqueness: {case_sensitive: false},
format: { with: /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i }
# before_create :generate_token # before_create :generate_token
before_update :invite_approve_notification before_update :invite_approve_notification

View File

@ -1,17 +1,22 @@
class Relation < ActiveRecord::Base class Relation < ActiveRecord::Base
ROLES = %w[reader writer admin]
belongs_to :target, polymorphic: true belongs_to :target, polymorphic: true
belongs_to :actor, polymorphic: true, touch: true belongs_to :actor, polymorphic: true, touch: true
ROLES = %w[reader writer admin] validates :role, inclusion: { in: ROLES }
validates :role, inclusion: {in: ROLES}
# validate { errors.add(:actor, :taken) if Relation.where(actor_type: self.actor_type, actor_id: self.actor_id).present? } # validate { errors.add(:actor, :taken) if Relation.where(actor_type: self.actor_type, actor_id: self.actor_id).present? }
before_validation :add_default_role before_validation :add_default_role
scope :by_user_through_groups, lambda {|u| where("actor_type = 'User' AND actor_id = ? OR actor_type = 'Group' AND actor_id IN (?)", u.id, u.group_ids)} attr_accessible :actor_id, :actor_type, :target_id, :target_type, :actor, :target, :role
scope :by_actor, lambda {|obj| where(actor_id: obj.id, actor_type: obj.class.to_s)}
scope :by_target, lambda {|tar| where(target_id: tar.id, target_type: tar.class.to_s)} scope :by_user_through_groups, ->(u) {
scope :by_role, lambda {|role| where(role: role)} where("actor_type = 'User' AND actor_id = ? OR actor_type = 'Group' AND actor_id IN (?)", u.id, u.group_ids)
}
scope :by_actor, ->(obj) { where(actor_id: obj.id, actor_type: obj.class.to_s) }
scope :by_target, ->(tar) { where(target_id: tar.id, target_type: tar.class.to_s) }
scope :by_role, ->(role) { where(role: role) }
def self.create_with_role(actor, target, role) def self.create_with_role(actor, target, role)
r = self.new r = self.new

View File

@ -1,9 +1,11 @@
class Repository < ActiveRecord::Base class Repository < ActiveRecord::Base
extend FriendlyId extend FriendlyId
friendly_id :name friendly_id :name, use: [:finders]
LOCK_FILE_NAMES = {sync: '.sync.lock', repo: '.repo.lock'} include EventLoggable
SORT = {'base' => 1, 'main' => 2, 'contrib' => 3, 'non-free' => 4, 'restricted' => 5}
LOCK_FILE_NAMES = { sync: '.sync.lock', repo: '.repo.lock' }
SORT = { 'base' => 1, 'main' => 2, 'contrib' => 3, 'non-free' => 4, 'restricted' => 5 }
belongs_to :platform belongs_to :platform
@ -19,10 +21,11 @@ class Repository < ActiveRecord::Base
has_many :build_lists, foreign_key: :save_to_repository_id, dependent: :destroy has_many :build_lists, foreign_key: :save_to_repository_id, dependent: :destroy
validates :description, presence: true validates :description, presence: true
validates :name, uniqueness: {scope: :platform_id, case_sensitive: false}, presence: true, format: {with: /\A[a-z0-9_\-]+\z/} validates :name, uniqueness: { scope: :platform_id, case_sensitive: false }, presence: true,
format: { with: /\A[a-z0-9_\-]+\z/ }
scope :recent, order("#{table_name}.name ASC") scope :recent, -> { order(:name) }
scope :main, lambda { where(name: %w(main base)) } scope :main, -> { where(name: %w(main base)) }
before_destroy :detele_directory before_destroy :detele_directory
@ -32,13 +35,13 @@ class Repository < ActiveRecord::Base
def regenerate(build_for_platform_id = nil) def regenerate(build_for_platform_id = nil)
build_for_platform = Platform.main.find build_for_platform_id if platform.personal? build_for_platform = Platform.main.find build_for_platform_id if platform.personal?
status = repository_statuses.find_or_create_by_platform_id(build_for_platform.try(:id) || platform_id) status = repository_statuses.find_or_create_by(platform_id: build_for_platform.try(:id) || platform_id)
status.regenerate status.regenerate
end end
def resign def resign
if platform.main? if platform.main?
status = repository_statuses.find_or_create_by_platform_id(platform_id) status = repository_statuses.find_or_create_by(platform_id: platform_id)
status.resign status.resign
end end
end end
@ -79,7 +82,7 @@ class Repository < ActiveRecord::Base
begin begin
name.chomp!; name.strip! name.chomp!; name.strip!
next if name.blank? next if name.blank?
project_to_repositories.where(projects: { name: name }).joins(:project).destroy_all project_to_repositories.where(projects: { name: name }).joins(:project).readonly(false).destroy_all
rescue RuntimeError, Exception rescue RuntimeError, Exception
end end
end end

View File

@ -1,6 +1,6 @@
class RepositoryStatus < ActiveRecord::Base class RepositoryStatus < ActiveRecord::Base
include Modules::Models::FileStoreClean include FileStoreClean
include Modules::Models::RegenerationStatus include RegenerationStatus
WAITING_FOR_RESIGN = 300 WAITING_FOR_RESIGN = 300
PUBLISH = 400 PUBLISH = 400
@ -29,14 +29,14 @@ class RepositoryStatus < ActiveRecord::Base
belongs_to :repository belongs_to :repository
validates :repository_id, :platform_id, presence: true validates :repository_id, :platform_id, presence: true
validates :repository_id, uniqueness: {scope: :platform_id} validates :repository_id, uniqueness: { scope: :platform_id }
attr_accessible :platform_id, :repository_id attr_accessible :platform_id, :repository_id
scope :platform_ready, where(platforms: {status: READY}).joins(:platform) scope :platform_ready, -> { where(platforms: {status: READY}).joins(:platform) }
scope :for_regeneration, where(status: WAITING_FOR_REGENERATION) scope :for_regeneration, -> { where(status: WAITING_FOR_REGENERATION) }
scope :for_resign, where(status: [WAITING_FOR_RESIGN, WAITING_FOR_RESIGN_AND_REGENERATION]) scope :for_resign, -> { where(status: [WAITING_FOR_RESIGN, WAITING_FOR_RESIGN_AND_REGENERATION]) }
scope :not_ready, where('repository_statuses.status != ?', READY) scope :not_ready, -> { where('repository_statuses.status != ?', READY) }
state_machine :status, initial: :ready do state_machine :status, initial: :ready do
event :ready do event :ready do
@ -80,5 +80,4 @@ class RepositoryStatus < ActiveRecord::Base
state name, value: code state name, value: code
end end
end end
end end

View File

@ -29,5 +29,4 @@ class RpmBuildNode < Ohm::Model
end end
{ systems: systems, others: others, busy: busy } { systems: systems, others: others, busy: busy }
end end
end end

View File

@ -2,4 +2,17 @@ class SettingsNotifier < ActiveRecord::Base
belongs_to :user belongs_to :user
validates :user_id, presence: true validates :user_id, presence: true
attr_accessible :can_notify,
:update_code,
:new_comment_commit_owner,
:new_comment_commit_repo_owner,
:new_comment_commit_commentor,
:new_comment,
:new_comment_reply,
:new_issue,
:issue_assign,
:new_build,
:new_associated_build
end end

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