Merge pull request #365 from abf/rosa-build:345-update_to_rails4
#345: Update to rails 4
This commit is contained in:
commit
93dd8dc48e
|
@ -1,6 +1,6 @@
|
|||
language: ruby
|
||||
rvm:
|
||||
- 2.1.0
|
||||
- 2.1.1
|
||||
bundler_args: --without development
|
||||
env:
|
||||
- SPEC_GROUP=controllers
|
||||
|
@ -18,7 +18,7 @@ before_install:
|
|||
before_script:
|
||||
- cp config/database.yml.sample config/database.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"
|
||||
branches:
|
||||
only:
|
||||
|
|
107
Gemfile
107
Gemfile
|
@ -1,71 +1,69 @@
|
|||
source 'https://rubygems.org'
|
||||
|
||||
gem 'rails', '3.2.17'
|
||||
gem 'redhillonrails_core', git: 'git://github.com/rosa-abf/redhillonrails_core.git', branch: 'rails31' # '~> 2.0.0.pre' # deprecated
|
||||
gem 'rails', '4.0.4'
|
||||
|
||||
gem 'pg', '~> 0.14.0'
|
||||
gem 'activerecord-postgres-hstore'
|
||||
|
||||
gem 'devise', '~> 2.2.3'
|
||||
gem 'pg', '~> 0.17.1'
|
||||
gem 'schema_plus', '~> 1.4.0'
|
||||
########
|
||||
gem 'protected_attributes'
|
||||
########
|
||||
gem 'devise', '~> 3.2.3'
|
||||
gem 'omniauth'
|
||||
gem 'omniauth-facebook'
|
||||
gem 'omniauth-google-oauth2'
|
||||
gem 'omniauth-github'
|
||||
# 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 'paperclip', '~> 4.1.0'
|
||||
gem 'resque', '~> 1.24'
|
||||
gem 'resque-status', '~> 0.3.3'
|
||||
gem 'ancestry', '~> 2.0.0'
|
||||
gem 'paperclip', '~> 4.1.1'
|
||||
gem 'resque', '~> 1.25'
|
||||
gem 'resque-status', '~> 0.4.2'
|
||||
gem 'resque_mailer', '~> 2.2'
|
||||
gem 'resque-scheduler'
|
||||
# gem 'perform_later', '~> 1.3.0' # should be after resque_mailer
|
||||
gem 'resque-scheduler', '~> 2.5.4'
|
||||
gem 'perform_later', git: 'git://github.com/KensoDev/perform_later.git' # should be after resque_mailer
|
||||
gem 'russian', '~> 0.6.0'
|
||||
gem 'highline', '~> 1.6.11'
|
||||
gem 'state_machine'
|
||||
gem 'redis-rails'
|
||||
gem 'highline', '~> 1.6.20'
|
||||
gem 'state_machine', '~> 1.2'
|
||||
gem 'redis-rails', '~> 4.0'
|
||||
|
||||
gem 'grack', git: 'git://github.com/rosa-abf/grack.git', require: 'git_http'
|
||||
gem 'grit', git: 'git://github.com/rosa-abf/grit.git'
|
||||
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'
|
||||
|
||||
# Wiki
|
||||
gem "gollum", '~> 2.1.3'
|
||||
gem "redcarpet", '~> 2.2.2'
|
||||
gem "gollum-lib", '~> 2.0'
|
||||
gem "redcarpet", '~> 3.1.1'
|
||||
gem 'creole'
|
||||
gem 'rdiscount'
|
||||
# gem 'org-ruby'
|
||||
gem 'RedCloth'
|
||||
gem 'wikicloth'
|
||||
|
||||
# gem 'unicorn', '~> 4.3.1', platforms: [:mri, :rbx]
|
||||
gem 'trinidad', '~> 1.0.2', platforms: :jruby
|
||||
|
||||
gem 'newrelic_rpm'
|
||||
# gem 'whenever', '~> 0.7.3', require: false
|
||||
gem 'whenever', '~> 0.9.0', require: false
|
||||
|
||||
gem 'jbuilder', '~> 1.4.2'
|
||||
gem 'rails3-jquery-autocomplete', '~> 1.0.7'
|
||||
gem 'will_paginate', '~> 3.0.3'
|
||||
gem 'meta-tags', '~> 1.2.5', require: 'meta_tags'
|
||||
gem "haml-rails", '~> 0.3.4'
|
||||
gem 'jquery-rails', '~> 2.0.2'
|
||||
gem 'ruby-haml-js', '~> 0.0.3'
|
||||
gem 'friendly_id'
|
||||
gem 'jbuilder', '~> 2.0.3'
|
||||
gem 'rails3-jquery-autocomplete', '~> 1.0'
|
||||
gem 'will_paginate', '~> 3.0.5'
|
||||
gem 'meta-tags', '~> 1.5', require: 'meta_tags'
|
||||
gem "haml-rails", '~> 0.5'
|
||||
gem 'jquery-rails', '~> 2.3.0'
|
||||
gem 'jquery-migrate-rails'
|
||||
gem 'ruby-haml-js', '~> 0.0.5'
|
||||
gem 'friendly_id', '~> 5.0.3'
|
||||
|
||||
gem 'rack-throttle'
|
||||
gem 'rest-client', '~> 1.6.6'
|
||||
gem 'ohm'
|
||||
gem 'ohm-expire'
|
||||
gem 'rack-throttle', '~> 0.3.0'
|
||||
gem 'rest-client', '~> 1.6.7'
|
||||
gem 'ohm', '~> 1.3.2'
|
||||
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'
|
||||
|
||||
# AngularJS related stuff
|
||||
|
@ -79,15 +77,13 @@ gem 'soundmanager-rails'
|
|||
|
||||
gem 'time_diff'
|
||||
|
||||
group :assets do
|
||||
gem 'sass-rails', '~> 3.2.5'
|
||||
gem 'coffee-rails', '~> 3.2.2'
|
||||
gem 'compass-rails', '~> 1.0.3'
|
||||
gem 'uglifier', '~> 1.2.4'
|
||||
gem 'therubyracer', '~> 0.12.1', platforms: [:mri, :rbx]
|
||||
gem 'therubyrhino', '~> 1.73.1', platforms: :jruby
|
||||
gem 'turbo-sprockets-rails3'
|
||||
end
|
||||
gem 'sass-rails', '~> 4.0.1'
|
||||
gem 'coffee-rails', '~> 4.0.1'
|
||||
gem 'compass-rails', '~> 1.1.6'
|
||||
gem 'uglifier', '~> 2.4'
|
||||
gem 'therubyracer', '~> 0.12.1', platforms: [:mri, :rbx]
|
||||
gem 'therubyrhino', '~> 1.73.1', platforms: :jruby
|
||||
|
||||
|
||||
group :production do
|
||||
gem "airbrake", '~> 3.1.2'
|
||||
|
@ -116,11 +112,16 @@ group :development do
|
|||
#gem 'ruby-dbus' if RUBY_PLATFORM =~ /linux/i # Error at deploy
|
||||
end
|
||||
|
||||
group :test do
|
||||
gem 'rspec-rails', '~> 2.11.0', group: 'development'
|
||||
gem 'factory_girl_rails', '~> 4.0.0'
|
||||
gem 'rr', '~> 1.0.4'
|
||||
gem 'shoulda'
|
||||
gem 'mock_redis', '0.6.2'
|
||||
gem 'rake'
|
||||
group :development, :test do
|
||||
gem 'rspec-rails', '~> 2.14.1'
|
||||
end
|
||||
|
||||
group :test do
|
||||
gem 'factory_girl_rails', '~> 4.4.1'
|
||||
gem 'rr', '~> 1.1.2'
|
||||
gem 'shoulda'
|
||||
gem 'shoulda-matchers'
|
||||
gem 'mock_redis', '~> 0.11'
|
||||
gem 'rake'
|
||||
gem 'test_after_commit'
|
||||
end
|
||||
|
|
510
Gemfile.lock
510
Gemfile.lock
|
@ -8,6 +8,13 @@ GIT
|
|||
resque (> 1.25)
|
||||
resque-scheduler
|
||||
|
||||
GIT
|
||||
remote: git://github.com/rosa-abf/cancan.git
|
||||
revision: fe1089b70c08d3ed11bac4f8e69ecb3d1d9adc29
|
||||
tag: 1.6.10-abf
|
||||
specs:
|
||||
cancan (1.6.10)
|
||||
|
||||
GIT
|
||||
remote: git://github.com/rosa-abf/grack.git
|
||||
revision: 020be3fef3fb308b9d214252522aa5945bf6584a
|
||||
|
@ -23,74 +30,60 @@ GIT
|
|||
mime-types (~> 1.15)
|
||||
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
|
||||
remote: https://rubygems.org/
|
||||
specs:
|
||||
RedCloth (4.2.9)
|
||||
actionmailer (3.2.17)
|
||||
actionpack (= 3.2.17)
|
||||
actionmailer (4.0.4)
|
||||
actionpack (= 4.0.4)
|
||||
mail (~> 2.5.4)
|
||||
actionpack (3.2.17)
|
||||
activemodel (= 3.2.17)
|
||||
activesupport (= 3.2.17)
|
||||
builder (~> 3.0.0)
|
||||
actionpack (4.0.4)
|
||||
activesupport (= 4.0.4)
|
||||
builder (~> 3.1.0)
|
||||
erubis (~> 2.7.0)
|
||||
journey (~> 1.0.4)
|
||||
rack (~> 1.4.5)
|
||||
rack-cache (~> 1.2)
|
||||
rack-test (~> 0.6.1)
|
||||
sprockets (~> 2.2.1)
|
||||
activemodel (3.2.17)
|
||||
activesupport (= 3.2.17)
|
||||
builder (~> 3.0.0)
|
||||
activerecord (3.2.17)
|
||||
activemodel (= 3.2.17)
|
||||
activesupport (= 3.2.17)
|
||||
arel (~> 3.0.2)
|
||||
tzinfo (~> 0.3.29)
|
||||
activerecord-postgres-hstore (0.7.7)
|
||||
activerecord (>= 3.1)
|
||||
pg-hstore (>= 1.1.5)
|
||||
rake
|
||||
activeresource (3.2.17)
|
||||
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)
|
||||
rack (~> 1.5.2)
|
||||
rack-test (~> 0.6.2)
|
||||
activemodel (4.0.4)
|
||||
activesupport (= 4.0.4)
|
||||
builder (~> 3.1.0)
|
||||
activerecord (4.0.4)
|
||||
activemodel (= 4.0.4)
|
||||
activerecord-deprecated_finders (~> 1.0.2)
|
||||
activesupport (= 4.0.4)
|
||||
arel (~> 4.0.0)
|
||||
activerecord-deprecated_finders (1.0.3)
|
||||
activesupport (4.0.4)
|
||||
i18n (~> 0.6, >= 0.6.9)
|
||||
minitest (~> 4.2)
|
||||
multi_json (~> 1.3)
|
||||
thread_safe (~> 0.1)
|
||||
tzinfo (~> 0.3.37)
|
||||
airbrake (3.1.16)
|
||||
builder
|
||||
multi_json
|
||||
ancestry (1.3.0)
|
||||
activerecord (>= 2.3.14)
|
||||
ancestry (2.0.0)
|
||||
activerecord (>= 3.0.0)
|
||||
angular-i18n (0.1.2)
|
||||
angularjs-rails (1.2.7)
|
||||
arel (3.0.3)
|
||||
attr_encrypted (1.2.1)
|
||||
encryptor (>= 1.1.1)
|
||||
bcrypt-ruby (3.1.2)
|
||||
angularjs-rails (1.2.14)
|
||||
arel (4.0.2)
|
||||
atomic (1.1.16)
|
||||
attr_encrypted (1.3.2)
|
||||
encryptor (>= 1.3.0)
|
||||
bcrypt (3.1.7)
|
||||
bcrypt-ruby (3.1.5)
|
||||
bcrypt (>= 3.1.3)
|
||||
better_errors (1.1.0)
|
||||
coderay (>= 1.0.0)
|
||||
erubis (>= 2.6.6)
|
||||
binding_of_caller (0.7.2)
|
||||
debug_inspector (>= 0.0.1)
|
||||
blankslate (3.1.2)
|
||||
bluepill (0.0.66)
|
||||
activesupport (>= 3.0.0, < 4.0.0)
|
||||
bluepill (0.0.64)
|
||||
activesupport (>= 3.0.0)
|
||||
daemons (~> 1.1.4)
|
||||
i18n (>= 0.5.0)
|
||||
state_machine (~> 1.1)
|
||||
builder (3.0.4)
|
||||
builder (3.1.4)
|
||||
callsite (0.0.11)
|
||||
cancan (1.6.7)
|
||||
cape (1.8.0)
|
||||
capistrano (2.15.5)
|
||||
highline
|
||||
|
@ -101,99 +94,100 @@ GEM
|
|||
capistrano_colors (0.5.5)
|
||||
charlock_holmes (0.6.9.4)
|
||||
chronic (0.10.2)
|
||||
chunky_png (1.2.9)
|
||||
chunky_png (1.3.0)
|
||||
climate_control (0.0.3)
|
||||
activesupport (>= 3.0)
|
||||
cocaine (0.5.3)
|
||||
climate_control (>= 0.0.3, < 1.0)
|
||||
coderay (1.1.0)
|
||||
coffee-rails (3.2.2)
|
||||
coffee-rails (4.0.1)
|
||||
coffee-script (>= 2.2.0)
|
||||
railties (~> 3.2.0)
|
||||
railties (>= 4.0.0, < 5.0)
|
||||
coffee-script (2.2.0)
|
||||
coffee-script-source
|
||||
execjs
|
||||
coffee-script-source (1.6.3)
|
||||
compass (0.12.2)
|
||||
coffee-script-source (1.7.0)
|
||||
compass (0.12.3)
|
||||
chunky_png (~> 1.2)
|
||||
fssm (>= 0.2.7)
|
||||
sass (~> 3.1)
|
||||
compass-rails (1.0.3)
|
||||
compass (>= 0.12.2, < 0.14)
|
||||
sass (= 3.2.14)
|
||||
compass-rails (1.1.6)
|
||||
compass (>= 0.12.2)
|
||||
creole (0.5.0)
|
||||
daemons (1.1.9)
|
||||
debug_inspector (0.0.2)
|
||||
devise (2.2.8)
|
||||
devise (3.2.3)
|
||||
bcrypt-ruby (~> 3.0)
|
||||
orm_adapter (~> 0.1)
|
||||
railties (~> 3.1)
|
||||
warden (~> 1.2.1)
|
||||
railties (>= 3.2.6, < 5)
|
||||
thread_safe (~> 0.1)
|
||||
warden (~> 1.2.3)
|
||||
diff-display (0.0.1)
|
||||
diff-lcs (1.1.3)
|
||||
diff-lcs (1.2.5)
|
||||
encryptor (1.3.0)
|
||||
erubis (2.7.0)
|
||||
escape_utils (0.2.4)
|
||||
escape_utils (1.0.1)
|
||||
eventmachine (1.0.3)
|
||||
execjs (2.0.2)
|
||||
expression_parser (0.9.0)
|
||||
factory_girl (4.0.0)
|
||||
factory_girl (4.4.0)
|
||||
activesupport (>= 3.0.0)
|
||||
factory_girl_rails (4.0.0)
|
||||
factory_girl (~> 4.0.0)
|
||||
factory_girl_rails (4.4.1)
|
||||
factory_girl (~> 4.4.0)
|
||||
railties (>= 3.0.0)
|
||||
faraday (0.8.9)
|
||||
multipart-post (~> 1.2.0)
|
||||
ffi (1.0.11)
|
||||
friendly_id (4.0.10.1)
|
||||
activerecord (>= 3.0, < 4.0)
|
||||
faraday (0.9.0)
|
||||
multipart-post (>= 1.2, < 3)
|
||||
ffi (1.9.3)
|
||||
friendly_id (5.0.3)
|
||||
activerecord (>= 4.0.0)
|
||||
fssm (0.2.10)
|
||||
gemoji (1.2.1)
|
||||
github-linguist (2.3.4)
|
||||
github-linguist (2.10.9)
|
||||
charlock_holmes (~> 0.6.6)
|
||||
escape_utils (~> 0.2.3)
|
||||
escape_utils (>= 0.3.1)
|
||||
mime-types (~> 1.19)
|
||||
pygments.rb (>= 0.2.13)
|
||||
github-markdown (0.6.3)
|
||||
pygments.rb (~> 0.5.4)
|
||||
github-markup (0.7.5)
|
||||
gli (2.8.1)
|
||||
gollum (2.1.10)
|
||||
github-markdown
|
||||
github-markup (>= 0.7.0, < 1.0.0)
|
||||
grit (~> 2.5.0)
|
||||
mustache (>= 0.11.2, < 1.0.0)
|
||||
nokogiri (~> 1.4)
|
||||
posix-spawn (~> 0.3.0)
|
||||
pygments.rb (~> 0.2.0)
|
||||
sanitize (~> 2.0.0)
|
||||
sinatra (~> 1.0)
|
||||
stringex (~> 1.4.0)
|
||||
useragent (~> 0.4.9)
|
||||
haml (3.1.8)
|
||||
haml-rails (0.3.5)
|
||||
actionpack (>= 3.1, < 4.1)
|
||||
activesupport (>= 3.1, < 4.1)
|
||||
haml (~> 3.1)
|
||||
railties (>= 3.1, < 4.1)
|
||||
gitlab-grit (2.6.0)
|
||||
charlock_holmes (~> 0.6.9)
|
||||
diff-lcs (~> 1.1)
|
||||
mime-types (~> 1.15)
|
||||
posix-spawn (~> 0.3.6)
|
||||
gli (2.9.0)
|
||||
gollum-lib (2.0.0)
|
||||
github-markup (>= 0.7.5, < 1.0.0)
|
||||
gitlab-grit (= 2.6.0)
|
||||
nokogiri (~> 1.6.0)
|
||||
rouge (~> 1.3.1)
|
||||
sanitize (~> 2.0.6)
|
||||
stringex (~> 2.1.0)
|
||||
haml (4.0.5)
|
||||
tilt
|
||||
haml-rails (0.5.3)
|
||||
actionpack (>= 4.0.1)
|
||||
activesupport (>= 4.0.1)
|
||||
haml (>= 3.1, < 5.0)
|
||||
railties (>= 4.0.1)
|
||||
hashie (2.0.5)
|
||||
highline (1.6.20)
|
||||
highline (1.6.21)
|
||||
hike (1.2.3)
|
||||
hirb (0.7.1)
|
||||
httpauth (0.2.0)
|
||||
i18n (0.6.9)
|
||||
jbuilder (1.4.2)
|
||||
jbuilder (2.0.4)
|
||||
activesupport (>= 3.0.0)
|
||||
multi_json (>= 1.2.0)
|
||||
journey (1.0.4)
|
||||
jquery-rails (2.0.3)
|
||||
railties (>= 3.1.0, < 5.0)
|
||||
thor (~> 0.14)
|
||||
js-routes (0.9.6)
|
||||
rails (>= 3.2)
|
||||
jquery-migrate-rails (1.2.1)
|
||||
jquery-rails (2.3.0)
|
||||
railties (>= 3.0, < 5.0)
|
||||
thor (>= 0.14, < 2.0)
|
||||
js-routes (0.9.7)
|
||||
railties (>= 3.2)
|
||||
sprockets-rails
|
||||
json (1.8.1)
|
||||
jwt (0.1.10)
|
||||
jwt (0.1.11)
|
||||
multi_json (>= 1.5)
|
||||
libv8 (3.16.14.3)
|
||||
localeapp (0.6.14)
|
||||
localeapp (0.7.1)
|
||||
gli
|
||||
i18n
|
||||
json
|
||||
|
@ -201,21 +195,20 @@ GEM
|
|||
rest-client
|
||||
ya2yaml
|
||||
logglier (0.2.11)
|
||||
macaddr (1.6.1)
|
||||
systemu (~> 2.5.0)
|
||||
mail (2.5.4)
|
||||
mime-types (~> 1.16)
|
||||
treetop (~> 1.4.8)
|
||||
mailcatcher (0.5.12)
|
||||
activesupport (~> 3.0)
|
||||
eventmachine (~> 1.0.0)
|
||||
haml (>= 3.1, < 5)
|
||||
mail (~> 2.3)
|
||||
sinatra (~> 1.2)
|
||||
skinny (~> 0.2.3)
|
||||
sqlite3 (~> 1.3)
|
||||
thin (~> 1.5.0)
|
||||
meta-tags (1.2.6)
|
||||
mailcatcher (0.2.4)
|
||||
eventmachine
|
||||
haml
|
||||
i18n
|
||||
json
|
||||
mail
|
||||
sinatra
|
||||
skinny (>= 0.1.2)
|
||||
sqlite3-ruby
|
||||
thin
|
||||
meta-tags (1.5.0)
|
||||
actionpack
|
||||
meta_request (0.2.8)
|
||||
callsite
|
||||
|
@ -223,31 +216,32 @@ GEM
|
|||
railties
|
||||
mime-types (1.25.1)
|
||||
mini_portile (0.5.2)
|
||||
mock_redis (0.6.2)
|
||||
momentjs-rails (2.5.0)
|
||||
minitest (4.7.5)
|
||||
mock_redis (0.11.0)
|
||||
momentjs-rails (2.5.1)
|
||||
railties (>= 3.1)
|
||||
mono_logger (1.1.0)
|
||||
multi_json (1.8.4)
|
||||
multipart-post (1.2.0)
|
||||
mustache (0.99.5)
|
||||
multi_json (1.9.0)
|
||||
multi_xml (0.5.5)
|
||||
multipart-post (2.0.0)
|
||||
nest (1.1.2)
|
||||
redis
|
||||
net-scp (1.1.2)
|
||||
net-ssh (>= 2.6.5)
|
||||
net-sftp (2.1.2)
|
||||
net-ssh (>= 2.6.5)
|
||||
net-ssh (2.7.0)
|
||||
net-ssh (2.8.0)
|
||||
net-ssh-gateway (1.2.0)
|
||||
net-ssh (>= 2.6.5)
|
||||
newrelic_rpm (3.7.1.182)
|
||||
newrelic_rpm (3.7.3.204)
|
||||
ng-rails-csrf (0.1.0)
|
||||
nokogiri (1.6.1)
|
||||
mini_portile (~> 0.5.0)
|
||||
oauth2 (0.8.1)
|
||||
faraday (~> 0.8)
|
||||
httpauth (~> 0.1)
|
||||
jwt (~> 0.1.4)
|
||||
multi_json (~> 1.0)
|
||||
oauth2 (0.9.3)
|
||||
faraday (>= 0.8, < 0.10)
|
||||
jwt (~> 0.1.8)
|
||||
multi_json (~> 1.3)
|
||||
multi_xml (~> 0.5)
|
||||
rack (~> 1.2)
|
||||
ohm (1.3.2)
|
||||
nest (~> 1.0)
|
||||
|
@ -255,9 +249,9 @@ GEM
|
|||
scrivener (~> 0.0.3)
|
||||
ohm-expire (0.1.3.2)
|
||||
ohm (>= 0.1.5)
|
||||
omniauth (1.1.4)
|
||||
omniauth (1.2.1)
|
||||
hashie (>= 1.2, < 3)
|
||||
rack
|
||||
rack (~> 1.0)
|
||||
omniauth-facebook (1.6.0)
|
||||
omniauth-oauth2 (~> 1.1)
|
||||
omniauth-github (1.1.1)
|
||||
|
@ -266,122 +260,111 @@ GEM
|
|||
omniauth-google-oauth2 (0.2.2)
|
||||
omniauth (~> 1.0)
|
||||
omniauth-oauth2
|
||||
omniauth-oauth2 (1.1.1)
|
||||
oauth2 (~> 0.8.0)
|
||||
omniauth (~> 1.0)
|
||||
omniauth-oauth2 (1.1.2)
|
||||
faraday (>= 0.8, < 0.10)
|
||||
multi_json (~> 1.3)
|
||||
oauth2 (~> 0.9.3)
|
||||
omniauth (~> 1.2)
|
||||
orm_adapter (0.5.0)
|
||||
paperclip (4.1.0)
|
||||
paperclip (4.1.1)
|
||||
activemodel (>= 3.0.0)
|
||||
activesupport (>= 3.0.0)
|
||||
cocaine (~> 0.5.3)
|
||||
mime-types
|
||||
pg (0.14.1)
|
||||
pg-hstore (1.2.0)
|
||||
pg (0.17.1)
|
||||
polyglot (0.3.4)
|
||||
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)
|
||||
pygments.rb (0.2.13)
|
||||
rubypython (~> 0.5.3)
|
||||
rack (1.4.5)
|
||||
rack-cache (1.2)
|
||||
rack (>= 0.4)
|
||||
pygments.rb (0.5.4)
|
||||
posix-spawn (~> 0.3.6)
|
||||
yajl-ruby (~> 1.1.0)
|
||||
rack (1.5.2)
|
||||
rack-contrib (1.1.0)
|
||||
rack (>= 0.9.1)
|
||||
rack-protection (1.5.2)
|
||||
rack
|
||||
rack-ssl (1.3.3)
|
||||
rack
|
||||
rack-test (0.6.2)
|
||||
rack (>= 1.0)
|
||||
rack-throttle (0.3.0)
|
||||
rack (>= 1.0.0)
|
||||
rails (3.2.17)
|
||||
actionmailer (= 3.2.17)
|
||||
actionpack (= 3.2.17)
|
||||
activerecord (= 3.2.17)
|
||||
activeresource (= 3.2.17)
|
||||
activesupport (= 3.2.17)
|
||||
bundler (~> 1.0)
|
||||
railties (= 3.2.17)
|
||||
rails (4.0.4)
|
||||
actionmailer (= 4.0.4)
|
||||
actionpack (= 4.0.4)
|
||||
activerecord (= 4.0.4)
|
||||
activesupport (= 4.0.4)
|
||||
bundler (>= 1.3.0, < 2.0)
|
||||
railties (= 4.0.4)
|
||||
sprockets-rails (~> 2.0.0)
|
||||
rails3-generators (1.0.0)
|
||||
railties (>= 3.0.0)
|
||||
rails3-jquery-autocomplete (1.0.12)
|
||||
rails (>= 3.0)
|
||||
railties (3.2.17)
|
||||
actionpack (= 3.2.17)
|
||||
activesupport (= 3.2.17)
|
||||
rack-ssl (~> 1.3.2)
|
||||
railties (4.0.4)
|
||||
actionpack (= 4.0.4)
|
||||
activesupport (= 4.0.4)
|
||||
rake (>= 0.8.7)
|
||||
rdoc (~> 3.4)
|
||||
thor (>= 0.14.6, < 2.0)
|
||||
thor (>= 0.18.1, < 2.0)
|
||||
rake (10.1.1)
|
||||
rdiscount (2.1.7)
|
||||
rdoc (3.12.2)
|
||||
json (~> 1.4)
|
||||
redcarpet (2.2.2)
|
||||
redcarpet (3.1.1)
|
||||
redis (3.0.7)
|
||||
redis-actionpack (3.2.4)
|
||||
actionpack (~> 3.2.0)
|
||||
redis-rack (~> 1.4.4)
|
||||
redis-store (~> 1.1.4)
|
||||
redis-activesupport (3.2.5)
|
||||
activesupport (~> 3.2.0)
|
||||
redis-actionpack (4.0.0)
|
||||
actionpack (~> 4)
|
||||
redis-rack (~> 1.5.0)
|
||||
redis-store (~> 1.1.0)
|
||||
redis-activesupport (4.0.0)
|
||||
activesupport (~> 4)
|
||||
redis-store (~> 1.1.0)
|
||||
redis-namespace (1.4.1)
|
||||
redis (~> 3.0.4)
|
||||
redis-rack (1.4.4)
|
||||
rack (~> 1.4.0)
|
||||
redis-store (~> 1.1.4)
|
||||
redis-rails (3.2.4)
|
||||
redis-actionpack (~> 3.2.4)
|
||||
redis-activesupport (~> 3.2.4)
|
||||
redis-store (~> 1.1.4)
|
||||
redis-rack (1.5.0)
|
||||
rack (~> 1.5)
|
||||
redis-store (~> 1.1.0)
|
||||
redis-rails (4.0.0)
|
||||
redis-actionpack (~> 4)
|
||||
redis-activesupport (~> 4)
|
||||
redis-store (~> 1.1.0)
|
||||
redis-store (1.1.4)
|
||||
redis (>= 2.2)
|
||||
redisk (0.2.2)
|
||||
redis (>= 0.1.1)
|
||||
redis-namespace (>= 0.1.0)
|
||||
ref (1.0.5)
|
||||
resque (1.25.1)
|
||||
resque (1.25.2)
|
||||
mono_logger (~> 1.0)
|
||||
multi_json (~> 1.0)
|
||||
redis-namespace (~> 1.2)
|
||||
redis-namespace (~> 1.3)
|
||||
sinatra (>= 0.9.2)
|
||||
vegas (~> 0.1.2)
|
||||
resque-scheduler (2.5.4)
|
||||
resque-scheduler (2.5.5)
|
||||
mono_logger (~> 1.0)
|
||||
redis (~> 3.0.4)
|
||||
resque (~> 1.25.1)
|
||||
rufus-scheduler (~> 2.0.24)
|
||||
resque-status (0.3.3)
|
||||
redisk (>= 0.2.1)
|
||||
resque-status (0.4.2)
|
||||
resque (~> 1.19)
|
||||
uuid (~> 2.3)
|
||||
resque_mailer (2.2.6)
|
||||
actionmailer (>= 3.0)
|
||||
rest-client (1.6.7)
|
||||
mime-types (>= 1.16)
|
||||
rinku (1.7.3)
|
||||
rr (1.0.5)
|
||||
rspec (2.11.0)
|
||||
rspec-core (~> 2.11.0)
|
||||
rspec-expectations (~> 2.11.0)
|
||||
rspec-mocks (~> 2.11.0)
|
||||
rspec-core (2.11.1)
|
||||
rspec-expectations (2.11.3)
|
||||
diff-lcs (~> 1.1.3)
|
||||
rspec-mocks (2.11.3)
|
||||
rspec-rails (2.11.4)
|
||||
rouge (1.3.3)
|
||||
rr (1.1.2)
|
||||
rspec-core (2.14.8)
|
||||
rspec-expectations (2.14.5)
|
||||
diff-lcs (>= 1.1.3, < 2.0)
|
||||
rspec-mocks (2.14.6)
|
||||
rspec-rails (2.14.1)
|
||||
actionpack (>= 3.0)
|
||||
activemodel (>= 3.0)
|
||||
activesupport (>= 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)
|
||||
execjs
|
||||
sprockets (>= 2.0.0)
|
||||
rubypython (0.5.3)
|
||||
blankslate (>= 2.1.2.3)
|
||||
ffi (~> 1.0.7)
|
||||
rufus-scheduler (2.0.24)
|
||||
tzinfo (>= 0.3.22)
|
||||
russian (0.6.0)
|
||||
|
@ -390,11 +373,15 @@ GEM
|
|||
capistrano (~> 2.15.4)
|
||||
sanitize (2.0.6)
|
||||
nokogiri (>= 1.4.4)
|
||||
sass (3.2.13)
|
||||
sass-rails (3.2.6)
|
||||
railties (~> 3.2.0)
|
||||
sass (>= 3.1.10)
|
||||
tilt (~> 1.3)
|
||||
sass (3.2.14)
|
||||
sass-rails (4.0.2)
|
||||
railties (>= 4.0.0, < 5.0)
|
||||
sass (~> 3.2.0)
|
||||
sprockets (~> 2.8, <= 2.11.0)
|
||||
sprockets-rails (~> 2.0.0)
|
||||
schema_plus (1.4.1)
|
||||
rails (>= 3.2)
|
||||
valuable
|
||||
scrivener (0.0.3)
|
||||
shotgun (0.9)
|
||||
rack (>= 1.0)
|
||||
|
@ -414,15 +401,21 @@ GEM
|
|||
skype (0.2.7)
|
||||
tmp_cache
|
||||
soundmanager-rails (1.0.0)
|
||||
sprockets (2.2.2)
|
||||
sprockets (2.11.0)
|
||||
hike (~> 1.2)
|
||||
multi_json (~> 1.0)
|
||||
rack (~> 1.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)
|
||||
stringex (1.4.0)
|
||||
systemu (2.5.2)
|
||||
stringex (2.1.2)
|
||||
test_after_commit (0.2.3)
|
||||
therubyracer (0.12.1)
|
||||
libv8 (~> 3.16.14.0)
|
||||
ref
|
||||
|
@ -431,6 +424,8 @@ GEM
|
|||
eventmachine (>= 0.12.6)
|
||||
rack (>= 1.0.0)
|
||||
thor (0.18.1)
|
||||
thread_safe (0.2.0)
|
||||
atomic (>= 1.1.7, < 2)
|
||||
tilt (1.4.1)
|
||||
time_diff (0.3.0)
|
||||
activesupport
|
||||
|
@ -439,22 +434,17 @@ GEM
|
|||
treetop (1.4.15)
|
||||
polyglot
|
||||
polyglot (>= 0.3.1)
|
||||
turbo-sprockets-rails3 (0.3.11)
|
||||
railties (> 3.2.8, < 4.0.0)
|
||||
sprockets (>= 2.2.0)
|
||||
tzinfo (0.3.38)
|
||||
uglifier (1.2.7)
|
||||
tzinfo (0.3.39)
|
||||
uglifier (2.4.0)
|
||||
execjs (>= 0.3.0)
|
||||
multi_json (~> 1.3)
|
||||
underscore-rails (1.5.2)
|
||||
useragent (0.4.16)
|
||||
uuid (2.3.7)
|
||||
macaddr (~> 1.0)
|
||||
json (>= 1.8.0)
|
||||
underscore-rails (1.6.0)
|
||||
valuable (0.9.8)
|
||||
vegas (0.1.11)
|
||||
rack (>= 1.0.0)
|
||||
warden (1.2.3)
|
||||
rack (>= 1.0)
|
||||
whenever (0.9.0)
|
||||
whenever (0.9.2)
|
||||
activesupport (>= 2.3.4)
|
||||
chronic (>= 0.6.3)
|
||||
wikicloth (0.8.1)
|
||||
|
@ -463,96 +453,98 @@ GEM
|
|||
rinku
|
||||
will_paginate (3.0.5)
|
||||
ya2yaml (0.31)
|
||||
yajl-ruby (1.1.0)
|
||||
|
||||
PLATFORMS
|
||||
ruby
|
||||
|
||||
DEPENDENCIES
|
||||
RedCloth
|
||||
activerecord-postgres-hstore
|
||||
airbrake (~> 3.1.2)
|
||||
ancestry (~> 1.3.0)
|
||||
ancestry (~> 2.0.0)
|
||||
angular-i18n (= 0.1.2)
|
||||
angularjs-rails
|
||||
attr_encrypted (= 1.2.1)
|
||||
attr_encrypted (~> 1.3.2)
|
||||
better_errors
|
||||
binding_of_caller
|
||||
bluepill (~> 0.0.60)
|
||||
cancan (= 1.6.7)
|
||||
cancan!
|
||||
cape
|
||||
capistrano
|
||||
capistrano_colors
|
||||
charlock_holmes (~> 0.6.9)
|
||||
coffee-rails (~> 3.2.2)
|
||||
compass-rails (~> 1.0.3)
|
||||
coffee-rails (~> 4.0.1)
|
||||
compass-rails (~> 1.1.6)
|
||||
creole
|
||||
devise (~> 2.2.3)
|
||||
devise (~> 3.2.3)
|
||||
diff-display (~> 0.0.1)
|
||||
factory_girl_rails (~> 4.0.0)
|
||||
ffi
|
||||
friendly_id
|
||||
factory_girl_rails (~> 4.4.1)
|
||||
ffi (~> 1.9.3)
|
||||
friendly_id (~> 5.0.3)
|
||||
gemoji (~> 1.2.1)
|
||||
github-linguist (~> 2.3.4)
|
||||
gollum (~> 2.1.3)
|
||||
github-linguist (~> 2.10)
|
||||
gollum-lib (~> 2.0)
|
||||
grack!
|
||||
grit!
|
||||
haml-rails (~> 0.3.4)
|
||||
highline (~> 1.6.11)
|
||||
haml-rails (~> 0.5)
|
||||
highline (~> 1.6.20)
|
||||
hirb
|
||||
jbuilder (~> 1.4.2)
|
||||
jquery-rails (~> 2.0.2)
|
||||
jbuilder (~> 2.0.3)
|
||||
jquery-migrate-rails
|
||||
jquery-rails (~> 2.3.0)
|
||||
js-routes
|
||||
localeapp
|
||||
logglier
|
||||
mailcatcher
|
||||
meta-tags (~> 1.2.5)
|
||||
meta-tags (~> 1.5)
|
||||
meta_request
|
||||
mock_redis (= 0.6.2)
|
||||
mock_redis (~> 0.11)
|
||||
momentjs-rails
|
||||
newrelic_rpm
|
||||
ng-rails-csrf
|
||||
ohm
|
||||
ohm-expire
|
||||
ohm (~> 1.3.2)
|
||||
ohm-expire (~> 0.1.3)
|
||||
omniauth
|
||||
omniauth-facebook
|
||||
omniauth-github
|
||||
omniauth-google-oauth2
|
||||
paperclip (~> 4.1.0)
|
||||
paperclip (~> 4.1.1)
|
||||
perform_later!
|
||||
pg (~> 0.14.0)
|
||||
pg (~> 0.17.1)
|
||||
protected_attributes
|
||||
puma
|
||||
rack-throttle
|
||||
rails (= 3.2.17)
|
||||
rack-throttle (~> 0.3.0)
|
||||
rails (= 4.0.4)
|
||||
rails3-generators
|
||||
rails3-jquery-autocomplete (~> 1.0.7)
|
||||
rails3-jquery-autocomplete (~> 1.0)
|
||||
rake
|
||||
rdiscount
|
||||
redcarpet (~> 2.2.2)
|
||||
redhillonrails_core!
|
||||
redis-rails
|
||||
resque (~> 1.24)
|
||||
resque-scheduler
|
||||
resque-status (~> 0.3.3)
|
||||
redcarpet (~> 3.1.1)
|
||||
redis-rails (~> 4.0)
|
||||
resque (~> 1.25)
|
||||
resque-scheduler (~> 2.5.4)
|
||||
resque-status (~> 0.4.2)
|
||||
resque_mailer (~> 2.2)
|
||||
rest-client (~> 1.6.6)
|
||||
rr (~> 1.0.4)
|
||||
rspec-rails (~> 2.11.0)
|
||||
ruby-haml-js (~> 0.0.3)
|
||||
rest-client (~> 1.6.7)
|
||||
rr (~> 1.1.2)
|
||||
rspec-rails (~> 2.14.1)
|
||||
ruby-haml-js (~> 0.0.5)
|
||||
russian (~> 0.6.0)
|
||||
rvm-capistrano
|
||||
sass-rails (~> 3.2.5)
|
||||
sass-rails (~> 4.0.1)
|
||||
schema_plus (~> 1.4.0)
|
||||
shotgun
|
||||
shoulda
|
||||
shoulda-matchers
|
||||
skype
|
||||
soundmanager-rails
|
||||
state_machine
|
||||
state_machine (~> 1.2)
|
||||
test_after_commit
|
||||
therubyracer (~> 0.12.1)
|
||||
therubyrhino (~> 1.73.1)
|
||||
time_diff
|
||||
trinidad (~> 1.0.2)
|
||||
turbo-sprockets-rails3
|
||||
uglifier (~> 1.2.4)
|
||||
uglifier (~> 2.4)
|
||||
underscore-rails
|
||||
whenever (~> 0.9.0)
|
||||
wikicloth
|
||||
will_paginate (~> 3.0.3)
|
||||
will_paginate (~> 3.0.5)
|
||||
|
|
|
@ -1,34 +1,24 @@
|
|||
RosaABF.controller('ProjectScheduleController', ['$scope', '$http', function($scope, $http) {
|
||||
|
||||
// See: Modules::Models::Autostart::AUTOSTART_STATUSES
|
||||
// See: Autostart::AUTOSTART_STATUSES
|
||||
$scope.statuses = {
|
||||
'0': 'autostart_statuses.0',
|
||||
'1': 'autostart_statuses.1',
|
||||
'2': 'autostart_statuses.2'
|
||||
};
|
||||
$scope.project = null;
|
||||
$scope.owner = null;
|
||||
$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() {
|
||||
$http.put(
|
||||
Routes.project_path($scope.owner, $scope.project),
|
||||
Routes.project_path($scope.name_with_owner),
|
||||
{project: {autostart_status: $scope.autostart_status}, format: 'json'}
|
||||
);
|
||||
}
|
||||
|
||||
$scope.updateSchedule = function(obj) {
|
||||
$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'}
|
||||
);
|
||||
}
|
||||
|
||||
}]);
|
|
@ -28,15 +28,15 @@ var BuildList = function(atts, dictionary) {
|
|||
}
|
||||
|
||||
if (self.project) {
|
||||
self.project.name_with_owner = self.project.owner + '/' + self.project.name;
|
||||
if (self.last_published_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 {
|
||||
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.name_with_owner = self.project.owner + '/' + self.project.name;
|
||||
self.project.url = Routes.project_path(self.project.name_with_owner);
|
||||
}
|
||||
|
||||
if (self.user)
|
||||
|
|
|
@ -14,15 +14,15 @@ var ProjectRef = function(atts) {
|
|||
self.ui_container = false;
|
||||
|
||||
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) {
|
||||
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) {
|
||||
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
|
||||
|
|
|
@ -13,7 +13,8 @@ RosaABF.factory('ApiCollaborator', ['$resource', function($resource) {
|
|||
isArray : false
|
||||
},
|
||||
find: {
|
||||
url: '/:owner/:project/collaborators/find.json',
|
||||
url: '/:owner/:project/collaborators/find',
|
||||
format: 'json',
|
||||
method: 'GET',
|
||||
isArray : true
|
||||
}
|
||||
|
|
|
@ -5,27 +5,32 @@ RosaABF.factory("ApiProject", ['$resource', function($resource) {
|
|||
{owner: '@project.owner.uname', project: '@project.name'},
|
||||
{
|
||||
tags: {
|
||||
url: '/:owner/:project/tags.json',
|
||||
url: '/:owner/:project/tags',
|
||||
format: 'json',
|
||||
method: 'GET',
|
||||
isArray : false
|
||||
},
|
||||
branches: {
|
||||
url: '/:owner/:project/branches.json',
|
||||
url: '/:owner/:project/branches',
|
||||
format: 'json',
|
||||
method: 'GET',
|
||||
isArray : false
|
||||
},
|
||||
delete_branch: {
|
||||
url: '/:owner/:project/branches/:ref.json',
|
||||
url: '/:owner/:project/branches/:ref',
|
||||
format: 'json',
|
||||
method: 'DELETE',
|
||||
isArray : false
|
||||
},
|
||||
restore_branch: {
|
||||
url: '/:owner/:project/branches/:ref.json', // ?sha=<sha>
|
||||
url: '/:owner/:project/branches/:ref', // ?sha=<sha>
|
||||
format: 'json',
|
||||
method: 'PUT',
|
||||
isArray : false
|
||||
},
|
||||
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',
|
||||
isArray : false
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
RosaABF.factory("ApiPullRequest", ['$resource', function($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',
|
||||
project: '@pull_request.to_ref.project.name',
|
||||
|
@ -13,7 +13,8 @@ RosaABF.factory("ApiPullRequest", ['$resource', function($resource) {
|
|||
isArray : false
|
||||
},
|
||||
merge: {
|
||||
url: '/:owner/:project/pull_requests/:serial_id/merge.json',
|
||||
url: '/:owner/:project/pull_requests/:serial_id/merge',
|
||||
format: 'json',
|
||||
method: 'PUT',
|
||||
isArray: false
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
//= require jquery
|
||||
//= require jquery-migrate-min
|
||||
//= require jquery_ujs
|
||||
//= require jquery-ui
|
||||
//= require autocomplete-rails
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
//= require jquery
|
||||
//= require jquery_ujs
|
||||
//= require jquery-ui
|
||||
//= require jquery-migrate-min
|
||||
//= require pirobox_extended_min
|
||||
//= require ./design/all
|
||||
|
||||
|
|
|
@ -87,6 +87,6 @@ class Admin::UsersController < Admin::BaseController
|
|||
protected
|
||||
|
||||
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
|
||||
|
|
|
@ -6,7 +6,7 @@ class Api::V1::AdvisoriesController < Api::V1::BaseController
|
|||
authorize_resource :build_list, only: [:create, :update]
|
||||
|
||||
def index
|
||||
@advisories = @advisories.scoped(include: [:platforms, :projects]).
|
||||
@advisories = @advisories.includes(:platforms, :projects).
|
||||
paginate(paginate_params)
|
||||
end
|
||||
|
||||
|
|
|
@ -13,6 +13,34 @@ class Api::V1::BaseController < ApplicationController
|
|||
|
||||
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)
|
||||
headers['Content-Type'] = 'text/csv'
|
||||
headers['Content-disposition'] = "attachment; filename=\"#{file_name}.csv\""
|
||||
|
|
|
@ -3,12 +3,13 @@ class Api::V1::BuildListsController < Api::V1::BaseController
|
|||
before_filter :authenticate_user!
|
||||
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]
|
||||
|
||||
def index
|
||||
authorize!(:show, @project) if @project
|
||||
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)
|
||||
end
|
||||
|
||||
|
|
|
@ -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 :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]
|
||||
|
||||
def index
|
||||
|
@ -60,7 +61,7 @@ class Api::V1::IssuesController < Api::V1::BaseController
|
|||
private
|
||||
|
||||
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'
|
||||
@issues = @issues.closed
|
||||
else
|
||||
|
|
|
@ -58,7 +58,7 @@ class Api::V1::JobsController < Api::V1::BaseController
|
|||
|
||||
def status
|
||||
if params[:key] =~ /\Aabfworker::(rpm|iso)-worker-[\d]+::live-inspector\z/
|
||||
status = Resque.redis.get(params[:key])
|
||||
status = Redis.current.get(params[:key])
|
||||
end
|
||||
render json: { status: status }.to_json
|
||||
end
|
||||
|
|
|
@ -7,12 +7,12 @@ class ApplicationController < ActionController::Base
|
|||
layout :layout_by_resource
|
||||
|
||||
# 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 lambda { EventLog.current_controller = self },
|
||||
before_filter -> { EventLog.current_controller = self },
|
||||
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
|
||||
|
||||
|
@ -48,10 +48,15 @@ class ApplicationController < ActionController::Base
|
|||
def render_error(status)
|
||||
respond_to do |format|
|
||||
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
|
||||
|
||||
# Helper method for all controllers
|
||||
def permit_params(param_name, *accessible)
|
||||
(params[param_name] || ActionController::Parameters.new).permit(*accessible.flatten)
|
||||
end
|
||||
|
||||
def set_locale
|
||||
I18n.locale = check_locale( get_user_locale ||
|
||||
(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
|
||||
end
|
||||
else
|
||||
params['user_id'] && User.find_by_id(params['user_id']) ||
|
||||
params['group_id'] && Group.find_by_id(params['group_id']) || current_user
|
||||
params['user_id'] && User.find(params['user_id']) ||
|
||||
params['group_id'] && Group.find(params['group_id']) || current_user
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -1,13 +1,14 @@
|
|||
class Groups::MembersController < Groups::BaseController
|
||||
before_filter lambda { authorize! :manage_members, @group }
|
||||
before_filter -> { authorize! :manage_members, @group }
|
||||
|
||||
def index
|
||||
@members = @group.members.order(:uname) - [@group.owner]
|
||||
end
|
||||
|
||||
def update
|
||||
params['user'].keys.each do |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
|
||||
else
|
||||
relation = @group.actors.build(actor_id: user_id, actor_type: 'User', role: role)
|
||||
|
@ -34,7 +35,7 @@ class Groups::MembersController < Groups::BaseController
|
|||
end
|
||||
|
||||
def add
|
||||
@user = User.find_by_uname(params[:user_uname])
|
||||
@user = User.find_by uname: params[:user_uname]
|
||||
if !@user
|
||||
flash[:error] = t("flash.collaborators.wrong_user", uname: params[:user_uname])
|
||||
elsif @group.add_member(@user, params[:role])
|
||||
|
|
|
@ -9,8 +9,8 @@ class Groups::ProfileController < Groups::BaseController
|
|||
end
|
||||
|
||||
def show
|
||||
@path, page = group_path, params[:page].to_i
|
||||
@projects = @group.own_projects.opened.search(params[:search]).recent
|
||||
@path, page = group_path(@group), params[:page].to_i
|
||||
@projects = @group.own_projects.search(params[:search]).recent
|
||||
if request.xhr?
|
||||
if params[:visibility] != 'hidden'
|
||||
@projects = @projects.opened
|
||||
|
@ -20,6 +20,7 @@ class Groups::ProfileController < Groups::BaseController
|
|||
end
|
||||
render partial: 'shared/profile_projects', layout: nil, locals: {projects: paginate_projects(page)}
|
||||
else
|
||||
@projects = @projects.opened
|
||||
@projects = paginate_projects(page)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -112,7 +112,7 @@ class Platforms::PlatformsController < Platforms::BaseController
|
|||
end
|
||||
|
||||
def members
|
||||
@members = @platform.members.order('name')
|
||||
@members = @platform.members.order(:uname)
|
||||
end
|
||||
|
||||
def remove_members
|
||||
|
|
|
@ -67,8 +67,6 @@ class Platforms::ProductsController < Platforms::BaseController
|
|||
protected
|
||||
|
||||
def set_project
|
||||
args = params[:src_project].try(:split, '/') || []
|
||||
@product.project = (args.length == 2) ?
|
||||
Project.find_by_owner_and_name(*args) : nil
|
||||
@product.project = Project.find_by_owner_and_name params[:src_project]
|
||||
end
|
||||
end
|
||||
|
|
|
@ -12,7 +12,7 @@ class Projects::BaseController < ApplicationController
|
|||
end
|
||||
|
||||
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
|
||||
|
||||
def init_statistics
|
||||
|
|
|
@ -8,13 +8,15 @@ class Projects::BuildListsController < Projects::BaseController
|
|||
|
||||
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 except: NESTED_ACTIONS
|
||||
|
||||
before_filter :create_from_build_list, only: :new
|
||||
|
||||
def index
|
||||
authorize!(:show, @project) if @project
|
||||
params[:filter].each{|k,v| params[:filter].delete(k) if v.blank? } if params[:filter]
|
||||
|
||||
respond_to do |format|
|
||||
|
|
|
@ -47,7 +47,7 @@ class Projects::CommentsController < Projects::BaseController
|
|||
protected
|
||||
|
||||
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])
|
||||
end
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
class Projects::Git::BlobsController < Projects::Git::BaseController
|
||||
before_filter :set_blob
|
||||
before_filter lambda {authorize! :write, @project}, only: [:edit, :update]
|
||||
before_filter -> {authorize! :write, @project}, only: [:edit, :update]
|
||||
|
||||
def show
|
||||
end
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
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
|
||||
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]
|
||||
before_filter lambda { authorize!(:write, @project) }, only: [:destroy, :restore_branch, :create]
|
||||
before_filter -> { authorize!(:write, @project) }, only: [:destroy, :restore_branch, :create]
|
||||
|
||||
def show
|
||||
unless request.xhr?
|
||||
|
|
|
@ -24,7 +24,7 @@ class Projects::IssuesController < Projects::BaseController
|
|||
@sort = params[:sort] == 'updated' ? :updated : :created
|
||||
@direction = params[:direction] == 'asc' ? :asc : :desc
|
||||
@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]
|
||||
if status == 200
|
||||
render 'index', layout: request.xhr? ? 'with_sidebar' : 'application'
|
||||
|
@ -81,11 +81,11 @@ class Projects::IssuesController < Projects::BaseController
|
|||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
@issue.destroy
|
||||
flash[:notice] = t("flash.issue.destroyed")
|
||||
redirect_to root_path
|
||||
end
|
||||
# def destroy
|
||||
# @issue.destroy
|
||||
# flash[:notice] = t("flash.issue.destroyed")
|
||||
# redirect_to root_path
|
||||
# end
|
||||
|
||||
def create_label
|
||||
index(@project.labels.create!(name: params[:name], color: params[:color]) ? 200 : 500)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
class Projects::ProjectsController < Projects::BaseController
|
||||
include ProjectsHelper
|
||||
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]
|
||||
|
||||
def index
|
||||
|
|
|
@ -152,8 +152,7 @@ class Projects::PullRequestsController < Projects::BaseController
|
|||
end
|
||||
|
||||
def find_destination_project bang=true
|
||||
args = params[:to_project].try(:split, '/') || []
|
||||
project = (args.length == 2) ? Project.find_by_owner_and_name(*args) : nil
|
||||
project = Project.find_by_owner_and_name params[:to_project]
|
||||
raise ActiveRecord::RecordNotFound if bang && !project
|
||||
project || @project
|
||||
end
|
||||
|
|
|
@ -45,7 +45,7 @@ class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
|
|||
else
|
||||
raise 'Provider #{provider} not handled'
|
||||
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?
|
||||
user.name = name
|
||||
user.uname = name.gsub(/\s/, '').underscore
|
||||
|
|
|
@ -13,6 +13,7 @@ class Users::ProfileController < Users::BaseController
|
|||
end
|
||||
render partial: 'shared/profile_projects', layout: nil, locals: {projects: paginate_projects(page)}
|
||||
else
|
||||
@projects = @projects.opened
|
||||
@projects = paginate_projects(page)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -3,7 +3,7 @@ class Users::SettingsController < Users::BaseController
|
|||
before_filter :set_current_user
|
||||
|
||||
def profile
|
||||
if request.put?
|
||||
if request.patch?
|
||||
send_confirmation = params[:user][:email] != @user.email
|
||||
if @user.update_without_password(params[:user])
|
||||
update_avatar(@user, params)
|
||||
|
@ -27,7 +27,7 @@ class Users::SettingsController < Users::BaseController
|
|||
end
|
||||
|
||||
def private
|
||||
if request.put?
|
||||
if request.patch?
|
||||
if @user.update_with_password(params[:user])
|
||||
flash[:notice] = t('flash.user.saved')
|
||||
redirect_to private_settings_path
|
||||
|
@ -40,7 +40,7 @@ class Users::SettingsController < Users::BaseController
|
|||
end
|
||||
|
||||
def notifiers
|
||||
if request.put?
|
||||
if request.patch?
|
||||
if @user.notifier.update_attributes(params[:settings_notifier])
|
||||
flash[:notice] = I18n.t("flash.settings.saved")
|
||||
redirect_to notifiers_settings_path
|
||||
|
@ -49,4 +49,5 @@ class Users::SettingsController < Users::BaseController
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -3,8 +3,7 @@ class Users::UsersController < Users::BaseController
|
|||
before_filter :find_user_by_key, only: [:allowed, :discover]
|
||||
|
||||
def allowed
|
||||
owner_name, project_name = params[:project].split '/'
|
||||
project = Project.find_by_owner_and_name!(owner_name, project_name ? project_name : '!')
|
||||
project = Project.find_by_owner_and_name! params[:project]
|
||||
action = case params[:action_type]
|
||||
when 'git-upload-pack'
|
||||
then :read
|
||||
|
|
|
@ -87,7 +87,7 @@ module BuildListsHelper
|
|||
bl = item.build_list
|
||||
{
|
||||
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
|
||||
{}
|
||||
|
@ -99,10 +99,10 @@ module BuildListsHelper
|
|||
if bl.commit_hash.present?
|
||||
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}",
|
||||
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
|
||||
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
|
||||
else
|
||||
bl.project_version
|
||||
|
@ -112,7 +112,7 @@ module BuildListsHelper
|
|||
def product_build_list_version_link(bl, str_version = false)
|
||||
if bl.commit_hash.present?
|
||||
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
|
||||
bl.project_version
|
||||
end
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# This module is based on
|
||||
# https://github.com/gitlabhq/gitlabhq/blob/7665b1de7eed4addd7b94786c84e6674710e6377/app/helpers/gitlab_markdown_helper.rb
|
||||
module GitlabMarkdownHelper
|
||||
include Modules::Models::Markdown
|
||||
include MarkdownHelper
|
||||
|
||||
# Use this in places where you would normally use link_to(gfm(...), ...).
|
||||
#
|
||||
|
|
|
@ -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
|
|
@ -2,13 +2,13 @@ class BuildListsQueuesMonitoringJob
|
|||
@queue = :hook
|
||||
|
||||
def self.perform
|
||||
redis.smembers('queues').each do |key|
|
||||
Redis.current.smembers('resque:queues').each do |key|
|
||||
next if key !~ /(user|mass)_build_/
|
||||
|
||||
queue = "queue:#{key}"
|
||||
queue = "resque:queue:#{key}"
|
||||
id = key.gsub(/[^\d]/, '')
|
||||
|
||||
if redis.llen(queue) == 0
|
||||
if Redis.current.llen(queue) == 0
|
||||
if key =~ /^user/
|
||||
last_updated_at = BuildList.select(:updated_at).
|
||||
where(user_id: id).order('updated_at DESC').first
|
||||
|
@ -21,29 +21,25 @@ class BuildListsQueuesMonitoringJob
|
|||
else
|
||||
# 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
|
||||
redis.sadd set_key, id
|
||||
Redis.current.sadd set_key, id
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
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
|
||||
redis.watch(queue) do
|
||||
if redis.llen(queue) == 0
|
||||
redis.multi do |multi|
|
||||
Redis.current.watch(queue) do
|
||||
if Redis.current.llen(queue) == 0
|
||||
Redis.current.multi do |multi|
|
||||
multi.del queue
|
||||
multi.srem 'queues', key
|
||||
multi.srem 'resque:queues', key
|
||||
end
|
||||
else
|
||||
redis.unwatch
|
||||
Redis.current.unwatch
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def self.redis
|
||||
@redis ||= Resque.redis
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -18,12 +18,12 @@ class UserMailer < ActionMailer::Base
|
|||
end
|
||||
end
|
||||
|
||||
def new_comment_notification(comment, user)
|
||||
@user, @comment = user, comment
|
||||
def new_comment_notification(comment, user_id)
|
||||
@user, @comment = User.find(user_id), comment
|
||||
subject = @comment.issue_comment? ? subject_for_issue(@comment.commentable) :
|
||||
I18n.t('notifications.subjects.new_commit_comment_notification')
|
||||
mail(
|
||||
to: email_with_name(user, user.email),
|
||||
to: email_with_name(@user, @user.email),
|
||||
subject: subject,
|
||||
from: email_with_name(comment.user)
|
||||
) do |format|
|
||||
|
|
|
@ -15,7 +15,7 @@ class Ability
|
|||
can [:show, :archive], Project, visibility: 'open'
|
||||
can :get_id, Project, visibility: 'open' # api
|
||||
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, :log, :everything], BuildList, project: {visibility: 'open'}
|
||||
can [:read, :log], ProductBuildList#, product: {platform: {visibility: 'open'}} # double nested hash don't work
|
||||
|
|
|
@ -1,20 +1,21 @@
|
|||
class ActivityFeed < ActiveRecord::Base
|
||||
|
||||
CODE = ['git_delete_branch_notification', 'git_new_push_notification', 'new_comment_commit_notification']
|
||||
TRACKER = ['issue_assign_notification', 'new_comment_notification', 'new_issue_notification']
|
||||
BUILD = ['build_list_notification']
|
||||
WIKI = ['wiki_new_commit_notification']
|
||||
CODE = %w(git_delete_branch_notification git_new_push_notification new_comment_commit_notification)
|
||||
TRACKER = %w(issue_assign_notification new_comment_notification new_issue_notification)
|
||||
BUILD = %w(build_list_notification)
|
||||
WIKI = %w(wiki_new_commit_notification)
|
||||
|
||||
belongs_to :user
|
||||
serialize :data
|
||||
|
||||
default_scope order("#{table_name}.created_at DESC")
|
||||
scope :outdated, offset(100)
|
||||
attr_accessible :user, :kind, :data
|
||||
|
||||
default_scope { order created_at: :desc }
|
||||
scope :outdated, -> { offset(100) }
|
||||
|
||||
self.per_page = 10
|
||||
|
||||
def partial
|
||||
'home/partials/' + self.kind
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
class Advisory < ActiveRecord::Base
|
||||
self.include_root_in_json = false
|
||||
|
||||
has_and_belongs_to_many :platforms
|
||||
has_and_belongs_to_many :projects
|
||||
has_many :build_lists
|
||||
|
@ -9,18 +11,20 @@ class Advisory < ActiveRecord::Base
|
|||
after_create :generate_advisory_id
|
||||
before_save :normalize_references, if: :references_changed?
|
||||
|
||||
attr_accessible :description
|
||||
|
||||
ID_TEMPLATE = 'ROSA-%<type>s-%<year>d:%<id>04d'
|
||||
ID_STRING_TEMPLATE = 'ROSA-%<type>s-%<year>04s:%<id>04s'
|
||||
TYPES = {'security' => 'SA', 'bugfix' => 'A'}
|
||||
|
||||
scope :search, lambda { |q|
|
||||
scope :search, ->(q) {
|
||||
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}%").
|
||||
joins(build_lists: :packages) if q.present?
|
||||
}
|
||||
scope :search_by_id, lambda { |aid| where("#{table_name}.advisory_id ILIKE ?", "%#{aid.to_s.strip}%") }
|
||||
scope :by_update_type, lambda { |ut| where(update_type: ut) }
|
||||
default_scope order("#{table_name}.created_at DESC")
|
||||
scope :search_by_id, ->(aid) { where("#{table_name}.advisory_id ILIKE ?", "%#{aid.to_s.strip}%") }
|
||||
scope :by_update_type, ->(ut) { where(update_type: ut) }
|
||||
default_scope { order(created_at: :desc) }
|
||||
|
||||
def to_param
|
||||
advisory_id
|
||||
|
@ -37,7 +41,7 @@ class Advisory < ActiveRecord::Base
|
|||
# this method fetches and structurize packages attached to current advisory.
|
||||
def fetch_packages_info
|
||||
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|
|
||||
tmp = build_list.packages.inject({srpm: nil, rpm: []}) do |h, p|
|
||||
p.package_type == 'binary' ? h[:rpm] << p.fullname : h[:srpm] = p.fullname
|
||||
|
@ -69,4 +73,3 @@ class Advisory < ActiveRecord::Base
|
|||
end
|
||||
|
||||
end
|
||||
Advisory.include_root_in_json = false
|
|
@ -5,5 +5,5 @@ class Arch < ActiveRecord::Base
|
|||
|
||||
validates :name, presence: true, uniqueness: true
|
||||
|
||||
scope :recent, order("#{table_name}.name ASC")
|
||||
scope :recent, -> { order(:name) }
|
||||
end
|
||||
|
|
|
@ -2,5 +2,5 @@ class Authentication < ActiveRecord::Base
|
|||
belongs_to :user
|
||||
|
||||
validates :provider, :uid, :user_id, presence: true
|
||||
validates :uid, uniqueness: {scope: :provider, case_sensitive: false}
|
||||
validates :uid, uniqueness: { scope: :provider, case_sensitive: false }
|
||||
end
|
||||
|
|
|
@ -2,18 +2,19 @@ class Avatar < ActiveRecord::Base
|
|||
self.abstract_class = true
|
||||
|
||||
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.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
|
||||
|
||||
has_attached_file :avatar, styles: AVATAR_SIZES_HASH
|
||||
validates_attachment_size :avatar, less_than_or_equal_to: MAX_AVATAR_SIZE
|
||||
validates_attachment_content_type :avatar, content_type: /\Aimage/
|
||||
validates_attachment_file_name :avatar, matches: [ /(png|jpe?g|gif|bmp|tif?f)\z/i ]
|
||||
|
||||
attr_accessible :avatar
|
||||
|
||||
end
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
class BuildList < ActiveRecord::Base
|
||||
include Modules::Models::CommitAndVersion
|
||||
include Modules::Models::FileStoreClean
|
||||
include CommitAndVersion
|
||||
include FileStoreClean
|
||||
include AbfWorker::ModelHelper
|
||||
include Modules::Observers::ActivityFeed::BuildList
|
||||
include Feed::BuildList
|
||||
include BuildListObserver
|
||||
include EventLoggable
|
||||
|
||||
belongs_to :project
|
||||
belongs_to :arch
|
||||
|
@ -16,7 +18,7 @@ class BuildList < ActiveRecord::Base
|
|||
belongs_to :mass_build, counter_cache: true, touch: true
|
||||
has_many :items, class_name: '::BuildList::Item', 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]
|
||||
RELEASE_UPDATE_TYPES = %w[bugfix security]
|
||||
|
@ -31,28 +33,28 @@ class BuildList < ActiveRecord::Base
|
|||
validates :project_id, :project_version, :arch, :include_repos,
|
||||
: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 :external_nodes, inclusion: {in: EXTERNAL_NODES}, allow_blank: true
|
||||
validates :auto_publish_status, inclusion: {in: AUTO_PUBLISH_STATUSES}
|
||||
validates :external_nodes, inclusion: { in: EXTERNAL_NODES }, allow_blank: true
|
||||
validates :auto_publish_status, inclusion: { in: AUTO_PUBLISH_STATUSES }
|
||||
validates :update_type, inclusion: UPDATE_TYPES,
|
||||
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? }
|
||||
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
|
||||
}
|
||||
validate lambda {
|
||||
validate -> {
|
||||
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
|
||||
}
|
||||
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
|
||||
}
|
||||
validate lambda {
|
||||
validate -> {
|
||||
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_build_lists, on: :create
|
||||
before_validation :prepare_extra_params, on: :create
|
||||
|
@ -95,40 +97,45 @@ class BuildList < ActiveRecord::Base
|
|||
STATUSES.freeze
|
||||
HUMAN_STATUSES.freeze
|
||||
|
||||
scope :recent, order("#{table_name}.updated_at DESC")
|
||||
scope :for_extra_build_lists, lambda {|ids, current_ability, save_to_platform|
|
||||
s = scoped
|
||||
scope :recent, -> { order(updated_at: :desc) }
|
||||
scope :for_extra_build_lists, ->(ids, current_ability, save_to_platform) {
|
||||
s = all
|
||||
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
|
||||
}
|
||||
scope :for_status, lambda {|status| where(status: status) if status.present? }
|
||||
scope :for_user, lambda { |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 :external_nodes, lambda { |type| where("#{table_name}.external_nodes = ?", type) }
|
||||
scope :oldest, lambda { where("#{table_name}.updated_at < ?", Time.zone.now - 15.seconds) }
|
||||
scope :for_platform, lambda { |platform| where(build_for_platform_id: platform) }
|
||||
scope :by_mass_build, lambda { |mass_build| where(mass_build_id: mass_build) }
|
||||
scope :scoped_to_arch, lambda {|arch| where(arch_id: arch) 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_project_version, lambda {|project_version| where(project_version: project_version) if project_version.present? }
|
||||
scope :scoped_to_is_circle, lambda {|is_circle| where(is_circle: is_circle) }
|
||||
scope :for_creation_date_period, lambda{|start_date, end_date|
|
||||
s = scoped
|
||||
scope :for_status, ->(status) { where(status: status) if status.present? }
|
||||
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 :external_nodes, ->(type) { where("#{table_name}.external_nodes = ?", type) }
|
||||
scope :oldest, -> { where("#{table_name}.updated_at < ?", Time.zone.now - 15.seconds) }
|
||||
scope :for_platform, ->(platform) { where(build_for_platform_id: platform) }
|
||||
scope :by_mass_build, ->(mass_build) { where(mass_build_id: mass_build) }
|
||||
scope :scoped_to_arch, ->(arch) { where(arch_id: arch) if arch.present? }
|
||||
scope :scoped_to_save_platform, ->(pl_id) { where(save_to_platform_id: pl_id) if pl_id.present? }
|
||||
scope :scoped_to_project_version, ->(pr_version) { where(project_version: pr_version) if pr_version.present? }
|
||||
scope :scoped_to_is_circle, ->(is_circle) { where(is_circle: is_circle) }
|
||||
scope :for_creation_date_period, ->(start_date, end_date) {
|
||||
s = all
|
||||
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
|
||||
}
|
||||
scope :for_notified_date_period, lambda{|start_date, end_date|
|
||||
s = scoped
|
||||
scope :for_notified_date_period, ->(start_date, end_date) {
|
||||
s = all
|
||||
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
|
||||
}
|
||||
scope :scoped_to_project_name, lambda {|project_name| joins(:project).where('projects.name LIKE ?', "%#{project_name}%") if project_name.present? }
|
||||
scope :scoped_to_new_core, lambda {|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)
|
||||
scope :scoped_to_project_name, ->(project_name) {
|
||||
joins(:project).where('projects.name LIKE ?', "%#{project_name}%") if project_name.present?
|
||||
}
|
||||
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 :include_repos
|
||||
|
@ -137,7 +144,7 @@ class BuildList < ActiveRecord::Base
|
|||
serialize :extra_build_lists, Array
|
||||
serialize :extra_params, Hash
|
||||
|
||||
after_commit :place_build, on: :create
|
||||
after_create :place_build
|
||||
after_destroy :remove_container
|
||||
|
||||
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: :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
|
||||
transition waiting_for_response: :build_pending
|
||||
|
@ -413,7 +420,7 @@ class BuildList < ActiveRecord::Base
|
|||
end
|
||||
|
||||
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!}
|
||||
pkg_hash['rpm'].each do |rpm_hash|
|
||||
build_package(rpm_hash, 'binary', prj) {|p| p.save!}
|
||||
|
@ -425,7 +432,11 @@ class BuildList < ActiveRecord::Base
|
|||
end
|
||||
|
||||
def current_duration
|
||||
if started_at
|
||||
(Time.now.utc - started_at.utc).to_i
|
||||
else
|
||||
0
|
||||
end
|
||||
end
|
||||
|
||||
def human_current_duration
|
||||
|
@ -527,17 +538,16 @@ class BuildList < ActiveRecord::Base
|
|||
end
|
||||
|
||||
def self.next_build
|
||||
redis = Resque.redis
|
||||
kind_id = redis.spop(USER_BUILDS_SET)
|
||||
kind_id = Redis.current.spop(USER_BUILDS_SET)
|
||||
key = "user_build_#{kind_id}_rpm_worker_default" if kind_id
|
||||
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
|
||||
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
|
||||
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? }
|
||||
|
||||
# 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?
|
||||
end if project
|
||||
users.each{ |u| UserMailer.build_list_notification(self, u).deliver }
|
||||
|
|
|
@ -9,7 +9,7 @@ class BuildList::Filter
|
|||
end
|
||||
|
||||
def find
|
||||
build_lists = @project ? @project.build_lists : BuildList.scoped
|
||||
build_lists = @project ? @project.build_lists : BuildList.all
|
||||
|
||||
if @options[:id]
|
||||
build_lists = build_lists.where(id: @options[:id])
|
||||
|
|
|
@ -17,14 +17,12 @@ class BuildList::Item < ActiveRecord::Base
|
|||
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
|
||||
items = scoped({}).recent
|
||||
|
||||
groups = []
|
||||
current_level = -1
|
||||
items.each do |item|
|
||||
all.recent.find_each do |item|
|
||||
groups << [] if current_level < item.level
|
||||
groups.last << item
|
||||
current_level = item.level
|
||||
|
|
|
@ -13,14 +13,14 @@ class BuildList::Package < ActiveRecord::Base
|
|||
validates :package_type, inclusion: PACKAGE_TYPES
|
||||
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.
|
||||
scope :actual, where(actual: true)
|
||||
scope :by_platform, lambda {|platform| where(platform_id: platform) }
|
||||
scope :by_name, lambda {|name| where(name: name) }
|
||||
scope :by_package_type, lambda {|type| where(package_type: type) }
|
||||
scope :like_name, lambda {|name| where("#{table_name}.name ILIKE ?", "%#{name}%") if name.present?}
|
||||
scope :actual, -> { where(actual: true) }
|
||||
scope :by_platform, ->(platform) { where(platform_id: platform) }
|
||||
scope :by_name, ->(name) { where(name: name) }
|
||||
scope :by_package_type, ->(type) { where(package_type: type) }
|
||||
scope :like_name, ->(name) { where("#{table_name}.name ILIKE ?", "%#{name}%") if name.present? }
|
||||
|
||||
before_create :set_epoch
|
||||
|
||||
|
|
|
@ -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
|
|
@ -1,5 +1,5 @@
|
|||
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
|
||||
# User/Project#Num
|
||||
|
@ -7,17 +7,18 @@ class Comment < ActiveRecord::Base
|
|||
# #Num
|
||||
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 :project
|
||||
serialize :data
|
||||
|
||||
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)}
|
||||
default_scope order("#{table_name}.created_at")
|
||||
scope :for_commit, ->(c) { where(commentable_id: c.id.hex, commentable_type: c.class) }
|
||||
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
|
||||
|
||||
attr_accessible :body, :data
|
||||
|
@ -186,8 +187,12 @@ class Comment < ActiveRecord::Base
|
|||
|
||||
protected
|
||||
|
||||
def touch_commentable
|
||||
commentable.touch unless commit_comment?
|
||||
end
|
||||
|
||||
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
|
||||
|
||||
def subscribe_users
|
||||
|
@ -195,7 +200,7 @@ class Comment < ActiveRecord::Base
|
|||
commentable.subscribes.create(user: user) if !commentable.subscribes.exists?(user_id: user.id)
|
||||
elsif commit_comment?
|
||||
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|
|
||||
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)
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -1,4 +1,4 @@
|
|||
module Modules::Observers::ActivityFeed::BuildList
|
||||
module Feed::BuildList
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
included do
|
|
@ -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
|
|
@ -1,4 +1,4 @@
|
|||
module Modules::Observers::ActivityFeed::Git
|
||||
module Feed::Git
|
||||
|
||||
def self.create_notifications(record)
|
||||
|
||||
|
@ -49,7 +49,7 @@ module Modules::Observers::ActivityFeed::Git
|
|||
end
|
||||
|
||||
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.admins.each do |recipient|
|
|
@ -1,14 +1,14 @@
|
|||
module Modules::Observers::ActivityFeed::Issue
|
||||
module Feed::Issue
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
included do
|
||||
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(:update) }, on: :update
|
||||
after_commit :send_assign_notifications, on: :create, if: ->(i) { i.assignee }
|
||||
after_update -> { send_assign_notifications(:update) }
|
||||
|
||||
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
|
||||
|
||||
private
|
||||
|
@ -34,7 +34,7 @@ module Modules::Observers::ActivityFeed::Issue
|
|||
}
|
||||
)
|
||||
end
|
||||
Comment.create_link_on_issues_from_item(self)
|
||||
::Comment.create_link_on_issues_from_item(self)
|
||||
end
|
||||
|
||||
def send_assign_notifications(action = :create)
|
||||
|
@ -57,7 +57,7 @@ module Modules::Observers::ActivityFeed::Issue
|
|||
)
|
||||
end
|
||||
# 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
|
||||
|
||||
def send_hooks(action = :create)
|
|
@ -1,4 +1,4 @@
|
|||
module Modules::Observers::ActivityFeed::User
|
||||
module Feed::User
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
included do
|
||||
|
@ -8,10 +8,9 @@ module Modules::Observers::ActivityFeed::User
|
|||
private
|
||||
|
||||
def new_user_notification
|
||||
ActivityFeed.create(
|
||||
user: self,
|
||||
activity_feeds.create(
|
||||
kind: 'new_user_notification',
|
||||
data: {user_name: self.user_appeal, user_email: self.email}
|
||||
data: { user_name: user_appeal, user_email: email }
|
||||
)
|
||||
end
|
||||
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -1,7 +1,7 @@
|
|||
module Modules::Models::UrlHelper
|
||||
module UrlHelper
|
||||
def default_url_options
|
||||
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'
|
||||
{host: host, protocol: protocol}
|
||||
{ host: host, protocol: protocol }
|
||||
end
|
||||
end
|
|
@ -1,4 +1,4 @@
|
|||
module Modules::Models::WebHooks
|
||||
module WebHooks
|
||||
|
||||
class << self
|
||||
protected
|
||||
|
@ -45,10 +45,11 @@ module Modules::Models::WebHooks
|
|||
password :password
|
||||
boolean :ssl, :message_without_join, :no_colors, :long_url, :notice
|
||||
end
|
||||
|
||||
add_hook :jabber do
|
||||
string :user
|
||||
end
|
||||
|
||||
SCHEMA.freeze
|
||||
NAMES.freeze
|
||||
|
||||
end
|
|
@ -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
|
|
@ -4,14 +4,15 @@ class EventLog < ActiveRecord::Base
|
|||
|
||||
# self.per_page = 1
|
||||
|
||||
scope :eager_loading, preload(:user)
|
||||
scope :default_order, order("#{table_name}.id DESC") # order('created_at DESC')
|
||||
scope :eager_loading, -> { preload(:user) }
|
||||
scope :default_order, -> { order(id: :desc) }
|
||||
|
||||
before_create do
|
||||
self.user_name = user.try(:uname) || 'guest'
|
||||
self.eventable_name ||= eventable.name if eventable.respond_to?(:name)
|
||||
end
|
||||
# after_create { self.class.current_controller = nil }
|
||||
attr_accessible :kind, :message, :eventable, :eventable_name
|
||||
|
||||
class << self
|
||||
def create_with_current_controller(attributes)
|
||||
|
|
|
@ -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
|
|
@ -8,6 +8,8 @@ class Feedback
|
|||
include ActiveModel::MassAssignmentSecurity
|
||||
extend ActiveModel::Naming
|
||||
|
||||
self.include_root_in_json = false
|
||||
|
||||
attr_accessor :name, :email, :subject, :message
|
||||
|
||||
attr_accessible :name, :email, :subject, :message
|
||||
|
@ -99,6 +101,4 @@ class Feedback
|
|||
perform_validation = options[:validate] != false
|
||||
perform_validation ? valid?(options[:context]) : true
|
||||
end
|
||||
|
||||
end
|
||||
Feedback.include_root_in_json = false
|
||||
|
|
|
@ -8,7 +8,9 @@ class FlashNotify < ActiveRecord::Base
|
|||
validates :status, inclusion: {in: STATUSES}
|
||||
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
|
||||
@digest ||= Digest::MD5.hexdigest("#{self.id}-#{self.updated_at}")
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
class GitHook
|
||||
include Feed::Git
|
||||
include Resque::Plugins::Status
|
||||
|
||||
ZERO = '0000000000000000000000000000000000000000'
|
||||
@queue = :hook
|
||||
|
||||
attr_reader :repo, :newrev, :oldrev, :newrev_type, :oldrev_type, :refname,
|
||||
:change_type, :rev, :rev_type, :refname_type, :owner, :project, :user, :message
|
||||
|
||||
include Resque::Plugins::Status
|
||||
|
||||
def self.perform(*options)
|
||||
self.process(*options)
|
||||
end
|
||||
|
@ -64,19 +65,19 @@ class GitHook
|
|||
end
|
||||
|
||||
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
|
||||
|
||||
def find_user(user)
|
||||
if user.blank?
|
||||
# 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/
|
||||
# git push over http
|
||||
User.find(user.gsub('user-', ''))
|
||||
elsif user =~ /\Akey-\d+\Z/
|
||||
# git push over ssh
|
||||
SshKey.find_by_id(user.gsub('key-', '')).try(:user)
|
||||
SshKey.find(user.gsub('key-', '')).try(:user)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
class Group < Avatar
|
||||
include ActsLikeMember
|
||||
include PersonalRepository
|
||||
|
||||
belongs_to :owner, class_name: 'User'
|
||||
|
||||
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
|
||||
validate { errors.add(:uname, :taken) if User.by_uname(uname).present? }
|
||||
|
||||
scope :opened, where('1=1')
|
||||
scope :by_owner, lambda {|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_and_writer, lambda {|actor| joins(:actors).where(:'relations.role' => ['admin', 'writer'], :'relations.actor_id' => actor.id, :'relations.actor_type' => 'User')}
|
||||
scope :opened, -> { all }
|
||||
scope :by_owner, ->(owner) { where(owner_id: owner.id) }
|
||||
scope :by_admin, ->(admin) {
|
||||
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_readonly :uname
|
||||
|
@ -27,10 +34,6 @@ class Group < Avatar
|
|||
|
||||
after_create :add_owner_to_members
|
||||
|
||||
include Modules::Models::ActsLikeMember
|
||||
include Modules::Models::PersonalRepository
|
||||
# include Modules::Models::Owner
|
||||
|
||||
def self.can_own_project(user)
|
||||
(by_owner(user) | by_admin_and_writer(user))
|
||||
end
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
class Hook < ActiveRecord::Base
|
||||
include Modules::Models::WebHooks
|
||||
include Modules::Models::UrlHelper
|
||||
include WebHooks
|
||||
include UrlHelper
|
||||
include Rails.application.routes.url_helpers
|
||||
|
||||
belongs_to :project
|
||||
|
||||
before_validation :cleanup_data
|
||||
|
@ -12,7 +13,7 @@ class Hook < ActiveRecord::Base
|
|||
|
||||
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)
|
||||
pull = issue.pull_request
|
||||
|
@ -121,7 +122,7 @@ class Hook < ActiveRecord::Base
|
|||
def cleanup_data
|
||||
if self.name.present? && fields = SCHEMA[self.name.to_sym]
|
||||
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
|
||||
end
|
||||
end
|
||||
|
@ -140,7 +141,7 @@ class Hook < ActiveRecord::Base
|
|||
modified << diff.a_path
|
||||
end
|
||||
end
|
||||
{removed: removed, added: added, modified: modified}
|
||||
{ removed: removed, added: added, modified: modified }
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
class Issue < ActiveRecord::Base
|
||||
include Modules::Observers::ActivityFeed::Issue
|
||||
include Feed::Issue
|
||||
STATUSES = ['open', 'closed']
|
||||
|
||||
belongs_to :project
|
||||
|
@ -10,8 +10,8 @@ class Issue < ActiveRecord::Base
|
|||
has_many :comments, as: :commentable, dependent: :destroy
|
||||
has_many :subscribes, as: :subscribeable, dependent: :destroy
|
||||
has_many :labelings, dependent: :destroy
|
||||
has_many :labels, through: :labelings, uniq: true
|
||||
has_one :pull_request, dependent: :destroy
|
||||
has_many :labels, -> { uniq }, through: :labelings
|
||||
has_one :pull_request#, dependent: :destroy
|
||||
|
||||
validates :title, :body, :project_id, presence: true
|
||||
|
||||
|
@ -22,15 +22,17 @@ class Issue < ActiveRecord::Base
|
|||
attr_accessible :labelings_attributes, :title, :body, :assignee_id
|
||||
accepts_nested_attributes_for :labelings, allow_destroy: true
|
||||
|
||||
scope :opened, where(status: 'open')
|
||||
scope :closed, where(status: 'closed')
|
||||
scope :opened, -> { where(status: 'open') }
|
||||
scope :closed, -> { where(status: 'closed') }
|
||||
|
||||
scope :needed_checking, where(issues: {status: ['open', 'blocked', 'ready', 'already']})
|
||||
scope :not_closed_or_merged, needed_checking
|
||||
scope :closed_or_merged, where(issues: {status: ['closed', 'merged']})
|
||||
scope :needed_checking, -> { where(issues: {status: ['open', 'blocked', 'ready', 'already']}) }
|
||||
scope :not_closed_or_merged, -> { needed_checking }
|
||||
scope :closed_or_merged, -> { where(issues: {status: ['closed', 'merged']}) }
|
||||
# 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 :without_pull_requests, where('NOT EXISTS (select null from pull_requests as pr where pr.issue_id = issues.id)')
|
||||
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)')
|
||||
}
|
||||
|
||||
def assign_uname
|
||||
assignee.uname if assignee
|
||||
|
|
|
@ -9,7 +9,7 @@ class KeyPair < ActiveRecord::Base
|
|||
validates :repository_id, :user_id, presence: true
|
||||
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
|
||||
|
||||
before_create { |record| record.key_id = @fingerprint }
|
||||
|
|
|
@ -3,8 +3,8 @@ class Label < ActiveRecord::Base
|
|||
has_many :issues, through: :labelings
|
||||
belongs_to :project
|
||||
|
||||
validates :name, uniqueness: {scope: :project_id}
|
||||
validates :name, uniqueness: { scope: :project_id }
|
||||
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
|
||||
|
|
|
@ -2,4 +2,5 @@ class Labeling < ActiveRecord::Base
|
|||
belongs_to :issue
|
||||
belongs_to :label
|
||||
|
||||
attr_accessible :label_id
|
||||
end
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
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 :user
|
||||
has_many :build_lists, dependent: :destroy
|
||||
|
@ -7,9 +7,9 @@ class MassBuild < ActiveRecord::Base
|
|||
serialize :extra_repositories, Array
|
||||
serialize :extra_build_lists, Array
|
||||
|
||||
scope :recent, order("#{table_name}.created_at DESC")
|
||||
scope :by_platform, lambda { |platform| where(save_to_platform_id: platform.id) }
|
||||
scope :outdated, where("#{table_name}.created_at < ?", Time.now + 1.day - BuildList::MAX_LIVE_TIME)
|
||||
scope :recent, -> { order(created_at: :desc) }
|
||||
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) }
|
||||
|
||||
attr_accessor :arches
|
||||
attr_accessible :arches, :auto_publish, :projects_list, :build_for_platform_id,
|
||||
|
@ -41,7 +41,7 @@ class MassBuild < ActiveRecord::Base
|
|||
next if name.blank?
|
||||
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
|
||||
return if self.reload.stop_build
|
||||
increase_rt = increase_release_tag?
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
class Platform < ActiveRecord::Base
|
||||
extend FriendlyId
|
||||
friendly_id :name
|
||||
friendly_id :name, use: [:finders]
|
||||
|
||||
include Modules::Models::FileStoreClean
|
||||
include Modules::Models::RegenerationStatus
|
||||
include FileStoreClean
|
||||
include RegenerationStatus
|
||||
include Owner
|
||||
include EventLoggable
|
||||
|
||||
AUTOMATIC_METADATA_REGENERATIONS = %w(day week)
|
||||
VISIBILITIES = %w(open hidden)
|
||||
|
@ -30,16 +32,16 @@ class Platform < ActiveRecord::Base
|
|||
has_many :mass_builds, foreign_key: :save_to_platform_id
|
||||
|
||||
validates :description, presence: true
|
||||
validates :visibility, presence: true, inclusion: {in: VISIBILITIES}
|
||||
validates :automatic_metadata_regeneration, inclusion: {in: AUTOMATIC_METADATA_REGENERATIONS}, allow_blank: true
|
||||
validates :visibility, presence: true, inclusion: { in: VISIBILITIES }
|
||||
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 :distrib_type, presence: true, inclusion: {in: APP_CONFIG['distr_types']}
|
||||
validate lambda {
|
||||
validates :distrib_type, presence: true, inclusion: { in: APP_CONFIG['distr_types'] }
|
||||
validate -> {
|
||||
if released_was && !released
|
||||
errors.add(:released, I18n.t('flash.platform.released_status_can_not_be_changed'))
|
||||
end
|
||||
}
|
||||
validate lambda {
|
||||
validate -> {
|
||||
if personal? && (owner_id_changed? || owner_type_changed?)
|
||||
errors.add :owner, I18n.t('flash.platform.owner_can_not_be_changed')
|
||||
end
|
||||
|
@ -51,25 +53,23 @@ class Platform < ActiveRecord::Base
|
|||
after_update :freeze_platform_and_update_repos
|
||||
after_update :update_owner_relation
|
||||
|
||||
after_create lambda { symlink_directory unless hidden? }
|
||||
after_destroy lambda { remove_symlink_directory unless hidden? }
|
||||
after_create -> { symlink_directory unless hidden? }
|
||||
after_destroy -> { remove_symlink_directory unless hidden? }
|
||||
|
||||
scope :search_order, order("CHAR_LENGTH(#{table_name}.name) ASC")
|
||||
scope :search, lambda {|q| where("#{table_name}.name ILIKE ?", "%#{q.to_s.strip}%")}
|
||||
scope :by_visibilities, lambda {|v| where(visibility: v)}
|
||||
scope :opened, where(visibility: 'open')
|
||||
scope :hidden, where(visibility: 'hidden')
|
||||
scope :by_type, lambda {|type| where(platform_type: type) if type.present?}
|
||||
scope :main, by_type('main')
|
||||
scope :personal, by_type('personal')
|
||||
scope :waiting_for_regeneration, where(status: WAITING_FOR_REGENERATION)
|
||||
scope :search_order, -> { order(:name) }
|
||||
scope :search, ->(q) { where("#{table_name}.name ILIKE ?", "%#{q.to_s.strip}%") }
|
||||
scope :by_visibilities, ->(v) { where(visibility: v) }
|
||||
scope :opened, -> { where(visibility: 'open') }
|
||||
scope :hidden, -> { where(visibility: 'hidden') }
|
||||
scope :by_type, ->(type) { where(platform_type: type) if type.present? }
|
||||
scope :main, -> { by_type('main') }
|
||||
scope :personal, -> { by_type('personal') }
|
||||
scope :waiting_for_regeneration, -> { where(status: WAITING_FOR_REGENERATION) }
|
||||
|
||||
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_readonly :name, :distrib_type, :parent_platform_id, :platform_type
|
||||
|
||||
include Modules::Models::Owner
|
||||
|
||||
state_machine :status, initial: :ready do
|
||||
|
||||
after_transition on: :ready, do: :notify_users
|
||||
|
@ -79,7 +79,7 @@ class Platform < ActiveRecord::Base
|
|||
end
|
||||
|
||||
event :regenerate do
|
||||
transition ready: :waiting_for_regeneration, if: lambda{ |p| p.main? }
|
||||
transition ready: :waiting_for_regeneration, if: ->(p) { p.main? }
|
||||
end
|
||||
|
||||
event :start_regeneration do
|
||||
|
@ -223,13 +223,13 @@ class Platform < ActiveRecord::Base
|
|||
end
|
||||
|
||||
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 true unless platform.hidden?
|
||||
next false unless token
|
||||
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)
|
||||
if user && current_ability.can?(:show, platform)
|
||||
true
|
||||
|
|
|
@ -2,21 +2,19 @@ class PlatformArchSetting < ActiveRecord::Base
|
|||
DEFAULT_TIME_LIVING = 43200 # seconds, 12 hours
|
||||
MIN_TIME_LIVING = 600 # seconds, 10 minutes
|
||||
MAX_TIME_LIVING = 360000 # seconds, 100 hours, 4 day and 4 hours
|
||||
include Modules::Models::TimeLiving
|
||||
include TimeLiving
|
||||
|
||||
belongs_to :arch
|
||||
belongs_to :platform
|
||||
|
||||
validates :arch_id, :platform_id, presence: true
|
||||
validates :platform_id, :uniqueness => {scope: :arch_id}
|
||||
validates :platform_id, uniqueness: { scope: :arch_id }
|
||||
validate lambda {
|
||||
errors.add(:platform, I18n.t('flash.platform_arch_settings.wrong_platform')) unless platform.main?
|
||||
}
|
||||
|
||||
|
||||
scope :by_arch, lambda {|arch| where(arch_id: arch) if arch.present?}
|
||||
scope :by_default, where(default: true)
|
||||
scope :by_arch, ->(arch) { where(arch_id: arch) if arch.present? }
|
||||
scope :by_default, -> { where(default: true) }
|
||||
|
||||
attr_accessible :arch_id, :platform_id, :default
|
||||
|
||||
end
|
||||
|
|
|
@ -1,15 +1,7 @@
|
|||
class PlatformContent
|
||||
|
||||
# ------------------
|
||||
# *** ATTRIBUTES ***
|
||||
# ------------------
|
||||
|
||||
attr_reader :path
|
||||
|
||||
# ---------------
|
||||
# *** METHODS ***
|
||||
# ---------------
|
||||
|
||||
def initialize(platform, path)
|
||||
@platform, @path = platform, path
|
||||
end
|
||||
|
@ -29,7 +21,7 @@ class PlatformContent
|
|||
bfp_name = @path.match(/\/#{@platform.name}\/repository\/[\w]+\//)
|
||||
return nil unless bfp_name
|
||||
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
|
||||
end
|
||||
|
||||
|
@ -61,10 +53,6 @@ class PlatformContent
|
|||
"#{APP_CONFIG['downloads_url']}/#{@platform.name}#{suffix}"
|
||||
end
|
||||
|
||||
# ---------------------
|
||||
# *** CLASS METHODS ***
|
||||
# ---------------------
|
||||
|
||||
def self.find_by_platform(platform, path, term)
|
||||
# Strip out the non-ascii character
|
||||
term = (term || '').strip.gsub(/[\\\/]+/, '')
|
||||
|
|
|
@ -1,16 +1,17 @@
|
|||
class Product < ActiveRecord::Base
|
||||
include Modules::Models::TimeLiving
|
||||
include Modules::Models::Autostart
|
||||
include TimeLiving
|
||||
include Autostart
|
||||
include EventLoggable
|
||||
|
||||
belongs_to :platform
|
||||
belongs_to :project
|
||||
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 :main_script, :params, length: { maximum: 255 }
|
||||
|
||||
scope :recent, order("#{table_name}.name ASC")
|
||||
scope :recent, -> { order(:name) }
|
||||
|
||||
attr_accessible :name,
|
||||
:description,
|
||||
|
@ -24,7 +25,7 @@ class Product < ActiveRecord::Base
|
|||
def full_clone(attrs = {})
|
||||
dup.tap do |c|
|
||||
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.product_build_lists = []
|
||||
c.updated_at = nil; c.created_at = nil
|
||||
|
@ -32,7 +33,7 @@ class Product < ActiveRecord::Base
|
|||
end
|
||||
|
||||
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
|
||||
autostart_iso_builds autostart_status
|
||||
end
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
class ProductBuildList < ActiveRecord::Base
|
||||
include Modules::Models::CommitAndVersion
|
||||
include Modules::Models::TimeLiving
|
||||
include Modules::Models::FileStoreClean
|
||||
include Modules::Models::UrlHelper
|
||||
include CommitAndVersion
|
||||
include TimeLiving
|
||||
include FileStoreClean
|
||||
include UrlHelper
|
||||
include AbfWorker::ModelHelper
|
||||
include EventLoggable
|
||||
|
||||
delegate :url_helpers, to: 'Rails.application.routes'
|
||||
|
||||
LIVE_TIME = 2.week # for autostart
|
||||
|
@ -38,9 +40,9 @@ class ProductBuildList < ActiveRecord::Base
|
|||
belongs_to :user
|
||||
|
||||
# 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
|
||||
before_validation lambda { self.not_delete = false unless build_completed?; true }
|
||||
before_validation -> { self.not_delete = false unless build_completed?; true }
|
||||
validates :product_id,
|
||||
:status,
|
||||
:project_id,
|
||||
|
@ -64,13 +66,16 @@ class ProductBuildList < ActiveRecord::Base
|
|||
serialize :results, Array
|
||||
|
||||
|
||||
scope :default_order, order("#{table_name}.updated_at DESC")
|
||||
scope :for_status, lambda {|status| where(status: status) }
|
||||
scope :for_user, lambda { |user| where(user_id: user.id) }
|
||||
scope :scoped_to_product_name, lambda {|product_name| joins(:product).where('products.name LIKE ?', "%#{product_name}%")}
|
||||
scope :recent, order("#{table_name}.updated_at DESC")
|
||||
scope :outdated, 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)
|
||||
scope :default_order, -> { order(updated_at: :desc) }
|
||||
scope :for_status, ->(status) { where(status: status) }
|
||||
scope :for_user, ->(user) { where(user_id: user.id) }
|
||||
scope :scoped_to_product_name, ->(product_name) { joins(:product).where('products.name LIKE ?', "%#{product_name}%") }
|
||||
scope :recent, -> { order(updated_at: :desc) }
|
||||
scope :outdated, -> {
|
||||
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
|
||||
before_destroy :can_destroy?
|
||||
|
@ -154,8 +159,7 @@ class ProductBuildList < ActiveRecord::Base
|
|||
opts = default_url_options
|
||||
opts.merge!({user: user.authentication_token, password: ''}) if user.present?
|
||||
srcpath = url_helpers.archive_url(
|
||||
project.owner,
|
||||
project.name,
|
||||
project.name_with_owner,
|
||||
file_name,
|
||||
'tar.gz',
|
||||
opts
|
||||
|
|
|
@ -1,12 +1,20 @@
|
|||
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']
|
||||
MAX_OWN_PROJECTS = 32000
|
||||
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 :maintainer, class_name: "User"
|
||||
belongs_to :maintainer, class_name: 'User'
|
||||
|
||||
has_many :issues, dependent: :destroy
|
||||
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 :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
|
||||
|
||||
validates :name, uniqueness: {scope: [:owner_id, :owner_type], case_sensitive: false},
|
||||
validates :name, uniqueness: { scope: [:owner_id, :owner_type], case_sensitive: false },
|
||||
presence: true,
|
||||
format: {with: /\A#{NAME_REGEXP}\z/,
|
||||
message: I18n.t("activerecord.errors.project.uname")}
|
||||
format: { with: /\A#{NAME_REGEXP.source}\z/,
|
||||
message: I18n.t("activerecord.errors.project.uname") }
|
||||
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 :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 :check_default_branch
|
||||
# throws validation error message from ProjectToRepository model into Project model
|
||||
|
@ -53,57 +61,50 @@ class Project < ActiveRecord::Base
|
|||
:autostart_status
|
||||
attr_readonly :owner_id, :owner_type
|
||||
|
||||
scope :recent, order("lower(#{table_name}.name) ASC")
|
||||
scope :search_order, order("CHAR_LENGTH(#{table_name}.name) ASC")
|
||||
scope :search, lambda {|q|
|
||||
scope :recent, -> { order(:name) }
|
||||
scope :search_order, -> { order('CHAR_LENGTH(projects.name) ASC') }
|
||||
scope :search, ->(q) {
|
||||
q = q.to_s.strip
|
||||
by_name("%#{q}%").search_order if q.present?
|
||||
}
|
||||
scope :by_name, lambda {|name| where("#{table_name}.name ILIKE ?", name) if name.present?}
|
||||
scope :by_owner_and_name, lambda { |*params|
|
||||
scope :by_name, ->(name) { where('projects.name ILIKE ?', name) if name.present? }
|
||||
scope :by_owner_and_name, ->(*params) {
|
||||
term = params.map(&:strip).join('/').downcase
|
||||
where("lower(concat(owner_uname, '/', name)) ILIKE ?", "%#{term}%") if term.present?
|
||||
}
|
||||
scope :by_visibilities, lambda {|v| where(visibility: v)}
|
||||
scope :opened, where(visibility: 'open')
|
||||
scope :package, where(is_package: true)
|
||||
scope :addable_to_repository, lambda { |repository_id| where %Q(
|
||||
projects.id NOT IN (
|
||||
SELECT
|
||||
ptr.project_id
|
||||
FROM
|
||||
project_to_repositories AS ptr
|
||||
WHERE (ptr.repository_id = #{ repository_id })
|
||||
)
|
||||
) }
|
||||
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)
|
||||
scope :by_visibilities, ->(v) { where(visibility: v) }
|
||||
scope :opened, -> { where(visibility: 'open') }
|
||||
scope :package, -> { where(is_package: true) }
|
||||
scope :addable_to_repository, ->(repository_id) {
|
||||
where('projects.id NOT IN (
|
||||
SELECT ptr.project_id
|
||||
FROM 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)
|
||||
}
|
||||
|
||||
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
|
||||
after_save :attach_to_personal_repository
|
||||
after_update :set_new_git_head
|
||||
after_update lambda { update_path_to_project(name_was) }, if: :name_changed?
|
||||
|
||||
has_ancestry orphan_strategy: :rootify #:adopt not available yet
|
||||
after_update -> { update_path_to_project(name_was) }, if: :name_changed?
|
||||
|
||||
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
|
||||
def find_by_owner_and_name(owner_name, project_name)
|
||||
where(owner_uname: owner_name, name: project_name).first ||
|
||||
by_owner_and_name(owner_name, project_name).first
|
||||
def find_by_owner_and_name(first, last = nil)
|
||||
arr = first.try(:split, '/') || []
|
||||
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
|
||||
|
||||
def find_by_owner_and_name!(owner_name, project_name)
|
||||
find_by_owner_and_name(owner_name, project_name) or raise ActiveRecord::RecordNotFound
|
||||
def find_by_owner_and_name!(first, last = nil)
|
||||
find_by_owner_and_name(first, last) or raise ActiveRecord::RecordNotFound
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -116,15 +117,15 @@ class Project < ActiveRecord::Base
|
|||
end
|
||||
|
||||
def to_param
|
||||
name
|
||||
name_with_owner
|
||||
end
|
||||
|
||||
def all_members
|
||||
members | (owner_type == 'User' ? [owner] : owner.members)
|
||||
def all_members(*includes)
|
||||
members(includes) | (owner_type == 'User' ? [owner] : owner.members.includes(includes))
|
||||
end
|
||||
|
||||
def members
|
||||
collaborators | groups.map(&:members).flatten
|
||||
def members(*includes)
|
||||
collaborators.includes(includes) | groups.map{ |g| g.members.includes(includes) }.flatten
|
||||
end
|
||||
|
||||
def add_member(member, role = 'admin')
|
||||
|
@ -160,11 +161,11 @@ class Project < ActiveRecord::Base
|
|||
def git_project_address auth_user
|
||||
opts = default_url_options
|
||||
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
|
||||
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
|
||||
save_to_platform = mass_build.save_to_platform
|
||||
user = mass_build.user
|
||||
|
@ -239,12 +240,12 @@ class Project < ActiveRecord::Base
|
|||
format_id = ProjectTag::FORMATS["#{tag_file_format(format)}"]
|
||||
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
|
||||
sha1 = Digest::SHA1.file(archive[:path]).hexdigest
|
||||
unless Modules::Models::FileStoreClean.file_exist_on_file_store? sha1
|
||||
token = User.find_by_uname('rosa_system').authentication_token
|
||||
unless FileStoreClean.file_exist_on_file_store? sha1
|
||||
token = User.find_by(uname: 'rosa_system').authentication_token
|
||||
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`
|
||||
rescue # Dont care about it
|
||||
|
@ -298,7 +299,7 @@ class Project < ActiveRecord::Base
|
|||
end
|
||||
|
||||
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
|
||||
autostart_build_lists autostart_status
|
||||
end
|
||||
|
|
|
@ -2,10 +2,10 @@ class ProjectImport < ActiveRecord::Base
|
|||
belongs_to :project
|
||||
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
|
||||
|
||||
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
|
||||
|
|
|
@ -4,7 +4,7 @@ class ProjectStatistic < ActiveRecord::Base
|
|||
belongs_to :project
|
||||
|
||||
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
|
||||
end
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
class ProjectTag < ActiveRecord::Base
|
||||
include Modules::Models::FileStoreClean
|
||||
include FileStoreClean
|
||||
|
||||
FORMATS = {
|
||||
'zip' => 0,
|
||||
|
@ -9,16 +9,11 @@ class ProjectTag < ActiveRecord::Base
|
|||
belongs_to :project
|
||||
|
||||
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,
|
||||
:commit_id,
|
||||
:sha1,
|
||||
:tag_name,
|
||||
:format_id
|
||||
attr_accessible :project_id, :commit_id, :sha1, :tag_name, :format_id
|
||||
|
||||
def sha1_of_file_store_files
|
||||
[sha1]
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -6,13 +6,14 @@ class ProjectToRepository < ActiveRecord::Base
|
|||
|
||||
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
|
||||
|
||||
serialize :autostart_options, ActiveRecord::Coders::Hstore
|
||||
attr_accessible :project, :project_id
|
||||
|
||||
AUTOSTART_OPTIONS.each do |field|
|
||||
store_accessor :autostart_options, field
|
||||
end
|
||||
|
@ -28,7 +29,8 @@ class ProjectToRepository < ActiveRecord::Base
|
|||
protected
|
||||
|
||||
def one_project_in_platform_repositories
|
||||
errors.add(:base, I18n.t('activerecord.errors.project_to_repository.project')) if Project.joins(repositories: :platform).
|
||||
where('platforms.id = ?', repository.platform_id).by_name(project.name).exists?
|
||||
if Project.joins(repositories: :platform).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
|
||||
|
|
|
@ -7,7 +7,7 @@ class PullRequest < ActiveRecord::Base
|
|||
:created_at, :updated_at, :comments, :status=, to: :issue, allow_nil: 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|
|
||||
check_ref record, attr, value
|
||||
end
|
||||
|
@ -19,9 +19,9 @@ class PullRequest < ActiveRecord::Base
|
|||
accepts_nested_attributes_for :issue
|
||||
attr_accessible :issue_attributes, :to_ref, :from_ref
|
||||
|
||||
scope :needed_checking, includes(:issue).where(issues: {status: ['open', 'blocked', 'ready']})
|
||||
scope :not_closed_or_merged, needed_checking
|
||||
scope :closed_or_merged, where(issues: {status: ['closed', 'merged']})
|
||||
scope :needed_checking, -> { includes(:issue).where(issues: {status: ['open', 'blocked', 'ready']}) }
|
||||
scope :not_closed_or_merged, -> { needed_checking }
|
||||
scope :closed_or_merged, -> { where(issues: {status: ['closed', 'merged']}) }
|
||||
|
||||
state_machine :status, initial: :open do
|
||||
event :ready do
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
class RegisterRequest < ActiveRecord::Base
|
||||
|
||||
default_scope order('created_at ASC')
|
||||
default_scope { order(:created_at) }
|
||||
|
||||
scope :rejected, where(rejected: true)
|
||||
scope :approved, where(approved: true)
|
||||
scope :unprocessed, where(approved: false, rejected: false)
|
||||
scope :rejected, -> { where(rejected: true) }
|
||||
scope :approved, -> { where(approved: true) }
|
||||
scope :unprocessed, -> { where(approved: false, rejected: false) }
|
||||
|
||||
validates :email, presence: true, uniqueness: {case_sensitive: false}, format: { with: /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i }
|
||||
validates :email, presence: true, uniqueness: {case_sensitive: false},
|
||||
format: { with: /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i }
|
||||
|
||||
# before_create :generate_token
|
||||
before_update :invite_approve_notification
|
||||
|
|
|
@ -1,17 +1,22 @@
|
|||
class Relation < ActiveRecord::Base
|
||||
ROLES = %w[reader writer admin]
|
||||
|
||||
belongs_to :target, polymorphic: 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? }
|
||||
before_validation :add_default_role
|
||||
|
||||
scope :by_user_through_groups, lambda {|u| where("actor_type = 'User' AND actor_id = ? OR actor_type = 'Group' AND actor_id IN (?)", u.id, u.group_ids)}
|
||||
scope :by_actor, lambda {|obj| where(actor_id: obj.id, actor_type: obj.class.to_s)}
|
||||
scope :by_target, lambda {|tar| where(target_id: tar.id, target_type: tar.class.to_s)}
|
||||
scope :by_role, lambda {|role| where(role: role)}
|
||||
attr_accessible :actor_id, :actor_type, :target_id, :target_type, :actor, :target, :role
|
||||
|
||||
scope :by_user_through_groups, ->(u) {
|
||||
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)
|
||||
r = self.new
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
class Repository < ActiveRecord::Base
|
||||
extend FriendlyId
|
||||
friendly_id :name
|
||||
friendly_id :name, use: [:finders]
|
||||
|
||||
LOCK_FILE_NAMES = {sync: '.sync.lock', repo: '.repo.lock'}
|
||||
SORT = {'base' => 1, 'main' => 2, 'contrib' => 3, 'non-free' => 4, 'restricted' => 5}
|
||||
include EventLoggable
|
||||
|
||||
LOCK_FILE_NAMES = { sync: '.sync.lock', repo: '.repo.lock' }
|
||||
SORT = { 'base' => 1, 'main' => 2, 'contrib' => 3, 'non-free' => 4, 'restricted' => 5 }
|
||||
|
||||
belongs_to :platform
|
||||
|
||||
|
@ -19,10 +21,11 @@ class Repository < ActiveRecord::Base
|
|||
has_many :build_lists, foreign_key: :save_to_repository_id, dependent: :destroy
|
||||
|
||||
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 :main, lambda { where(name: %w(main base)) }
|
||||
scope :recent, -> { order(:name) }
|
||||
scope :main, -> { where(name: %w(main base)) }
|
||||
|
||||
before_destroy :detele_directory
|
||||
|
||||
|
@ -32,13 +35,13 @@ class Repository < ActiveRecord::Base
|
|||
|
||||
def regenerate(build_for_platform_id = nil)
|
||||
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
|
||||
end
|
||||
|
||||
def resign
|
||||
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
|
||||
end
|
||||
end
|
||||
|
@ -79,7 +82,7 @@ class Repository < ActiveRecord::Base
|
|||
begin
|
||||
name.chomp!; name.strip!
|
||||
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
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
class RepositoryStatus < ActiveRecord::Base
|
||||
include Modules::Models::FileStoreClean
|
||||
include Modules::Models::RegenerationStatus
|
||||
include FileStoreClean
|
||||
include RegenerationStatus
|
||||
|
||||
WAITING_FOR_RESIGN = 300
|
||||
PUBLISH = 400
|
||||
|
@ -29,14 +29,14 @@ class RepositoryStatus < ActiveRecord::Base
|
|||
belongs_to :repository
|
||||
|
||||
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
|
||||
|
||||
scope :platform_ready, where(platforms: {status: READY}).joins(:platform)
|
||||
scope :for_regeneration, where(status: WAITING_FOR_REGENERATION)
|
||||
scope :for_resign, where(status: [WAITING_FOR_RESIGN, WAITING_FOR_RESIGN_AND_REGENERATION])
|
||||
scope :not_ready, where('repository_statuses.status != ?', READY)
|
||||
scope :platform_ready, -> { where(platforms: {status: READY}).joins(:platform) }
|
||||
scope :for_regeneration, -> { where(status: WAITING_FOR_REGENERATION) }
|
||||
scope :for_resign, -> { where(status: [WAITING_FOR_RESIGN, WAITING_FOR_RESIGN_AND_REGENERATION]) }
|
||||
scope :not_ready, -> { where('repository_statuses.status != ?', READY) }
|
||||
|
||||
state_machine :status, initial: :ready do
|
||||
event :ready do
|
||||
|
@ -80,5 +80,4 @@ class RepositoryStatus < ActiveRecord::Base
|
|||
state name, value: code
|
||||
end
|
||||
end
|
||||
|
||||
end
|
|
@ -29,5 +29,4 @@ class RpmBuildNode < Ohm::Model
|
|||
end
|
||||
{ systems: systems, others: others, busy: busy }
|
||||
end
|
||||
|
||||
end
|
|
@ -2,4 +2,17 @@ class SettingsNotifier < ActiveRecord::Base
|
|||
belongs_to :user
|
||||
|
||||
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
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue