mirror of
https://github.com/wahyd4/gitlabhq.git
synced 2026-08-16 16:16:43 +10:00
Merge branch '6-4-stable' of dev.gitlab.org:gitlab/gitlabhq into 6-4-from-ce
Signed-off-by: Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com> Conflicts: Gemfile Gemfile.lock VERSION app/controllers/application_controller.rb db/schema.rb doc/install/installation.md doc/update/6.2-to-6.3.md
This commit is contained in:
@@ -16,9 +16,12 @@ rvm:
|
||||
- 2.0.0
|
||||
services:
|
||||
- mysql
|
||||
- redis-server
|
||||
before_script:
|
||||
- "cp config/database.yml.$DB config/database.yml"
|
||||
- "cp config/gitlab.yml.example config/gitlab.yml"
|
||||
- "bundle exec rake db:setup"
|
||||
- "bundle exec rake db:seed_fu"
|
||||
script: "bundle exec rake $TASK --trace"
|
||||
notifications:
|
||||
email: false
|
||||
|
||||
@@ -1,3 +1,29 @@
|
||||
v 6.4.0
|
||||
- Added sorting to project issues page (Jason Blanchard)
|
||||
- Assembla integration (Carlos Paramio)
|
||||
- Fixed another 500 error with submodules
|
||||
- UI: More compact issues page
|
||||
- Minimal password length increased to 8 symbols
|
||||
- Side-by-side diff view (Steven Thonus)
|
||||
- Internal projects (Jason Hollingsworth)
|
||||
- Allow removal of avatar (Drew Blessing)
|
||||
- Project web hooks now support issues and merge request events
|
||||
- Visiting project page while not logged in will redirect to sign-in instead of 404 (Jason Hollingsworth)
|
||||
- Expire event cache on avatar creation/removal (Drew Blessing)
|
||||
- Archiving old projects (Steven Thonus)
|
||||
- Rails 4
|
||||
- Add time ago tooltips to show actual date/time
|
||||
- UI: Fixed UI for admin system hooks
|
||||
- Ruby script for easier GitLab upgrade
|
||||
- Do not remove Merge requests if fork project was removed
|
||||
- Improve sign-in/signup UX
|
||||
- Add resend confirmation link to sign-in page
|
||||
- Set noreply@HOSTNAME for reply_to field in all emails
|
||||
- Show GitLab API version on Admin#dashboard
|
||||
- API Cross-origin resource sharing
|
||||
- Show READMe link at project home page
|
||||
- Show repo size for projects in Admin area
|
||||
|
||||
v 6.3.0
|
||||
- API for adding gitlab-ci service
|
||||
- Init script now waits for pids to appear after (re)starting before reporting status (Rovanion Luckey)
|
||||
@@ -58,7 +84,7 @@ v 6.2.0
|
||||
- Avatar upload on profile page with a maximum of 100KB (Steven Thonus)
|
||||
- Store the sessions in Redis instead of the cookie store
|
||||
- Fixed relative links in markdown
|
||||
- User must confirm his email if signup enabled
|
||||
- User must confirm their email if signup enabled
|
||||
- User must confirm changed email
|
||||
|
||||
v 6.1.0
|
||||
@@ -80,7 +106,7 @@ v 6.1.0
|
||||
- Add links to create branch/tag from project home page
|
||||
- Add public-project? checkbox to new-project view
|
||||
- Improved compare page. Added link to proceed into Merge Request
|
||||
- Send email to user when he was added to group
|
||||
- Send an email to a user when they are added to group
|
||||
- New landing page when you have 0 projects
|
||||
|
||||
v 6.0.0
|
||||
|
||||
+7
-4
@@ -65,8 +65,13 @@ If you can, please submit a pull request with the fix or improvements including
|
||||
1. Add your changes to the [CHANGELOG](CHANGELOG)
|
||||
1. If you have multiple commits please combine them into one commit by [squashing them](http://git-scm.com/book/en/Git-Tools-Rewriting-History#Squashing-Commits)
|
||||
1. Push the commit to your fork
|
||||
1. Submit a pull request
|
||||
2. [Search for issues](https://github.com/gitlabhq/gitlabhq/search?q=&ref=cmdform&type=Issues) related to your pull request and mention them in the pull request description
|
||||
1. Submit a pull request (PR)
|
||||
1. The PR title should describes the change you want to make
|
||||
1. The PR description should give a motive for your change and the method you used to achieve it
|
||||
* If the PR changes the UI it should include before and after screenshots
|
||||
1. [Search for issues](https://github.com/gitlabhq/gitlabhq/search?q=&ref=cmdform&type=Issues) related to your pull request and mention them in the pull request description
|
||||
|
||||
Please keep the change in a single PR as small as possible. If you want to contribute a large feature think very hard what the minimum viable change is. Can you split functionality? Can you only submit the backend/API code? Can you start with a very simple UI? The smaller a PR is the more likely it is it will be merged, after that you can send more PR's to enhance it.
|
||||
|
||||
We will accept pull requests if:
|
||||
|
||||
@@ -74,11 +79,9 @@ We will accept pull requests if:
|
||||
* It can be merged without problems (if not please use: `git rebase master`)
|
||||
* It does not break any existing functionality
|
||||
* It's quality code that conforms to the [Ruby](https://github.com/bbatsov/ruby-style-guide) and [Rails](https://github.com/bbatsov/rails-style-guide) style guides and best practices
|
||||
* The description includes a motive for your change and the method you used to achieve it
|
||||
* It is not a catch all pull request but rather fixes a specific issue or implements a specific feature
|
||||
* It keeps the GitLab code base clean and well structured
|
||||
* We think other users will benefit from the same functionality
|
||||
* If it makes changes to the UI the pull request should include screenshots
|
||||
* It is a single commit (please use `git rebase -i` to squash commits)
|
||||
|
||||
For examples of feedback on pull requests please look at already [closed pull requests](https://github.com/gitlabhq/gitlabhq/pulls?direction=desc&page=1&sort=created&state=closed).
|
||||
|
||||
@@ -8,15 +8,21 @@ def linux_only(require_as)
|
||||
RUBY_PLATFORM.include?('linux') && require_as
|
||||
end
|
||||
|
||||
gem "rails", "3.2.16"
|
||||
gem "rails", "~> 4.0.0"
|
||||
|
||||
gem "protected_attributes"
|
||||
gem 'rails-observers'
|
||||
gem 'actionpack-page_caching'
|
||||
gem 'actionpack-action_caching'
|
||||
gem 'activerecord-deprecated_finders'
|
||||
|
||||
# Supported DBs
|
||||
gem "mysql2", group: :mysql
|
||||
gem "pg", group: :postgres
|
||||
|
||||
# Auth
|
||||
gem "devise", '~> 2.2'
|
||||
gem "devise-async"
|
||||
gem "devise", '3.0.4'
|
||||
gem "devise-async", '0.8.0'
|
||||
gem 'omniauth', "~> 1.1.3"
|
||||
gem 'omniauth-google-oauth2'
|
||||
gem 'omniauth-twitter'
|
||||
@@ -24,27 +30,28 @@ gem 'omniauth-github'
|
||||
|
||||
# Extracting information from a git repository
|
||||
# Provide access to Gitlab::Git library
|
||||
gem "gitlab_git", "~> 3.0.0.rc2"
|
||||
gem "gitlab_git", "~> 4.0.0.pre"
|
||||
|
||||
# Ruby/Rack Git Smart-HTTP Server Handler
|
||||
gem 'gitlab-grack', '~> 1.0.1', require: 'grack'
|
||||
gem 'gitlab-grack', '~> 2.0.0.pre', require: 'grack'
|
||||
|
||||
# LDAP Auth
|
||||
gem 'gitlab_omniauth-ldap', '1.0.3', require: "omniauth-ldap"
|
||||
gem 'net-ldap'
|
||||
|
||||
# Syntax highlighter
|
||||
gem "gitlab-pygments.rb", '~> 0.3.2', require: 'pygments.rb'
|
||||
gem "gitlab-pygments.rb", '~> 0.5.4', require: 'pygments.rb'
|
||||
|
||||
# Git Wiki
|
||||
gem "gitlab-gollum-lib", "~> 1.0.1", require: 'gollum-lib'
|
||||
gem "gitlab-gollum-lib", "~> 1.0.2", require: 'gollum-lib'
|
||||
|
||||
# Language detection
|
||||
gem "github-linguist", require: "linguist"
|
||||
gem "gitlab-linguist", "~> 2.9.6", require: "linguist"
|
||||
|
||||
# API
|
||||
gem "grape", "~> 0.4.1"
|
||||
gem "grape", "~> 0.6.1"
|
||||
gem "grape-entity", "~> 0.3.0"
|
||||
gem 'rack-cors', require: 'rack/cors'
|
||||
|
||||
# Format dates and times
|
||||
# based on human-friendly examples
|
||||
@@ -79,7 +86,10 @@ gem "github-markup", "~> 0.7.4", require: 'github/markup'
|
||||
gem "asciidoctor"
|
||||
|
||||
# Application server
|
||||
gem "unicorn", '~> 4.6.3', group: :unicorn
|
||||
group :unicorn do
|
||||
gem "unicorn", '~> 4.6.3'
|
||||
gem 'unicorn-worker-killer'
|
||||
end
|
||||
|
||||
# State machine
|
||||
gem "state_machine"
|
||||
@@ -128,26 +138,24 @@ gem "sanitize"
|
||||
# Protect against bruteforcing
|
||||
gem "rack-attack"
|
||||
|
||||
group :assets do
|
||||
gem "sass-rails"
|
||||
gem "coffee-rails"
|
||||
gem "uglifier"
|
||||
gem "therubyracer"
|
||||
gem 'turbolinks'
|
||||
gem 'jquery-turbolinks'
|
||||
gem "sass-rails"
|
||||
gem "coffee-rails"
|
||||
gem "uglifier"
|
||||
gem "therubyracer"
|
||||
gem 'turbolinks'
|
||||
gem 'jquery-turbolinks'
|
||||
|
||||
gem 'chosen-rails', "1.0.0"
|
||||
gem 'select2-rails'
|
||||
gem 'jquery-atwho-rails', "0.3.0"
|
||||
gem "jquery-rails", "2.1.3"
|
||||
gem "jquery-ui-rails", "2.0.2"
|
||||
gem "modernizr", "2.6.2"
|
||||
gem "raphael-rails", "~> 2.1.2"
|
||||
gem 'bootstrap-sass'
|
||||
gem "font-awesome-rails"
|
||||
gem "gemoji", "~> 1.2.1", require: 'emoji/railtie'
|
||||
gem "gon"
|
||||
end
|
||||
gem 'chosen-rails', "1.0.1"
|
||||
gem 'select2-rails'
|
||||
gem 'jquery-atwho-rails', "~> 0.3.3"
|
||||
gem "jquery-rails", "2.1.3"
|
||||
gem "jquery-ui-rails", "2.0.2"
|
||||
gem "modernizr", "2.6.2"
|
||||
gem "raphael-rails", "~> 2.1.2"
|
||||
gem 'bootstrap-sass', '~> 2.3'
|
||||
gem "font-awesome-rails", '~> 3.2'
|
||||
gem "gemoji", "~> 1.3.0"
|
||||
gem "gon", git: "https://github.com/gitlabhq/gon.git", ref: '58ca8e17273051cb370182cabd3602d1da6783ab'
|
||||
|
||||
group :development do
|
||||
gem "annotate", "~> 2.6.0.beta2"
|
||||
@@ -170,7 +178,7 @@ end
|
||||
|
||||
group :development, :test do
|
||||
gem 'coveralls', require: false
|
||||
gem 'rails-dev-tweaks'
|
||||
# gem 'rails-dev-tweaks'
|
||||
gem 'spinach-rails'
|
||||
gem "rspec-rails"
|
||||
gem "capybara"
|
||||
@@ -199,7 +207,7 @@ group :development, :test do
|
||||
gem 'poltergeist', '~> 1.4.1'
|
||||
|
||||
gem 'spork', '~> 1.0rc'
|
||||
gem 'jasmine'
|
||||
gem 'jasmine', '2.0.0.rc5'
|
||||
end
|
||||
|
||||
group :test do
|
||||
|
||||
+276
-260
@@ -1,44 +1,57 @@
|
||||
GIT
|
||||
remote: https://github.com/gitlabhq/gon.git
|
||||
revision: 58ca8e17273051cb370182cabd3602d1da6783ab
|
||||
ref: 58ca8e17273051cb370182cabd3602d1da6783ab
|
||||
specs:
|
||||
gon (4.1.1)
|
||||
actionpack (>= 2.3.0)
|
||||
json
|
||||
|
||||
GEM
|
||||
remote: https://rubygems.org/
|
||||
specs:
|
||||
actionmailer (3.2.16)
|
||||
actionpack (= 3.2.16)
|
||||
actionmailer (4.0.2)
|
||||
actionpack (= 4.0.2)
|
||||
mail (~> 2.5.4)
|
||||
actionpack (3.2.16)
|
||||
activemodel (= 3.2.16)
|
||||
activesupport (= 3.2.16)
|
||||
builder (~> 3.0.0)
|
||||
actionpack (4.0.2)
|
||||
activesupport (= 4.0.2)
|
||||
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.16)
|
||||
activesupport (= 3.2.16)
|
||||
builder (~> 3.0.0)
|
||||
activerecord (3.2.16)
|
||||
activemodel (= 3.2.16)
|
||||
activesupport (= 3.2.16)
|
||||
arel (~> 3.0.2)
|
||||
tzinfo (~> 0.3.29)
|
||||
activeresource (3.2.16)
|
||||
activemodel (= 3.2.16)
|
||||
activesupport (= 3.2.16)
|
||||
activesupport (3.2.16)
|
||||
rack (~> 1.5.2)
|
||||
rack-test (~> 0.6.2)
|
||||
actionpack-action_caching (1.1.0)
|
||||
actionpack (>= 4.0.0, < 5.0)
|
||||
actionpack-page_caching (1.0.2)
|
||||
actionpack (>= 4.0.0, < 5)
|
||||
activemodel (4.0.2)
|
||||
activesupport (= 4.0.2)
|
||||
builder (~> 3.1.0)
|
||||
activerecord (4.0.2)
|
||||
activemodel (= 4.0.2)
|
||||
activerecord-deprecated_finders (~> 1.0.2)
|
||||
activesupport (= 4.0.2)
|
||||
arel (~> 4.0.0)
|
||||
activerecord-deprecated_finders (1.0.3)
|
||||
activesupport (4.0.2)
|
||||
i18n (~> 0.6, >= 0.6.4)
|
||||
multi_json (~> 1.0)
|
||||
minitest (~> 4.2)
|
||||
multi_json (~> 1.3)
|
||||
thread_safe (~> 0.1)
|
||||
tzinfo (~> 0.3.37)
|
||||
acts-as-taggable-on (2.4.1)
|
||||
rails (>= 3, < 5)
|
||||
addressable (2.3.4)
|
||||
annotate (2.6.0.beta2)
|
||||
addressable (2.3.5)
|
||||
annotate (2.6.0)
|
||||
activerecord (>= 2.3.0)
|
||||
rake (>= 0.8.7)
|
||||
arel (3.0.3)
|
||||
asciidoctor (0.1.3)
|
||||
arel (4.0.1)
|
||||
asciidoctor (0.1.4)
|
||||
atomic (1.1.14)
|
||||
awesome_print (1.2.0)
|
||||
backports (3.3.2)
|
||||
bcrypt-ruby (3.1.1)
|
||||
axiom-types (0.0.5)
|
||||
descendants_tracker (~> 0.0.1)
|
||||
ice_nine (~> 0.9)
|
||||
bcrypt-ruby (3.1.2)
|
||||
better_errors (1.0.1)
|
||||
coderay (>= 1.0.0)
|
||||
erubis (>= 2.6.6)
|
||||
@@ -46,92 +59,94 @@ GEM
|
||||
debug_inspector (>= 0.0.1)
|
||||
bootstrap-sass (2.3.2.2)
|
||||
sass (~> 3.2)
|
||||
builder (3.0.4)
|
||||
builder (3.1.4)
|
||||
capybara (2.1.0)
|
||||
mime-types (>= 1.16)
|
||||
nokogiri (>= 1.3.3)
|
||||
rack (>= 1.0.0)
|
||||
rack-test (>= 0.5.4)
|
||||
xpath (~> 2.0)
|
||||
carrierwave (0.8.0)
|
||||
carrierwave (0.9.0)
|
||||
activemodel (>= 3.2.0)
|
||||
activesupport (>= 3.2.0)
|
||||
celluloid (0.14.1)
|
||||
timers (>= 1.0.0)
|
||||
json (>= 1.7)
|
||||
celluloid (0.15.2)
|
||||
timers (~> 1.1.0)
|
||||
charlock_holmes (0.6.9.4)
|
||||
childprocess (0.3.9)
|
||||
ffi (~> 1.0, >= 1.0.11)
|
||||
chosen-rails (1.0.0)
|
||||
chosen-rails (1.0.1)
|
||||
coffee-rails (>= 3.2)
|
||||
compass-rails (>= 1.0)
|
||||
railties (>= 3.0)
|
||||
sass-rails (>= 3.2)
|
||||
chunky_png (1.2.8)
|
||||
cliver (0.2.1)
|
||||
chunky_png (1.2.9)
|
||||
cliver (0.2.2)
|
||||
code_analyzer (0.4.3)
|
||||
sexp_processor
|
||||
coderay (1.0.9)
|
||||
coffee-rails (3.2.2)
|
||||
coderay (1.1.0)
|
||||
coercible (1.0.0)
|
||||
descendants_tracker (~> 0.0.1)
|
||||
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.2)
|
||||
coffee-script-source (1.6.3)
|
||||
colored (1.2)
|
||||
colorize (0.5.8)
|
||||
compass (0.12.2)
|
||||
chunky_png (~> 1.2)
|
||||
fssm (>= 0.2.7)
|
||||
sass (~> 3.1)
|
||||
compass-rails (1.0.3)
|
||||
compass (>= 0.12.2, < 0.14)
|
||||
connection_pool (1.1.0)
|
||||
compass-rails (1.1.1)
|
||||
compass (>= 0.12.2)
|
||||
connection_pool (1.2.0)
|
||||
coveralls (0.7.0)
|
||||
multi_json (~> 1.3)
|
||||
rest-client
|
||||
simplecov (>= 0.7)
|
||||
term-ansicolor
|
||||
thor
|
||||
crack (0.4.0)
|
||||
crack (0.4.1)
|
||||
safe_yaml (~> 0.9.0)
|
||||
d3_rails (3.1.10)
|
||||
railties (>= 3.1.0)
|
||||
daemons (1.1.9)
|
||||
database_cleaner (1.1.1)
|
||||
database_cleaner (1.2.0)
|
||||
debug_inspector (0.0.2)
|
||||
descendants_tracker (0.0.1)
|
||||
devise (2.2.5)
|
||||
descendants_tracker (0.0.3)
|
||||
devise (3.0.4)
|
||||
bcrypt-ruby (~> 3.0)
|
||||
orm_adapter (~> 0.1)
|
||||
railties (~> 3.1)
|
||||
warden (~> 1.2.1)
|
||||
railties (>= 3.2.6, < 5)
|
||||
warden (~> 1.2.3)
|
||||
devise-async (0.8.0)
|
||||
devise (>= 2.2, < 3.2)
|
||||
diff-lcs (1.2.5)
|
||||
dotenv (0.8.0)
|
||||
email_spec (1.4.0)
|
||||
docile (1.1.1)
|
||||
dotenv (0.9.0)
|
||||
email_spec (1.5.0)
|
||||
launchy (~> 2.1)
|
||||
mail (~> 2.2)
|
||||
enumerize (0.6.1)
|
||||
enumerize (0.7.0)
|
||||
activesupport (>= 3.2)
|
||||
equalizer (0.0.8)
|
||||
erubis (2.7.0)
|
||||
escape_utils (0.2.4)
|
||||
eventmachine (1.0.3)
|
||||
excon (0.13.4)
|
||||
execjs (1.4.0)
|
||||
multi_json (~> 1.0)
|
||||
factory_girl (4.2.0)
|
||||
execjs (2.0.2)
|
||||
factory_girl (4.3.0)
|
||||
activesupport (>= 3.0.0)
|
||||
factory_girl_rails (4.2.1)
|
||||
factory_girl (~> 4.2.0)
|
||||
factory_girl_rails (4.3.0)
|
||||
factory_girl (~> 4.3.0)
|
||||
railties (>= 3.0.0)
|
||||
faraday (0.8.7)
|
||||
multipart-post (~> 1.1)
|
||||
faraday (0.8.8)
|
||||
multipart-post (~> 1.2.0)
|
||||
faraday_middleware (0.9.0)
|
||||
faraday (>= 0.7.4, < 0.9)
|
||||
ffaker (1.18.0)
|
||||
ffi (1.9.0)
|
||||
ffaker (1.22.1)
|
||||
ffi (1.9.3)
|
||||
fog (1.3.1)
|
||||
builder
|
||||
excon (~> 0.13.0)
|
||||
@@ -149,50 +164,49 @@ GEM
|
||||
thor (>= 0.13.6)
|
||||
formatador (0.2.4)
|
||||
fssm (0.2.10)
|
||||
gemoji (1.2.1)
|
||||
gherkin-ruby (0.3.0)
|
||||
github-linguist (2.3.4)
|
||||
charlock_holmes (~> 0.6.6)
|
||||
escape_utils (~> 0.2.3)
|
||||
mime-types (~> 1.19)
|
||||
pygments.rb (>= 0.2.13)
|
||||
github-markdown (0.5.3)
|
||||
gemoji (1.3.1)
|
||||
gherkin-ruby (0.3.1)
|
||||
racc
|
||||
github-markdown (0.5.5)
|
||||
github-markup (0.7.5)
|
||||
gitlab-flowdock-git-hook (0.4.2.2)
|
||||
gitlab-grit (>= 2.4.1)
|
||||
multi_json
|
||||
gitlab-gollum-lib (1.0.1)
|
||||
gitlab-gollum-lib (1.0.2)
|
||||
github-markdown (~> 0.5.3)
|
||||
github-markup (>= 0.7.5, < 1.0.0)
|
||||
gitlab-grit (>= 2.5.1)
|
||||
gitlab-grit (~> 2.6.1)
|
||||
gitlab-pygments.rb (~> 0.5.4)
|
||||
nokogiri (~> 1.5.9)
|
||||
pygments.rb (~> 0.4.2)
|
||||
sanitize (~> 2.0.3)
|
||||
stringex (~> 1.5.1)
|
||||
gitlab-grack (1.0.1)
|
||||
rack (~> 1.4.1)
|
||||
gitlab-grack (2.0.0.pre)
|
||||
rack (~> 1.5.1)
|
||||
gitlab-grit (2.6.3)
|
||||
charlock_holmes (~> 0.6.9)
|
||||
diff-lcs (~> 1.1)
|
||||
mime-types (~> 1.15)
|
||||
posix-spawn (~> 0.3.6)
|
||||
gitlab-pygments.rb (0.3.2)
|
||||
gitlab-linguist (2.9.6)
|
||||
charlock_holmes (~> 0.6.6)
|
||||
escape_utils (~> 0.2.4)
|
||||
gitlab-pygments.rb (~> 0.5.4)
|
||||
mime-types (~> 1.19)
|
||||
gitlab-pygments.rb (0.5.4)
|
||||
posix-spawn (~> 0.3.6)
|
||||
yajl-ruby (~> 1.1.0)
|
||||
gitlab_git (3.0.0.rc2)
|
||||
activesupport (~> 3.2.13)
|
||||
github-linguist (~> 2.3.4)
|
||||
gitlab_git (4.0.0.pre)
|
||||
activesupport (~> 4.0.0)
|
||||
gitlab-grit (~> 2.6.1)
|
||||
gitlab-linguist (~> 2.9.5)
|
||||
gitlab-pygments.rb (~> 0.5.4)
|
||||
gitlab_meta (6.0)
|
||||
gitlab_omniauth-ldap (1.0.3)
|
||||
net-ldap (~> 0.3.1)
|
||||
omniauth (~> 1.0)
|
||||
pyu-ruby-sasl (~> 0.0.3.1)
|
||||
rubyntlm (~> 0.1.1)
|
||||
gon (4.1.1)
|
||||
actionpack (>= 2.3.0)
|
||||
json
|
||||
grape (0.4.1)
|
||||
grape (0.6.1)
|
||||
activesupport
|
||||
builder
|
||||
hashie (>= 1.2.0)
|
||||
@@ -201,91 +215,91 @@ GEM
|
||||
rack (>= 1.3.0)
|
||||
rack-accept
|
||||
rack-mount
|
||||
virtus
|
||||
virtus (>= 1.0.0)
|
||||
grape-entity (0.3.0)
|
||||
activesupport
|
||||
multi_json (>= 1.3.2)
|
||||
growl (1.0.3)
|
||||
guard (1.8.1)
|
||||
guard (2.2.4)
|
||||
formatador (>= 0.2.4)
|
||||
listen (>= 1.0.0)
|
||||
lumberjack (>= 1.0.2)
|
||||
pry (>= 0.9.10)
|
||||
thor (>= 0.14.6)
|
||||
guard-rspec (3.0.2)
|
||||
guard (>= 1.8)
|
||||
rspec (~> 2.13)
|
||||
listen (~> 2.1)
|
||||
lumberjack (~> 1.0)
|
||||
pry (>= 0.9.12)
|
||||
thor (>= 0.18.1)
|
||||
guard-rspec (4.2.0)
|
||||
guard (>= 2.1.1)
|
||||
rspec (>= 2.14, < 4.0)
|
||||
guard-spinach (0.0.2)
|
||||
guard (>= 1.1)
|
||||
spinach
|
||||
haml (4.0.3)
|
||||
haml (4.0.4)
|
||||
tilt
|
||||
haml-rails (0.4)
|
||||
actionpack (>= 3.1, < 4.1)
|
||||
activesupport (>= 3.1, < 4.1)
|
||||
haml (>= 3.1, < 4.1)
|
||||
railties (>= 3.1, < 4.1)
|
||||
hashie (1.2.0)
|
||||
haml-rails (0.5.1)
|
||||
actionpack (~> 4.0.0)
|
||||
activesupport (~> 4.0.0)
|
||||
haml (>= 3.1, < 5.0)
|
||||
railties (~> 4.0.0)
|
||||
hashie (2.0.5)
|
||||
hike (1.2.3)
|
||||
hipchat (0.9.0)
|
||||
httparty
|
||||
httparty
|
||||
http_parser.rb (0.5.3)
|
||||
httparty (0.11.0)
|
||||
multi_json (~> 1.0)
|
||||
httparty (0.12.0)
|
||||
json (~> 1.8)
|
||||
multi_xml (>= 0.5.2)
|
||||
httpauth (0.2.0)
|
||||
i18n (0.6.9)
|
||||
jasmine (1.3.2)
|
||||
jasmine-core (~> 1.3.1)
|
||||
rack (~> 1.0)
|
||||
rspec (>= 1.3.1)
|
||||
selenium-webdriver (>= 0.1.3)
|
||||
jasmine-core (1.3.1)
|
||||
journey (1.0.4)
|
||||
jquery-atwho-rails (0.3.0)
|
||||
ice_nine (0.10.0)
|
||||
jasmine (2.0.0.rc5)
|
||||
jasmine-core (~> 2.0.0.rc5)
|
||||
phantomjs
|
||||
rack (>= 1.2.1)
|
||||
rake
|
||||
jasmine-core (2.0.0.rc5)
|
||||
jquery-atwho-rails (0.3.3)
|
||||
jquery-rails (2.1.3)
|
||||
railties (>= 3.1.0, < 5.0)
|
||||
thor (~> 0.14)
|
||||
jquery-turbolinks (1.0.0)
|
||||
jquery-turbolinks (2.0.1)
|
||||
railties (>= 3.1.0)
|
||||
turbolinks
|
||||
jquery-ui-rails (2.0.2)
|
||||
jquery-rails
|
||||
railties (>= 3.1.0)
|
||||
json (1.7.7)
|
||||
json (1.8.1)
|
||||
jwt (0.1.8)
|
||||
multi_json (>= 1.5)
|
||||
kaminari (0.14.1)
|
||||
actionpack (>= 3.0.0)
|
||||
activesupport (>= 3.0.0)
|
||||
kgio (2.8.0)
|
||||
launchy (2.3.0)
|
||||
kgio (2.8.1)
|
||||
launchy (2.4.2)
|
||||
addressable (~> 2.3)
|
||||
letter_opener (1.1.1)
|
||||
letter_opener (1.1.2)
|
||||
launchy (~> 2.2)
|
||||
libv8 (3.11.8.17)
|
||||
listen (1.2.2)
|
||||
libv8 (3.16.14.3)
|
||||
listen (2.3.1)
|
||||
celluloid (>= 0.15.2)
|
||||
rb-fsevent (>= 0.9.3)
|
||||
rb-inotify (>= 0.9)
|
||||
rb-kqueue (>= 0.2)
|
||||
lumberjack (1.0.3)
|
||||
lumberjack (1.0.4)
|
||||
mail (2.5.4)
|
||||
mime-types (~> 1.16)
|
||||
treetop (~> 1.4.8)
|
||||
method_source (0.8.1)
|
||||
method_source (0.8.2)
|
||||
mime-types (1.25.1)
|
||||
minitest (4.7.4)
|
||||
minitest (4.7.5)
|
||||
modernizr (2.6.2)
|
||||
sprockets (~> 2.0)
|
||||
multi_json (1.8.2)
|
||||
multi_xml (0.5.4)
|
||||
multi_xml (0.5.5)
|
||||
multipart-post (1.2.0)
|
||||
mysql2 (0.3.11)
|
||||
net-ldap (0.3.1)
|
||||
net-scp (1.0.4)
|
||||
net-ssh (>= 1.99.1)
|
||||
net-ssh (2.6.8)
|
||||
net-ssh (2.7.0)
|
||||
nokogiri (1.5.10)
|
||||
oauth (0.4.7)
|
||||
oauth2 (0.8.1)
|
||||
@@ -297,10 +311,10 @@ GEM
|
||||
omniauth (1.1.4)
|
||||
hashie (>= 1.2, < 3)
|
||||
rack
|
||||
omniauth-github (1.1.0)
|
||||
omniauth-github (1.1.1)
|
||||
omniauth (~> 1.0)
|
||||
omniauth-oauth2 (~> 1.1)
|
||||
omniauth-google-oauth2 (0.1.19)
|
||||
omniauth-google-oauth2 (0.2.1)
|
||||
omniauth (~> 1.0)
|
||||
omniauth-oauth2
|
||||
omniauth-oauth (1.0.1)
|
||||
@@ -309,11 +323,12 @@ GEM
|
||||
omniauth-oauth2 (1.1.1)
|
||||
oauth2 (~> 0.8.0)
|
||||
omniauth (~> 1.0)
|
||||
omniauth-twitter (0.0.17)
|
||||
omniauth-twitter (1.0.1)
|
||||
multi_json (~> 1.3)
|
||||
omniauth-oauth (~> 1.0)
|
||||
orm_adapter (0.4.0)
|
||||
orm_adapter (0.5.0)
|
||||
pg (0.15.1)
|
||||
phantomjs (1.9.2.0)
|
||||
poltergeist (1.4.1)
|
||||
capybara (~> 2.1.0)
|
||||
cliver (~> 0.2.1)
|
||||
@@ -321,44 +336,40 @@ GEM
|
||||
websocket-driver (>= 0.2.0)
|
||||
polyglot (0.3.3)
|
||||
posix-spawn (0.3.6)
|
||||
pry (0.9.12.2)
|
||||
coderay (~> 1.0.5)
|
||||
protected_attributes (1.0.5)
|
||||
activemodel (>= 4.0.1, < 5.0)
|
||||
pry (0.9.12.4)
|
||||
coderay (~> 1.0)
|
||||
method_source (~> 0.8)
|
||||
slop (~> 3.4)
|
||||
pygments.rb (0.4.2)
|
||||
posix-spawn (~> 0.3.6)
|
||||
yajl-ruby (~> 1.1.0)
|
||||
pyu-ruby-sasl (0.0.3.3)
|
||||
quiet_assets (1.0.2)
|
||||
railties (>= 3.1, < 5.0)
|
||||
rack (1.4.5)
|
||||
racc (1.4.10)
|
||||
rack (1.5.2)
|
||||
rack-accept (0.4.5)
|
||||
rack (>= 0.4)
|
||||
rack-attack (2.2.1)
|
||||
rack-attack (2.3.0)
|
||||
rack
|
||||
rack-cache (1.2)
|
||||
rack (>= 0.4)
|
||||
rack-cors (0.2.9)
|
||||
rack-mini-profiler (0.1.31)
|
||||
rack (>= 1.1.3)
|
||||
rack-mount (0.8.3)
|
||||
rack (>= 1.0.0)
|
||||
rack-protection (1.5.0)
|
||||
rack
|
||||
rack-ssl (1.3.3)
|
||||
rack-protection (1.5.1)
|
||||
rack
|
||||
rack-test (0.6.2)
|
||||
rack (>= 1.0)
|
||||
rails (3.2.16)
|
||||
actionmailer (= 3.2.16)
|
||||
actionpack (= 3.2.16)
|
||||
activerecord (= 3.2.16)
|
||||
activeresource (= 3.2.16)
|
||||
activesupport (= 3.2.16)
|
||||
bundler (~> 1.0)
|
||||
railties (= 3.2.16)
|
||||
rails-dev-tweaks (0.6.1)
|
||||
actionpack (~> 3.1)
|
||||
railties (~> 3.1)
|
||||
rails (4.0.2)
|
||||
actionmailer (= 4.0.2)
|
||||
actionpack (= 4.0.2)
|
||||
activerecord (= 4.0.2)
|
||||
activesupport (= 4.0.2)
|
||||
bundler (>= 1.3.0, < 2.0)
|
||||
railties (= 4.0.2)
|
||||
sprockets-rails (~> 2.0.0)
|
||||
rails-observers (0.1.2)
|
||||
activemodel (~> 4.0)
|
||||
rails_best_practices (1.14.4)
|
||||
activesupport
|
||||
awesome_print
|
||||
@@ -368,180 +379,179 @@ GEM
|
||||
i18n
|
||||
require_all
|
||||
ruby-progressbar
|
||||
railties (3.2.16)
|
||||
actionpack (= 3.2.16)
|
||||
activesupport (= 3.2.16)
|
||||
rack-ssl (~> 1.3.2)
|
||||
railties (4.0.2)
|
||||
actionpack (= 4.0.2)
|
||||
activesupport (= 4.0.2)
|
||||
rake (>= 0.8.7)
|
||||
rdoc (~> 3.4)
|
||||
thor (>= 0.14.6, < 2.0)
|
||||
raindrops (0.11.0)
|
||||
thor (>= 0.18.1, < 2.0)
|
||||
raindrops (0.12.0)
|
||||
rake (10.1.0)
|
||||
raphael-rails (2.1.2)
|
||||
rb-fsevent (0.9.3)
|
||||
rb-inotify (0.9.0)
|
||||
ffi (>= 0.5.0)
|
||||
rb-kqueue (0.2.0)
|
||||
rb-inotify (0.9.2)
|
||||
ffi (>= 0.5.0)
|
||||
rdoc (3.12.2)
|
||||
json (~> 1.4)
|
||||
redcarpet (2.2.2)
|
||||
redis (3.0.4)
|
||||
redis-actionpack (3.2.4)
|
||||
actionpack (~> 3.2.0)
|
||||
redis-rack (~> 1.4.4)
|
||||
redis-store (~> 1.1.4)
|
||||
redis-activesupport (3.2.4)
|
||||
activesupport (~> 3.2.0)
|
||||
redis (3.0.6)
|
||||
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.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-namespace (1.3.1)
|
||||
redis (~> 3.0.0)
|
||||
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-store (1.1.4)
|
||||
redis (>= 2.2)
|
||||
ref (1.0.5)
|
||||
require_all (1.3.1)
|
||||
require_all (1.3.2)
|
||||
rest-client (1.6.7)
|
||||
mime-types (>= 1.16)
|
||||
rspec (2.13.0)
|
||||
rspec-core (~> 2.13.0)
|
||||
rspec-expectations (~> 2.13.0)
|
||||
rspec-mocks (~> 2.13.0)
|
||||
rspec-core (2.13.1)
|
||||
rspec-expectations (2.13.0)
|
||||
rspec (2.14.1)
|
||||
rspec-core (~> 2.14.0)
|
||||
rspec-expectations (~> 2.14.0)
|
||||
rspec-mocks (~> 2.14.0)
|
||||
rspec-core (2.14.7)
|
||||
rspec-expectations (2.14.4)
|
||||
diff-lcs (>= 1.1.3, < 2.0)
|
||||
rspec-mocks (2.13.1)
|
||||
rspec-rails (2.13.2)
|
||||
rspec-mocks (2.14.4)
|
||||
rspec-rails (2.14.0)
|
||||
actionpack (>= 3.0)
|
||||
activesupport (>= 3.0)
|
||||
railties (>= 3.0)
|
||||
rspec-core (~> 2.13.0)
|
||||
rspec-expectations (~> 2.13.0)
|
||||
rspec-mocks (~> 2.13.0)
|
||||
rspec-core (~> 2.14.0)
|
||||
rspec-expectations (~> 2.14.0)
|
||||
rspec-mocks (~> 2.14.0)
|
||||
ruby-hmac (0.4.0)
|
||||
ruby-progressbar (1.2.0)
|
||||
rubyntlm (0.1.1)
|
||||
rubyzip (0.9.9)
|
||||
safe_yaml (0.9.3)
|
||||
sanitize (2.0.3)
|
||||
nokogiri (>= 1.4.4, < 1.6)
|
||||
sass (3.2.11)
|
||||
sass-rails (3.2.6)
|
||||
railties (~> 3.2.0)
|
||||
safe_yaml (0.9.7)
|
||||
sanitize (2.0.6)
|
||||
nokogiri (>= 1.4.4)
|
||||
sass (3.2.12)
|
||||
sass-rails (4.0.1)
|
||||
railties (>= 4.0.0, < 5.0)
|
||||
sass (>= 3.1.10)
|
||||
tilt (~> 1.3)
|
||||
sprockets-rails (~> 2.0.0)
|
||||
sdoc (0.3.20)
|
||||
json (>= 1.1.3)
|
||||
rdoc (~> 3.10)
|
||||
seed-fu (2.2.0)
|
||||
activerecord (~> 3.1)
|
||||
activesupport (~> 3.1)
|
||||
select2-rails (3.4.2)
|
||||
sass-rails
|
||||
seed-fu (2.3.0)
|
||||
activerecord (>= 3.1, < 4.1)
|
||||
activesupport (>= 3.1, < 4.1)
|
||||
select2-rails (3.5.2)
|
||||
thor (~> 0.14)
|
||||
selenium-webdriver (2.33.0)
|
||||
childprocess (>= 0.2.5)
|
||||
multi_json (~> 1.0)
|
||||
rubyzip
|
||||
websocket (~> 1.0.4)
|
||||
settingslogic (2.0.9)
|
||||
sexp_processor (4.3.0)
|
||||
sexp_processor (4.4.0)
|
||||
shoulda-matchers (2.1.0)
|
||||
activesupport (>= 3.0.0)
|
||||
sidekiq (2.14.0)
|
||||
celluloid (>= 0.14.1)
|
||||
sidekiq (2.17.0)
|
||||
celluloid (>= 0.15.2)
|
||||
connection_pool (>= 1.0.0)
|
||||
json
|
||||
redis (>= 3.0.4)
|
||||
redis-namespace
|
||||
redis-namespace (>= 1.3.1)
|
||||
simple_oauth (0.1.9)
|
||||
simplecov (0.7.1)
|
||||
multi_json (~> 1.0)
|
||||
simplecov-html (~> 0.7.1)
|
||||
simplecov-html (0.7.1)
|
||||
sinatra (1.4.3)
|
||||
simplecov (0.8.2)
|
||||
docile (~> 1.1.0)
|
||||
multi_json
|
||||
simplecov-html (~> 0.8.0)
|
||||
simplecov-html (0.8.0)
|
||||
sinatra (1.4.4)
|
||||
rack (~> 1.4)
|
||||
rack-protection (~> 1.4)
|
||||
tilt (~> 1.3, >= 1.3.4)
|
||||
six (0.2.0)
|
||||
slim (2.0.0)
|
||||
temple (~> 0.6.5)
|
||||
tilt (~> 1.3, >= 1.3.3)
|
||||
slop (3.4.5)
|
||||
spinach (0.8.3)
|
||||
slim (2.0.2)
|
||||
temple (~> 0.6.6)
|
||||
tilt (>= 1.3.3, < 2.1)
|
||||
slop (3.4.7)
|
||||
spinach (0.8.7)
|
||||
colorize (= 0.5.8)
|
||||
gherkin-ruby (~> 0.3.0)
|
||||
gherkin-ruby (>= 0.3.1)
|
||||
spinach-rails (0.2.1)
|
||||
capybara (>= 2.0.0)
|
||||
railties (>= 3)
|
||||
spinach (>= 0.4)
|
||||
spork (1.0.0rc2)
|
||||
sprockets (2.2.2)
|
||||
spork (1.0.0rc4)
|
||||
sprockets (2.10.1)
|
||||
hike (~> 1.2)
|
||||
multi_json (~> 1.0)
|
||||
rack (~> 1.0)
|
||||
tilt (~> 1.1, != 1.3.0)
|
||||
sprockets-rails (2.0.1)
|
||||
actionpack (>= 3.0)
|
||||
activesupport (>= 3.0)
|
||||
sprockets (~> 2.8)
|
||||
stamp (0.5.0)
|
||||
state_machine (1.2.0)
|
||||
stringex (1.5.1)
|
||||
temple (0.6.5)
|
||||
temple (0.6.7)
|
||||
term-ansicolor (1.2.2)
|
||||
tins (~> 0.8)
|
||||
test_after_commit (0.2.1)
|
||||
therubyracer (0.11.4)
|
||||
libv8 (~> 3.11.8.12)
|
||||
test_after_commit (0.2.2)
|
||||
therubyracer (0.12.0)
|
||||
libv8 (~> 3.16.14.0)
|
||||
ref
|
||||
thin (1.5.1)
|
||||
thin (1.6.1)
|
||||
daemons (>= 1.0.9)
|
||||
eventmachine (>= 0.12.6)
|
||||
eventmachine (>= 1.0.0)
|
||||
rack (>= 1.0.0)
|
||||
thor (0.18.1)
|
||||
thread_safe (0.1.3)
|
||||
atomic
|
||||
tilt (1.4.1)
|
||||
timers (1.1.0)
|
||||
tinder (1.9.2)
|
||||
tinder (1.9.3)
|
||||
eventmachine (~> 1.0)
|
||||
faraday (~> 0.8)
|
||||
faraday_middleware (~> 0.9)
|
||||
hashie (~> 1.0)
|
||||
json (~> 1.7.5)
|
||||
hashie (>= 1.0, < 3)
|
||||
json (~> 1.8.0)
|
||||
mime-types (~> 1.19)
|
||||
multi_json (~> 1.5)
|
||||
multi_json (~> 1.7)
|
||||
twitter-stream (~> 0.1)
|
||||
tins (0.11.0)
|
||||
tins (0.13.1)
|
||||
treetop (1.4.15)
|
||||
polyglot
|
||||
polyglot (>= 0.3.1)
|
||||
turbolinks (1.2.0)
|
||||
turbolinks (2.0.0)
|
||||
coffee-rails
|
||||
twitter-stream (0.1.16)
|
||||
eventmachine (>= 0.12.8)
|
||||
http_parser.rb (~> 0.5.1)
|
||||
simple_oauth (~> 0.1.4)
|
||||
tzinfo (0.3.38)
|
||||
uglifier (2.1.1)
|
||||
uglifier (2.3.2)
|
||||
execjs (>= 0.3.0)
|
||||
multi_json (~> 1.0, >= 1.0.2)
|
||||
json (>= 1.8.0)
|
||||
underscore-rails (1.4.4)
|
||||
unicorn (4.6.3)
|
||||
kgio (~> 2.6)
|
||||
rack
|
||||
raindrops (~> 0.7)
|
||||
virtus (0.5.5)
|
||||
backports (~> 3.3)
|
||||
unicorn-worker-killer (0.4.2)
|
||||
unicorn (~> 4)
|
||||
virtus (1.0.1)
|
||||
axiom-types (~> 0.0.5)
|
||||
coercible (~> 1.0)
|
||||
descendants_tracker (~> 0.0.1)
|
||||
equalizer (~> 0.0.7)
|
||||
warden (1.2.3)
|
||||
rack (>= 1.0)
|
||||
webmock (1.11.0)
|
||||
webmock (1.16.0)
|
||||
addressable (>= 2.2.7)
|
||||
crack (>= 0.3.2)
|
||||
websocket (1.0.7)
|
||||
websocket-driver (0.3.0)
|
||||
websocket-driver (0.3.1)
|
||||
xpath (2.0.0)
|
||||
nokogiri (~> 1.3)
|
||||
yajl-ruby (1.1.0)
|
||||
@@ -550,42 +560,45 @@ PLATFORMS
|
||||
ruby
|
||||
|
||||
DEPENDENCIES
|
||||
actionpack-action_caching
|
||||
actionpack-page_caching
|
||||
activerecord-deprecated_finders
|
||||
acts-as-taggable-on
|
||||
annotate (~> 2.6.0.beta2)
|
||||
asciidoctor
|
||||
awesome_print
|
||||
better_errors
|
||||
binding_of_caller
|
||||
bootstrap-sass
|
||||
bootstrap-sass (~> 2.3)
|
||||
capybara
|
||||
carrierwave
|
||||
chosen-rails (= 1.0.0)
|
||||
chosen-rails (= 1.0.1)
|
||||
coffee-rails
|
||||
colored
|
||||
coveralls
|
||||
d3_rails (~> 3.1.4)
|
||||
database_cleaner
|
||||
devise (~> 2.2)
|
||||
devise-async
|
||||
devise (= 3.0.4)
|
||||
devise-async (= 0.8.0)
|
||||
email_spec
|
||||
enumerize
|
||||
factory_girl_rails
|
||||
ffaker
|
||||
fog (~> 1.3.1)
|
||||
font-awesome-rails
|
||||
font-awesome-rails (~> 3.2)
|
||||
foreman
|
||||
gemoji (~> 1.2.1)
|
||||
github-linguist
|
||||
gemoji (~> 1.3.0)
|
||||
github-markup (~> 0.7.4)
|
||||
gitlab-flowdock-git-hook (~> 0.4.2)
|
||||
gitlab-gollum-lib (~> 1.0.1)
|
||||
gitlab-grack (~> 1.0.1)
|
||||
gitlab-pygments.rb (~> 0.3.2)
|
||||
gitlab_git (~> 3.0.0.rc2)
|
||||
gitlab-gollum-lib (~> 1.0.2)
|
||||
gitlab-grack (~> 2.0.0.pre)
|
||||
gitlab-linguist (~> 2.9.6)
|
||||
gitlab-pygments.rb (~> 0.5.4)
|
||||
gitlab_git (~> 4.0.0.pre)
|
||||
gitlab_meta (= 6.0)
|
||||
gitlab_omniauth-ldap (= 1.0.3)
|
||||
gon
|
||||
grape (~> 0.4.1)
|
||||
gon!
|
||||
grape (~> 0.6.1)
|
||||
grape-entity (~> 0.3.0)
|
||||
growl
|
||||
guard-rspec
|
||||
@@ -593,8 +606,8 @@ DEPENDENCIES
|
||||
haml-rails
|
||||
hipchat (~> 0.9.0)
|
||||
httparty
|
||||
jasmine
|
||||
jquery-atwho-rails (= 0.3.0)
|
||||
jasmine (= 2.0.0.rc5)
|
||||
jquery-atwho-rails (~> 0.3.3)
|
||||
jquery-rails (= 2.1.3)
|
||||
jquery-turbolinks
|
||||
jquery-ui-rails (= 2.0.2)
|
||||
@@ -611,12 +624,14 @@ DEPENDENCIES
|
||||
omniauth-twitter
|
||||
pg
|
||||
poltergeist (~> 1.4.1)
|
||||
protected_attributes
|
||||
pry
|
||||
quiet_assets (~> 1.0.1)
|
||||
rack-attack
|
||||
rack-cors
|
||||
rack-mini-profiler
|
||||
rails (= 3.2.16)
|
||||
rails-dev-tweaks
|
||||
rails (~> 4.0.0)
|
||||
rails-observers
|
||||
rails_best_practices
|
||||
raphael-rails (~> 2.1.2)
|
||||
rb-fsevent
|
||||
@@ -648,4 +663,5 @@ DEPENDENCIES
|
||||
uglifier
|
||||
underscore-rails (~> 1.4.4)
|
||||
unicorn (~> 4.6.3)
|
||||
unicorn-worker-killer
|
||||
webmock
|
||||
|
||||
@@ -32,7 +32,9 @@
|
||||
|
||||
* GitLab.com commercial services: [Homepage](http://www.gitlab.com/) | [Subscription](http://www.gitlab.com/subscription/) | [Consultancy](http://www.gitlab.com/consultancy/) | [GitLab Cloud](http://www.gitlab.com/cloud/) | [Blog](http://blog.gitlab.com/)
|
||||
|
||||
* GitLab CI: [Readme](https://github.com/gitlabhq/gitlab-ci/blob/master/README.md) of the GitLab open-source continuous integration server
|
||||
* [GitLab Enterprise Edition](https://www.gitlab.com/features/) offers additional features that are useful for larger organizations (100+ users).
|
||||
|
||||
* [GitLab CI](https://github.com/gitlabhq/gitlab-ci/blob/master/README.md) is a continuous integration (CI) server that is easy to integrate with GitLab.
|
||||
|
||||
### Requirements
|
||||
|
||||
@@ -46,30 +48,24 @@
|
||||
|
||||
### Installation
|
||||
|
||||
#### Official production installation
|
||||
#### Official installation methods
|
||||
|
||||
* [Installation guide for a production server](doc/install/installation.md)
|
||||
* [Manual installation guide for a production server](doc/install/installation.md)
|
||||
|
||||
* [GitLab Chef Cookbook](https://gitlab.com/gitlab-org/cookbook-gitlab/blob/master/README.md) This cookbook can be used both for development installations and production installations. If you want to [contribute](CONTRIBUTE.md) to GitLab we suggest you follow the [development installation on a virtual machine with Vagrant](https://gitlab.com/gitlab-org/cookbook-gitlab/blob/master/doc/development.md) instructions to install all testing dependencies.
|
||||
|
||||
#### Official development installation
|
||||
#### Third party one-click installers
|
||||
|
||||
If you want to contribute, please first read our [Contributing Guidelines](https://github.com/gitlabhq/gitlabhq/blob/master/CONTRIBUTING.md) and then we suggest you to use the Vagrant virtual machine project to get an environment working with all dependencies.
|
||||
* [Digital Ocean 1-Click Application Install](https://www.digitalocean.com/blog_posts/host-your-git-repositories-in-55-seconds-with-gitlab) Have a new server up in 55 seconds. Digital Ocean uses SSD disks which is great for an IO intensive app such as GitLab.
|
||||
|
||||
* [Vagrant virtual machine for development](https://github.com/gitlabhq/gitlab-vagrant-vm)
|
||||
* [BitNami one-click installers](http://bitnami.com/stack/gitlab) This package contains both GitLab and GitLab CI. It is available as installer, virtual machine or for cloud hosting providers (Amazon Web Services/Azure/etc.).
|
||||
|
||||
|
||||
#### Unofficial production installations
|
||||
#### Unofficial installation methods
|
||||
|
||||
* [GitLab recipes](https://github.com/gitlabhq/gitlab-recipes) repository with unofficial guides for using GitLab with different software (operating systems, webservers, etc.) than the official version.
|
||||
|
||||
* [Installation guides](https://github.com/gitlabhq/gitlab-public-wiki/wiki/Unofficial-Installation-Guides) public wiki with unofficial guides to install GitLab on different operating systems.
|
||||
|
||||
|
||||
* [Digital Ocean 1-Click Application Install](https://www.digitalocean.com/) Have a new server up in 55 seconds. Digital Ocean uses SSD disks which is great for an IO intensive app as GitLab. Look for GitLab under 'Select Image' => 'Applications' when creating a droplet.
|
||||
|
||||
* [BitNami one-click installers](http://bitnami.com/stack/gitlab) Get an image with GitLab and GitLab CI preinstalled for Amazon Web Services, Azure, VMware or your local server.
|
||||
|
||||
|
||||
### New versions and upgrading
|
||||
|
||||
Since 2011 GitLab is released on the 22nd of every month. Every new release includes an upgrade guide.
|
||||
@@ -80,7 +76,6 @@ Since 2011 GitLab is released on the 22nd of every month. Every new release incl
|
||||
|
||||
* Features that will be in the next releases are listed on [the feedback and suggestions forum](http://feedback.gitlab.com/forums/176466-general) with the status [started](http://feedback.gitlab.com/forums/176466-general/status/796456) and [completed](http://feedback.gitlab.com/forums/176466-general/status/796457).
|
||||
|
||||
|
||||
### Run in production mode
|
||||
|
||||
The Installation guide contains instructions on how to download an init script and run it automatically on boot. You can also start the init script manually:
|
||||
@@ -111,7 +106,7 @@ or start each component separately
|
||||
|
||||
* Run all tests
|
||||
|
||||
bundle exec rake gitlab:test
|
||||
bundle exec rake gitlab:test RAILS_ENV=test
|
||||
|
||||
* [RSpec](http://rspec.info/) unit and functional tests
|
||||
|
||||
@@ -148,15 +143,17 @@ or start each component separately
|
||||
|
||||
* [Mailing list](https://groups.google.com/forum/#!forum/gitlabhq) and [Stack Overflow](http://stackoverflow.com/questions/tagged/gitlab) are the best places to ask questions. For example you can use it if you have questions about: permission denied errors, invisible repos, can't clone/pull/push or with web hooks that don't fire. Please search for similar issues before posting your own, there's a good chance somebody else had the same issue you have now and has resolved it. There are a lot of helpful GitLab users there who may be able to help you quickly. If your particular issue turns out to be a bug, it will find its way from there to a fix.
|
||||
|
||||
* [Unofficial #gitlab IRC on Freenode](http://www.freenode.net/) is another way to get in touch with other GitLab users who may be able to help you.
|
||||
|
||||
* [Feedback and suggestions forum](http://feedback.gitlab.com) is the place to propose and discuss new features for GitLab.
|
||||
|
||||
* [Contributing guide](https://github.com/gitlabhq/gitlabhq/blob/master/CONTRIBUTING.md) describes how to submit pull requests and issues. Pull requests and issues not in line with the guidelines in this document will be closed.
|
||||
|
||||
* [Support subscription](http://www.gitlab.com/subscription/) connects you to the knowledge of GitLab experts that will resolve your issues and answer your questions.
|
||||
|
||||
* [Consultancy](http://www.gitlab.com/consultancy/) allows you hire GitLab experts for installations, upgrades and customizations.
|
||||
* [Consultancy](http://www.gitlab.com/consultancy/) from the GitLab experts for installations, upgrades and customizations.
|
||||
|
||||
* [#gitlab IRC channel](http://www.freenode.net/) on Freenode to get in touch with other GitLab users and get help, it's managed by James Newton, Drew Blessing and Sam Gleske
|
||||
|
||||
* [Book](http://www.packtpub.com/gitlab-repository-management/book) written by GitLab enthusiast Jonathan M. Hethey is unofficial but it offers a good overview.
|
||||
|
||||
|
||||
### Getting in touch
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 32 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 2.9 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 5.6 KiB After Width: | Height: | Size: 8.1 KiB |
@@ -1,24 +1,76 @@
|
||||
class BlobView
|
||||
constructor: ->
|
||||
# handle multi-line select
|
||||
handleMultiSelect = (e) ->
|
||||
[ first_line, last_line ] = parseSelectedLines()
|
||||
[ line_number ] = parseSelectedLines($(this).attr("id"))
|
||||
hash = "L#{line_number}"
|
||||
|
||||
if e.shiftKey and not isNaN(first_line) and not isNaN(line_number)
|
||||
if line_number < first_line
|
||||
last_line = first_line
|
||||
first_line = line_number
|
||||
else
|
||||
last_line = line_number
|
||||
|
||||
hash = if first_line == last_line then "L#{first_line}" else "L#{first_line}-#{last_line}"
|
||||
|
||||
setHash(hash)
|
||||
e.preventDefault()
|
||||
|
||||
# See if there are lines selected
|
||||
# "#L12" and "#L34-56" supported
|
||||
highlightBlobLines = ->
|
||||
if window.location.hash isnt ""
|
||||
matches = window.location.hash.match(/\#L(\d+)(\-(\d+))?/)
|
||||
highlightBlobLines = (e) ->
|
||||
[ first_line, last_line ] = parseSelectedLines()
|
||||
|
||||
unless isNaN first_line
|
||||
$("#tree-content-holder .highlight .line").removeClass("hll")
|
||||
$("#LC#{line}").addClass("hll") for line in [first_line..last_line]
|
||||
$("#L#{first_line}").ScrollTo() unless e?
|
||||
|
||||
# parse selected lines from hash
|
||||
# always return first and last line (initialized to NaN)
|
||||
parseSelectedLines = (str) ->
|
||||
first_line = NaN
|
||||
last_line = NaN
|
||||
hash = str || window.location.hash
|
||||
|
||||
if hash isnt ""
|
||||
matches = hash.match(/\#?L(\d+)(\-(\d+))?/)
|
||||
first_line = parseInt(matches?[1])
|
||||
last_line = parseInt(matches?[3])
|
||||
last_line = first_line if isNaN(last_line)
|
||||
|
||||
unless isNaN first_line
|
||||
last_line = first_line if isNaN(last_line)
|
||||
$("#tree-content-holder .highlight .line").removeClass("hll")
|
||||
$("#LC#{line}").addClass("hll") for line in [first_line..last_line]
|
||||
$("#L#{first_line}").ScrollTo()
|
||||
[ first_line, last_line ]
|
||||
|
||||
setHash = (hash) ->
|
||||
hash = hash.replace(/^\#/, "")
|
||||
nodes = $("#" + hash)
|
||||
# if any nodes are using this id, they must be temporarily changed
|
||||
# also, add a temporary div at the top of the screen to prevent scrolling
|
||||
if nodes.length > 0
|
||||
scroll_top = $(document).scrollTop()
|
||||
nodes.attr("id", "")
|
||||
tmp = $("<div></div>")
|
||||
.css({ position: "absolute", visibility: "hidden", top: scroll_top + "px" })
|
||||
.attr("id", hash)
|
||||
.appendTo(document.body)
|
||||
|
||||
window.location.hash = hash
|
||||
|
||||
# restore the nodes
|
||||
if nodes.length > 0
|
||||
tmp.remove()
|
||||
nodes.attr("id", hash)
|
||||
|
||||
# initialize multi-line select
|
||||
$("#tree-content-holder .line_numbers a[id^=L]").on("click", handleMultiSelect)
|
||||
|
||||
# Highlight the correct lines on load
|
||||
highlightBlobLines()
|
||||
|
||||
# Highlight the correct lines when the hash part of the URL changes
|
||||
$(window).on 'hashchange', highlightBlobLines
|
||||
$(window).on("hashchange", highlightBlobLines)
|
||||
|
||||
|
||||
@BlobView = BlobView
|
||||
|
||||
@@ -4,13 +4,13 @@ class CommitsList
|
||||
limit: 0
|
||||
offset: 0
|
||||
@disable = false
|
||||
|
||||
|
||||
@showProgress: ->
|
||||
$('.loading').show()
|
||||
|
||||
|
||||
@hideProgress: ->
|
||||
$('.loading').hide()
|
||||
|
||||
|
||||
@init: (ref, limit) ->
|
||||
$(".day-commits-table li.commit").live 'click', (event) ->
|
||||
if event.target.nodeName != "A"
|
||||
@@ -21,7 +21,7 @@ class CommitsList
|
||||
@data.ref = ref
|
||||
@data.limit = limit
|
||||
@data.offset = limit
|
||||
|
||||
|
||||
this.initLoadMore()
|
||||
this.showProgress()
|
||||
|
||||
@@ -32,7 +32,9 @@ class CommitsList
|
||||
url: location.href
|
||||
data: @data
|
||||
complete: this.hideProgress
|
||||
dataType: "script"
|
||||
success: (data) ->
|
||||
CommitsList.append(data.count, data.html)
|
||||
dataType: "json"
|
||||
|
||||
@append: (count, html) ->
|
||||
$("#commits-list").append(html)
|
||||
@@ -40,7 +42,7 @@ class CommitsList
|
||||
@data.offset += count
|
||||
else
|
||||
@disable = true
|
||||
|
||||
|
||||
@initLoadMore: ->
|
||||
$(document).unbind('scroll')
|
||||
$(document).endlessScroll
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
backgroundColor: '#DDD'
|
||||
opacity: .4
|
||||
)
|
||||
|
||||
|
||||
reload: ->
|
||||
Issues.initSelects()
|
||||
Issues.initChecks()
|
||||
@@ -54,7 +54,16 @@
|
||||
unless terms is last_terms
|
||||
last_terms = terms
|
||||
if terms.length >= 2 or terms.length is 0
|
||||
form.submit()
|
||||
$.ajax
|
||||
type: "GET"
|
||||
url: location.href
|
||||
data: "issue_search=" + terms
|
||||
complete: ->
|
||||
$(".loading").hide()
|
||||
success: (data) ->
|
||||
$('.issues-holder').html(data.html)
|
||||
Issues.reload()
|
||||
dataType: "json"
|
||||
|
||||
checkChanged: ->
|
||||
checked_issues = $(".selected_issue:checked")
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
window.updatePage = (data) ->
|
||||
$.ajax({type: "GET", url: location.href, data: data, dataType: "script"})
|
||||
|
||||
window.slugify = (text) ->
|
||||
text.replace(/[^-a-zA-Z0-9]+/g, '_').toLowerCase()
|
||||
|
||||
@@ -56,7 +53,7 @@ window.unbindEvents = ->
|
||||
|
||||
document.addEventListener("page:fetch", startSpinner)
|
||||
document.addEventListener("page:fetch", unbindEvents)
|
||||
document.addEventListener("page:receive", stopSpinner)
|
||||
document.addEventListener("page:change", stopSpinner)
|
||||
|
||||
$ ->
|
||||
# Click a .one_click_select field, select the contents
|
||||
|
||||
@@ -21,7 +21,7 @@ class MergeRequest
|
||||
this.initMergeWidget()
|
||||
this.$('.show-all-commits').on 'click', =>
|
||||
this.showAllCommits()
|
||||
|
||||
|
||||
modal = $('#modal_merge_info').modal(show: false)
|
||||
|
||||
# Local jQuery finder
|
||||
@@ -83,12 +83,12 @@ class MergeRequest
|
||||
url: this.$('.nav-tabs .diffs-tab a').attr('href')
|
||||
beforeSend: =>
|
||||
this.$('.status').addClass 'loading'
|
||||
|
||||
complete: =>
|
||||
@diffs_loaded = true
|
||||
this.$('.status').removeClass 'loading'
|
||||
|
||||
dataType: 'script'
|
||||
success: (data) =>
|
||||
this.$(".diffs").html(data.html)
|
||||
dataType: 'json'
|
||||
|
||||
showAllCommits: ->
|
||||
this.$('.first-commits').remove()
|
||||
|
||||
@@ -6,7 +6,7 @@ var NoteList = {
|
||||
target_type: null,
|
||||
|
||||
init: function(tid, tt, path) {
|
||||
NoteList.notes_path = path + ".js";
|
||||
NoteList.notes_path = path + ".json";
|
||||
NoteList.target_id = tid;
|
||||
NoteList.target_type = tt;
|
||||
NoteList.target_params = "target_type=" + NoteList.target_type + "&target_id=" + NoteList.target_id;
|
||||
@@ -411,7 +411,10 @@ var NoteList = {
|
||||
data: NoteList.target_params,
|
||||
complete: function(){ $('.js-notes-busy').removeClass("loading")},
|
||||
beforeSend: function() { $('.js-notes-busy').addClass("loading") },
|
||||
dataType: "script"
|
||||
success: function(data) {
|
||||
NoteList.setContent(data.html);
|
||||
},
|
||||
dataType: "json"
|
||||
});
|
||||
},
|
||||
|
||||
@@ -419,7 +422,7 @@ var NoteList = {
|
||||
* Called in response to getContent().
|
||||
* Replaces the content of #notes-list with the given html.
|
||||
*/
|
||||
setContent: function(newNoteIds, html) {
|
||||
setContent: function(html) {
|
||||
$("#notes-list").html(html);
|
||||
},
|
||||
|
||||
|
||||
@@ -19,8 +19,9 @@
|
||||
data: "limit=" + @limit + "&offset=" + @offset
|
||||
complete: ->
|
||||
$(".loading").hide()
|
||||
|
||||
dataType: "script"
|
||||
success: (data) ->
|
||||
Pager.append(data.count, data.html)
|
||||
dataType: "json"
|
||||
|
||||
append: (count, html) ->
|
||||
$(".content_list").append html
|
||||
|
||||
@@ -5,6 +5,7 @@ html {
|
||||
/** LAYOUT **/
|
||||
|
||||
body {
|
||||
-webkit-font-smoothing: antialiased;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
@@ -354,6 +355,7 @@ table {
|
||||
.navbar-gitlab .navbar-inner .nav > li .btn-sign-in {
|
||||
@extend .btn-new;
|
||||
padding: 5px 15px;
|
||||
text-shadow: none;
|
||||
}
|
||||
|
||||
.broadcast-message {
|
||||
@@ -369,6 +371,10 @@ table {
|
||||
&.input-large {
|
||||
width: 210px;
|
||||
}
|
||||
|
||||
&.input-clamp {
|
||||
max-width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.user-result {
|
||||
|
||||
@@ -72,10 +72,11 @@
|
||||
|
||||
.ui-box-head {
|
||||
.box-title {
|
||||
font-size: 18px;
|
||||
font-weight: normal;
|
||||
font-size: 20px;
|
||||
font-weight: 500;
|
||||
line-height: 28px;
|
||||
margin: 0;
|
||||
color: #444;
|
||||
}
|
||||
h3 {
|
||||
margin: 0;
|
||||
@@ -154,7 +155,7 @@
|
||||
}
|
||||
|
||||
.row_title {
|
||||
font-weight: bold;
|
||||
font-weight: 500;
|
||||
color: #444;
|
||||
&:hover {
|
||||
color: #444;
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
.cblue { color: #29A }
|
||||
.cblack { color: #111 }
|
||||
.cdark { color: #444 }
|
||||
.camber { color: #ffc000 }
|
||||
.cwhite { color: #fff!important }
|
||||
.bgred { background: #F2DEDE!important }
|
||||
|
||||
@@ -127,3 +128,8 @@ pre.well-pre {
|
||||
.dropdown-menu > li > a {
|
||||
text-shadow: none;
|
||||
}
|
||||
|
||||
.dropdown-menu > li > a:hover,
|
||||
.dropdown-menu > li > a:focus {
|
||||
background: #29b;
|
||||
}
|
||||
|
||||
@@ -13,6 +13,13 @@ form {
|
||||
margin-top: 1px !important;
|
||||
}
|
||||
}
|
||||
|
||||
&.list-label {
|
||||
float: none;
|
||||
padding: 0 !important;
|
||||
margin: 0;
|
||||
text-align: left;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -15,18 +15,16 @@
|
||||
> li > a {
|
||||
border-left: 4px solid #EEE;
|
||||
padding: 12px;
|
||||
color: #777;
|
||||
}
|
||||
> .active > a {
|
||||
border-color: $primary_color;
|
||||
border-radius: 0;
|
||||
background: #F1F1F1;
|
||||
color: $style_color;
|
||||
font-weight: bold;
|
||||
text-shadow: 0 1px 1px #fff;
|
||||
background: none;
|
||||
color: #333;
|
||||
font-weight: bolder;
|
||||
}
|
||||
|
||||
&.nav-stacked-menu {
|
||||
background: #FAFAFA;
|
||||
li > a {
|
||||
padding: 16px;
|
||||
}
|
||||
@@ -36,6 +34,7 @@
|
||||
&.nav-pills-small {
|
||||
> li > a {
|
||||
padding: 8px 12px;
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,15 @@
|
||||
label { width: 110px; }
|
||||
.controls { margin-left: 130px; }
|
||||
.form-actions { padding-left: 130px; background: #fff }
|
||||
.visibility-levels {
|
||||
.controls {
|
||||
margin-bottom: 9px;
|
||||
}
|
||||
|
||||
i {
|
||||
color: inherit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.broadcast-messages {
|
||||
|
||||
@@ -70,7 +70,7 @@
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
.old_line, .new_line {
|
||||
.old_line, .new_line, .diff_line {
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
border: none;
|
||||
@@ -92,6 +92,15 @@
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
&.new {
|
||||
background: #CFD;
|
||||
}
|
||||
&.old {
|
||||
background: #FDD;
|
||||
}
|
||||
}
|
||||
.diff_line {
|
||||
padding: 0;
|
||||
}
|
||||
.line_holder {
|
||||
&.old .old_line,
|
||||
@@ -122,6 +131,11 @@
|
||||
color: #ccc;
|
||||
background: #fafafa;
|
||||
}
|
||||
&.parallel {
|
||||
display: table-cell;
|
||||
overflow: hidden;
|
||||
width: 50%;
|
||||
}
|
||||
}
|
||||
}
|
||||
.image {
|
||||
@@ -468,8 +482,8 @@ li.commit {
|
||||
}
|
||||
|
||||
.commit-row-message {
|
||||
color: #555;
|
||||
font-weight: bolder;
|
||||
color: #333;
|
||||
font-weight: 500;
|
||||
&:hover {
|
||||
color: #444;
|
||||
text-decoration: underline;
|
||||
@@ -478,13 +492,14 @@ li.commit {
|
||||
}
|
||||
|
||||
.commit-row-info {
|
||||
color: #777;
|
||||
|
||||
a {
|
||||
color: #777;
|
||||
}
|
||||
|
||||
.committed_ago {
|
||||
float: right;
|
||||
@extend .cgray;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -100,3 +100,21 @@
|
||||
padding: 2px 5px;
|
||||
}
|
||||
}
|
||||
|
||||
.project-access-icon {
|
||||
margin-left: 10px;
|
||||
float: left;
|
||||
margin-right: 15px;
|
||||
font-size: 20px;
|
||||
margin-bottom: 15px;
|
||||
border: 1px solid #EEE;
|
||||
padding: 8px 12px;
|
||||
border-radius: 50px;
|
||||
background: #f5f5f5;
|
||||
width: 16px;
|
||||
text-align: center;
|
||||
|
||||
i {
|
||||
color: #BBB;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,8 +46,8 @@ header {
|
||||
|
||||
h1 {
|
||||
margin: 0;
|
||||
background: url('logo-black.png') no-repeat center 1px;
|
||||
background-size: 38px;
|
||||
background: url('logo-black.png') no-repeat center center;
|
||||
background-size: 32px;
|
||||
float: left;
|
||||
height: 40px;
|
||||
width: 40px;
|
||||
@@ -152,8 +152,8 @@ header {
|
||||
.app_logo {
|
||||
a {
|
||||
h1 {
|
||||
background: url('logo-white.png') no-repeat center 1px;
|
||||
background-size: 38px;
|
||||
background: url('logo-white.png') no-repeat center center;
|
||||
background-size: 32px;
|
||||
color: #fff;
|
||||
text-shadow: 0 1px 1px #444;
|
||||
}
|
||||
|
||||
@@ -77,8 +77,8 @@ input.check_all_issues {
|
||||
@media (min-width: 800px) { .issues_filters select { width: 160px; } }
|
||||
@media (min-width: 1200px) { .issues_filters select { width: 220px; } }
|
||||
|
||||
@media (min-width: 800px) { .issues_bulk_update select { width: 120px; } }
|
||||
@media (min-width: 1200px) { .issues_bulk_update select { width: 160px; } }
|
||||
@media (min-width: 800px) { .issues_bulk_update .chosen-container { min-width: 120px; } }
|
||||
@media (min-width: 1200px) { .issues_bulk_update .chosen-container { min-width: 160px; } }
|
||||
|
||||
.issues-holder {
|
||||
.issues_filters {
|
||||
@@ -103,3 +103,19 @@ input.check_all_issues {
|
||||
.participants {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.issues_bulk_update {
|
||||
.chosen-container {
|
||||
text-shadow: none;
|
||||
}
|
||||
}
|
||||
|
||||
.issue-search-form {
|
||||
margin: 0;
|
||||
height: 24px;
|
||||
|
||||
.issue_search {
|
||||
border: 1px solid #DDD !important;
|
||||
background-color: #f4f4f4;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,3 +46,10 @@ body.login-page{
|
||||
margin: 2px;
|
||||
}
|
||||
}
|
||||
|
||||
.devise-errors {
|
||||
h2 {
|
||||
font-size: 14px;
|
||||
color: #a00;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -130,6 +130,12 @@ ul.notes {
|
||||
&.notes_line {
|
||||
text-align: center;
|
||||
padding: 10px 0;
|
||||
background: #eee;
|
||||
}
|
||||
&.notes_line2 {
|
||||
text-align: center;
|
||||
padding: 10px 0;
|
||||
border-left: 1px solid #ddd !important;
|
||||
}
|
||||
&.notes_content {
|
||||
background-color: $white;
|
||||
@@ -270,10 +276,9 @@ ul.notes {
|
||||
|
||||
// preview/edit buttons
|
||||
> a {
|
||||
font-size: 24px;
|
||||
padding: 4px;
|
||||
position: absolute;
|
||||
right: 10px;
|
||||
right: 5px;
|
||||
bottom: -60px;
|
||||
}
|
||||
.note_preview {
|
||||
background: #f5f5f5;
|
||||
@@ -306,10 +311,8 @@ ul.notes {
|
||||
|
||||
.common-note-form {
|
||||
margin: 0;
|
||||
height: 140px;
|
||||
background: #F9F9F9;
|
||||
padding: 3px;
|
||||
padding-bottom: 25px;
|
||||
border: 1px solid #DDD;
|
||||
}
|
||||
|
||||
@@ -320,7 +323,7 @@ ul.notes {
|
||||
padding: 0 5px;
|
||||
|
||||
.note-form-option {
|
||||
margin-top: 10px;
|
||||
margin-top: 8px;
|
||||
margin-left: 30px;
|
||||
@extend .pull-left;
|
||||
}
|
||||
@@ -358,3 +361,7 @@ ul.notes {
|
||||
.js-note-attachment-delete {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.parallel-comment {
|
||||
padding: 6px;
|
||||
}
|
||||
|
||||
@@ -42,3 +42,8 @@
|
||||
margin-right: 12px;
|
||||
}
|
||||
|
||||
.profile-avatar-form-option {
|
||||
hr {
|
||||
margin: 10px 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,12 @@
|
||||
padding-bottom: 25px;
|
||||
margin-bottom: 30px;
|
||||
|
||||
&.empty-project {
|
||||
border-bottom: 0px;
|
||||
padding-bottom: 15px;
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
|
||||
.project-home-title {
|
||||
font-size: 18px;
|
||||
color: #777;
|
||||
@@ -45,7 +51,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
.public-label {
|
||||
.visibility-level-label {
|
||||
font-size: 14px;
|
||||
background: #f1f1f1;
|
||||
padding: 8px 10px;
|
||||
@@ -53,6 +59,10 @@
|
||||
margin-left: 10px;
|
||||
color: #888;
|
||||
text-shadow: 0 1px 1px #FFF;
|
||||
|
||||
i {
|
||||
color: inherit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,13 +71,24 @@
|
||||
border: 1px solid #E1E1E1;
|
||||
@include border-radius(4px);
|
||||
|
||||
input[type="text"],
|
||||
.btn {
|
||||
margin-left: 3px;
|
||||
border: none;
|
||||
background: none;
|
||||
@include border-radius(0px);
|
||||
border-left: 1px solid #E1E1E1;
|
||||
box-shadow: none;
|
||||
padding: 6px 10px;
|
||||
}
|
||||
|
||||
.btn {
|
||||
float: left;
|
||||
background: none;
|
||||
color: #29b;
|
||||
padding: 6px;
|
||||
|
||||
&:first-child {
|
||||
@include border-radius-left(4px);
|
||||
border-left: 0px;
|
||||
}
|
||||
|
||||
&.active {
|
||||
color: #333;
|
||||
@@ -76,20 +97,46 @@
|
||||
}
|
||||
|
||||
input[type="text"] {
|
||||
margin-left: 2px;
|
||||
border: none;
|
||||
border-radius: 0;
|
||||
border-left: 1px solid #E1E1E1;
|
||||
cursor: auto;
|
||||
@extend .monospace;
|
||||
box-shadow: none;
|
||||
background: #FAFAFA;
|
||||
padding: 6px 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.project-public-holder {
|
||||
.help-inline {
|
||||
padding-top: 7px;
|
||||
.project-visibility-level-holder {
|
||||
.controls {
|
||||
padding-bottom: 9px;
|
||||
}
|
||||
|
||||
.controls {
|
||||
input {
|
||||
float: left;
|
||||
}
|
||||
.descr {
|
||||
display: block;
|
||||
margin-left: 1.5em;
|
||||
&.restricted {
|
||||
color: #888;
|
||||
}
|
||||
|
||||
label {
|
||||
float: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
text-align: left;
|
||||
}
|
||||
}
|
||||
.info {
|
||||
display: block;
|
||||
margin-top: 5px;
|
||||
}
|
||||
strong {
|
||||
display: inline-block;
|
||||
width: 4em;
|
||||
}
|
||||
}
|
||||
i {
|
||||
color: inherit;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -130,7 +177,8 @@ ul.nav.nav-projects-tabs {
|
||||
margin: 0px;
|
||||
}
|
||||
|
||||
.my-projects {
|
||||
.my-projects,
|
||||
.public-projects {
|
||||
li {
|
||||
.project-info {
|
||||
margin-bottom: 10px;
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
require_relative "base_context"
|
||||
|
||||
module Files
|
||||
class CreateContext < BaseContext
|
||||
def execute
|
||||
@@ -19,13 +21,13 @@ module Files
|
||||
file_path = path
|
||||
|
||||
unless file_name =~ Gitlab::Regex.path_regex
|
||||
return error("Your changes could not be commited, because file name contains not allowed characters")
|
||||
return error("Your changes could not be committed, because file name contains not allowed characters")
|
||||
end
|
||||
|
||||
blob = repository.blob_at(ref, file_path)
|
||||
|
||||
if blob
|
||||
return error("Your changes could not be commited, because file with such name exists")
|
||||
return error("Your changes could not be committed, because file with such name exists")
|
||||
end
|
||||
|
||||
new_file_action = Gitlab::Satellite::NewFileAction.new(current_user, project, ref, file_path)
|
||||
@@ -37,7 +39,7 @@ module Files
|
||||
if created_successfully
|
||||
success
|
||||
else
|
||||
error("Your changes could not be commited, because the file has been changed")
|
||||
error("Your changes could not be committed, because the file has been changed")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
require_relative "base_context"
|
||||
|
||||
module Files
|
||||
class DeleteContext < BaseContext
|
||||
def execute
|
||||
@@ -31,7 +33,7 @@ module Files
|
||||
if deleted_successfully
|
||||
success
|
||||
else
|
||||
error("Your changes could not be commited, because the file has been changed")
|
||||
error("Your changes could not be committed, because the file has been changed")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
require_relative "base_context"
|
||||
|
||||
module Files
|
||||
class UpdateContext < BaseContext
|
||||
def execute
|
||||
@@ -30,7 +32,7 @@ module Files
|
||||
if created_successfully
|
||||
success
|
||||
else
|
||||
error("Your changes could not be commited, because the file has been changed")
|
||||
error("Your changes could not be committed, because the file has been changed")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -22,7 +22,7 @@ module Issues
|
||||
opts[:milestone_id] = milestone_id if milestone_id.present?
|
||||
opts[:assignee_id] = assignee_id if assignee_id.present?
|
||||
|
||||
issues = Issue.where(id: issues_ids).all
|
||||
issues = Issue.where(id: issues_ids)
|
||||
issues = issues.select { |issue| can?(current_user, :modify_issue, issue) }
|
||||
|
||||
issues.each do |issue|
|
||||
|
||||
@@ -29,8 +29,26 @@ module Issues
|
||||
if params[:milestone_id].present?
|
||||
@issues = @issues.where(milestone_id: (params[:milestone_id] == '0' ? nil : params[:milestone_id]))
|
||||
end
|
||||
|
||||
# Sort by :sort param
|
||||
@issues = sort(@issues, params[:sort])
|
||||
|
||||
@issues
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def sort(issues, condition)
|
||||
case condition
|
||||
when 'newest' then issues.except(:order).order('created_at DESC')
|
||||
when 'oldest' then issues.except(:order).order('created_at ASC')
|
||||
when 'recently_updated' then issues.except(:order).order('updated_at DESC')
|
||||
when 'last_updated' then issues.except(:order).order('updated_at ASC')
|
||||
when 'milestone_due_soon' then issues.except(:order).joins(:milestone).order("milestones.due_date ASC")
|
||||
when 'milestone_due_later' then issues.except(:order).joins(:milestone).order("milestones.due_date DESC")
|
||||
else issues
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
@@ -8,6 +8,11 @@ module Projects
|
||||
# get namespace id
|
||||
namespace_id = params.delete(:namespace_id)
|
||||
|
||||
# check that user is allowed to set specified visibility_level
|
||||
unless Gitlab::VisibilityLevel.allowed_for?(current_user, params[:visibility_level])
|
||||
params.delete(:visibility_level)
|
||||
end
|
||||
|
||||
# Load default feature settings
|
||||
default_features = Gitlab.config.gitlab.default_projects_features
|
||||
|
||||
@@ -17,7 +22,7 @@ module Projects
|
||||
wall_enabled: default_features.wall,
|
||||
snippets_enabled: default_features.snippets,
|
||||
merge_requests_enabled: default_features.merge_requests,
|
||||
public: default_features.public
|
||||
visibility_level: default_features.visibility_level
|
||||
}.stringify_keys
|
||||
|
||||
@project = Project.new(default_opts.merge(params))
|
||||
|
||||
@@ -2,15 +2,15 @@ module Projects
|
||||
class UpdateContext < BaseContext
|
||||
def execute(role = :default)
|
||||
params[:project].delete(:namespace_id)
|
||||
params[:project].delete(:public) unless can?(current_user, :change_public_mode, project)
|
||||
# check that user is allowed to set specified visibility_level
|
||||
unless can?(current_user, :change_visibility_level, project) && Gitlab::VisibilityLevel.allowed_for?(current_user, params[:project][:visibility_level])
|
||||
params[:project].delete(:visibility_level)
|
||||
end
|
||||
|
||||
new_branch = params[:project].delete(:default_branch)
|
||||
|
||||
if project.repository.exists? && new_branch != project.repository.root_ref
|
||||
GitlabShellWorker.perform_async(
|
||||
:update_repository_head,
|
||||
project.path_with_namespace,
|
||||
new_branch
|
||||
)
|
||||
if project.repository.exists? && new_branch != project.default_branch
|
||||
project.change_head(new_branch)
|
||||
end
|
||||
|
||||
project.update_attributes(params[:project], as: role)
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
class SearchContext
|
||||
attr_accessor :project_ids, :params
|
||||
attr_accessor :project_ids, :current_user, :params
|
||||
|
||||
def initialize(project_ids, params)
|
||||
@project_ids, @params = project_ids, params.dup
|
||||
def initialize(project_ids, user, params)
|
||||
@project_ids, @current_user, @params = project_ids, user, params.dup
|
||||
end
|
||||
|
||||
def execute
|
||||
@@ -10,7 +10,8 @@ class SearchContext
|
||||
query = Shellwords.shellescape(query) if query.present?
|
||||
|
||||
return result unless query.present?
|
||||
result[:projects] = Project.where("projects.id in (?) OR projects.public = true", project_ids).search(query).limit(20)
|
||||
visibility_levels = @current_user ? [ Gitlab::VisibilityLevel::INTERNAL, Gitlab::VisibilityLevel::PUBLIC ] : [ Gitlab::VisibilityLevel::PUBLIC ]
|
||||
result[:projects] = Project.where("projects.id in (?) OR projects.visibility_level in (?)", project_ids, visibility_levels).search(query).limit(20)
|
||||
|
||||
# Search inside single project
|
||||
single_project_search(Project.where(id: project_ids), query)
|
||||
|
||||
@@ -7,8 +7,8 @@ class Admin::ProjectsController < Admin::ApplicationController
|
||||
owner_id = params[:owner_id]
|
||||
user = User.find_by_id(owner_id)
|
||||
|
||||
@projects = user ? user.owned_projects : Project.scoped
|
||||
@projects = @projects.where(public: true) if params[:public_only].present?
|
||||
@projects = user ? user.owned_projects : Project.all
|
||||
@projects = @projects.where("visibility_level IN (?)", params[:visibility_levels]) if params[:visibility_levels].present?
|
||||
@projects = @projects.with_push if params[:with_push].present?
|
||||
@projects = @projects.abandoned if params[:abandoned].present?
|
||||
@projects = @projects.search(params[:name]) if params[:name].present?
|
||||
|
||||
@@ -2,8 +2,7 @@ class Admin::UsersController < Admin::ApplicationController
|
||||
before_filter :user, only: [:show, :edit, :update, :destroy]
|
||||
|
||||
def index
|
||||
@users = User.scoped
|
||||
@users = @users.filter(params[:filter])
|
||||
@users = User.filter(params[:filter])
|
||||
@users = @users.search(params[:name]) if params[:name].present?
|
||||
@users = @users.alphabetically.page(params[:page])
|
||||
end
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
require 'gon'
|
||||
|
||||
class ApplicationController < ActionController::Base
|
||||
before_filter :authenticate_user!
|
||||
before_filter :reject_blocked!
|
||||
@@ -8,6 +10,7 @@ class ApplicationController < ActionController::Base
|
||||
before_filter :dev_tools if Rails.env == 'development'
|
||||
before_filter :default_headers
|
||||
before_filter :add_gon_variables
|
||||
before_filter :configure_permitted_parameters, if: :devise_controller?
|
||||
|
||||
protect_from_forgery
|
||||
|
||||
@@ -82,6 +85,9 @@ class ApplicationController < ActionController::Base
|
||||
|
||||
if @project and can?(current_user, :read_project, @project)
|
||||
@project
|
||||
elsif current_user.nil?
|
||||
@project = nil
|
||||
authenticate_user!
|
||||
else
|
||||
@project = nil
|
||||
render_404 and return
|
||||
@@ -103,7 +109,7 @@ class ApplicationController < ActionController::Base
|
||||
end
|
||||
|
||||
def authorize_code_access!
|
||||
return access_denied! unless can?(current_user, :download_code, project) or project.public?
|
||||
return access_denied! unless can?(current_user, :download_code, project)
|
||||
end
|
||||
|
||||
def authorize_push!
|
||||
@@ -193,4 +199,31 @@ class ApplicationController < ActionController::Base
|
||||
def gitlab_ldap_access
|
||||
Gitlab::LDAP::Access.new
|
||||
end
|
||||
|
||||
# JSON for infinite scroll via Pager object
|
||||
def pager_json(partial, count)
|
||||
html = render_to_string(
|
||||
partial,
|
||||
layout: false,
|
||||
formats: [:html]
|
||||
)
|
||||
|
||||
render json: {
|
||||
html: html,
|
||||
count: count
|
||||
}
|
||||
end
|
||||
|
||||
def view_to_html_string(partial)
|
||||
render_to_string(
|
||||
partial,
|
||||
layout: false,
|
||||
formats: [:html]
|
||||
)
|
||||
end
|
||||
|
||||
def configure_permitted_parameters
|
||||
devise_parameter_sanitizer.for(:sign_in) { |u| u.permit(:username, :email, :password) }
|
||||
devise_parameter_sanitizer.for(:sign_up) { |u| u.permit(:username, :email, :name, :password, :password_confirmation) }
|
||||
end
|
||||
end
|
||||
|
||||
@@ -22,7 +22,7 @@ class DashboardController < ApplicationController
|
||||
|
||||
respond_to do |format|
|
||||
format.html
|
||||
format.js
|
||||
format.json { pager_json("events/_events", @events.count) }
|
||||
format.atom { render layout: false }
|
||||
end
|
||||
end
|
||||
@@ -40,6 +40,7 @@ class DashboardController < ApplicationController
|
||||
end
|
||||
|
||||
@projects = @projects.where(namespace_id: Group.find_by_name(params[:group])) if params[:group].present?
|
||||
@projects = @projects.where(visibility_level: params[:visibility_level]) if params[:visibility_level].present?
|
||||
@projects = @projects.includes(:namespace).sorted_by_activity
|
||||
|
||||
@labels = current_user.authorized_projects.tags_on(:labels)
|
||||
@@ -72,6 +73,6 @@ class DashboardController < ApplicationController
|
||||
protected
|
||||
|
||||
def load_projects
|
||||
@projects = current_user.authorized_projects.sorted_by_activity
|
||||
@projects = current_user.authorized_projects.sorted_by_activity.non_archived
|
||||
end
|
||||
end
|
||||
|
||||
@@ -40,7 +40,7 @@ class GroupsController < ApplicationController
|
||||
|
||||
respond_to do |format|
|
||||
format.html
|
||||
format.js
|
||||
format.json { pager_json("events/_events", @events.count) }
|
||||
format.atom { render layout: false }
|
||||
end
|
||||
end
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
class Profiles::AvatarsController < ApplicationController
|
||||
layout "profile"
|
||||
|
||||
def destroy
|
||||
@user = current_user
|
||||
@user.remove_avatar!
|
||||
|
||||
@user.save
|
||||
@user.reset_events_cache
|
||||
|
||||
redirect_to profile_path
|
||||
end
|
||||
end
|
||||
@@ -2,7 +2,7 @@ class Profiles::KeysController < ApplicationController
|
||||
layout "profile"
|
||||
|
||||
def index
|
||||
@keys = current_user.keys.order('id DESC').all
|
||||
@keys = current_user.keys.order('id DESC')
|
||||
end
|
||||
|
||||
def show
|
||||
|
||||
@@ -13,6 +13,8 @@ class ProfilesController < ApplicationController
|
||||
end
|
||||
|
||||
def update
|
||||
params[:user].delete(:email) if @user.ldap_user?
|
||||
|
||||
if @user.update_attributes(params[:user])
|
||||
flash[:notice] = "Profile was successfully updated"
|
||||
else
|
||||
|
||||
@@ -10,7 +10,7 @@ class Projects::ApplicationController < ApplicationController
|
||||
id = params[:project_id] || params[:id]
|
||||
@project = Project.find_with_namespace(id)
|
||||
|
||||
return if @project && @project.public
|
||||
return if @project && @project.public?
|
||||
end
|
||||
|
||||
super
|
||||
|
||||
@@ -16,7 +16,7 @@ class Projects::BlobController < Projects::ApplicationController
|
||||
result = Files::DeleteContext.new(@project, current_user, params, @ref, @path).execute
|
||||
|
||||
if result[:status] == :success
|
||||
flash[:notice] = "Your changes have been successfully commited"
|
||||
flash[:notice] = "Your changes have been successfully committed"
|
||||
redirect_to project_tree_path(@project, @ref)
|
||||
else
|
||||
flash[:alert] = result[:error]
|
||||
|
||||
@@ -16,7 +16,7 @@ class Projects::CommitsController < Projects::ApplicationController
|
||||
|
||||
respond_to do |format|
|
||||
format.html # index.html.erb
|
||||
format.js
|
||||
format.json { pager_json("projects/commits/_commits", @commits.size) }
|
||||
format.atom { render layout: false }
|
||||
end
|
||||
end
|
||||
|
||||
@@ -7,7 +7,7 @@ class Projects::DeployKeysController < Projects::ApplicationController
|
||||
layout "project_settings"
|
||||
|
||||
def index
|
||||
@enabled_keys = @project.deploy_keys.all
|
||||
@enabled_keys = @project.deploy_keys
|
||||
@available_keys = available_keys - @enabled_keys
|
||||
end
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ class Projects::EditTreeController < Projects::BaseTreeController
|
||||
result = Files::UpdateContext.new(@project, current_user, params, @ref, @path).execute
|
||||
|
||||
if result[:status] == :success
|
||||
flash[:notice] = "Your changes have been successfully commited"
|
||||
flash[:notice] = "Your changes have been successfully committed"
|
||||
redirect_to project_blob_path(@project, @id)
|
||||
else
|
||||
flash[:alert] = result[:error]
|
||||
|
||||
@@ -7,7 +7,7 @@ class Projects::HooksController < Projects::ApplicationController
|
||||
layout "project_settings"
|
||||
|
||||
def index
|
||||
@hooks = @project.hooks.all
|
||||
@hooks = @project.hooks
|
||||
@hook = ProjectHook.new
|
||||
end
|
||||
|
||||
@@ -18,7 +18,7 @@ class Projects::HooksController < Projects::ApplicationController
|
||||
if @hook.valid?
|
||||
redirect_to project_hooks_path(@project)
|
||||
else
|
||||
@hooks = @project.hooks.all
|
||||
@hooks = @project.hooks
|
||||
render :index
|
||||
end
|
||||
end
|
||||
|
||||
@@ -11,7 +11,7 @@ class Projects::IssuesController < Projects::ApplicationController
|
||||
# Allow modify issue
|
||||
before_filter :authorize_modify_issue!, only: [:edit, :update]
|
||||
|
||||
respond_to :js, :html
|
||||
respond_to :html
|
||||
|
||||
def index
|
||||
terms = params['issue_search']
|
||||
@@ -23,11 +23,18 @@ class Projects::IssuesController < Projects::ApplicationController
|
||||
assignee_id, milestone_id = params[:assignee_id], params[:milestone_id]
|
||||
@assignee = @project.team.find(assignee_id) if assignee_id.present? && !assignee_id.to_i.zero?
|
||||
@milestone = @project.milestones.find(milestone_id) if milestone_id.present? && !milestone_id.to_i.zero?
|
||||
sort_param = params[:sort] || 'newest'
|
||||
@sort = sort_param.humanize unless sort_param.empty?
|
||||
|
||||
|
||||
respond_to do |format|
|
||||
format.html # index.html.erb
|
||||
format.js
|
||||
format.html
|
||||
format.atom { render layout: false }
|
||||
format.json do
|
||||
render json: {
|
||||
html: view_to_html_string("projects/issues/_issues")
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -45,10 +52,7 @@ class Projects::IssuesController < Projects::ApplicationController
|
||||
@target_type = :issue
|
||||
@target_id = @issue.id
|
||||
|
||||
respond_to do |format|
|
||||
format.html
|
||||
format.js
|
||||
end
|
||||
respond_with(@issue)
|
||||
end
|
||||
|
||||
def create
|
||||
@@ -70,6 +74,7 @@ class Projects::IssuesController < Projects::ApplicationController
|
||||
|
||||
def update
|
||||
@issue.update_attributes(params[:issue].merge(author_id_of_changes: current_user.id))
|
||||
@issue.reset_events_cache
|
||||
|
||||
respond_to do |format|
|
||||
format.js
|
||||
|
||||
@@ -2,8 +2,8 @@ require 'gitlab/satellite/satellite'
|
||||
|
||||
class Projects::MergeRequestsController < Projects::ApplicationController
|
||||
before_filter :module_enabled
|
||||
before_filter :merge_request, only: [:edit, :update, :show, :commits, :diffs, :automerge, :automerge_check, :ci_status]
|
||||
before_filter :closes_issues, only: [:edit, :update, :show, :commits, :diffs]
|
||||
before_filter :merge_request, only: [:edit, :update, :show, :diffs, :automerge, :automerge_check, :ci_status]
|
||||
before_filter :closes_issues, only: [:edit, :update, :show, :diffs]
|
||||
before_filter :validates_merge_request, only: [:show, :diffs]
|
||||
before_filter :define_show_vars, only: [:show, :diffs]
|
||||
|
||||
@@ -26,8 +26,6 @@ class Projects::MergeRequestsController < Projects::ApplicationController
|
||||
def show
|
||||
respond_to do |format|
|
||||
format.html
|
||||
format.js
|
||||
|
||||
format.diff { render text: @merge_request.to_diff(current_user) }
|
||||
format.patch { render text: @merge_request.to_patch(current_user) }
|
||||
end
|
||||
@@ -44,6 +42,11 @@ class Projects::MergeRequestsController < Projects::ApplicationController
|
||||
diff_line_count = Commit::diff_line_count(@merge_request.diffs)
|
||||
@suppress_diff = Commit::diff_suppress?(@merge_request.diffs, diff_line_count) && !params[:force_show_diff]
|
||||
@force_suppress_diff = Commit::diff_force_suppress?(@merge_request.diffs, diff_line_count)
|
||||
|
||||
respond_to do |format|
|
||||
format.html
|
||||
format.json { render json: { html: view_to_html_string("projects/merge_requests/show/_diffs") } }
|
||||
end
|
||||
end
|
||||
|
||||
def new
|
||||
@@ -76,9 +79,30 @@ class Projects::MergeRequestsController < Projects::ApplicationController
|
||||
end
|
||||
|
||||
def update
|
||||
# If we close MergeRequest we want to ignore validation
|
||||
# so we can close broken one (Ex. fork project removed)
|
||||
if params[:merge_request] == {"state_event"=>"close"}
|
||||
@merge_request.allow_broken = true
|
||||
|
||||
if @merge_request.close
|
||||
opts = { notice: 'Merge request was successfully closed.' }
|
||||
else
|
||||
opts = { alert: 'Failed to close merge request.' }
|
||||
end
|
||||
|
||||
redirect_to [@merge_request.target_project, @merge_request], opts
|
||||
return
|
||||
end
|
||||
|
||||
# We dont allow change of source/target projects
|
||||
# after merge request was created
|
||||
params[:merge_request].delete(:source_project_id)
|
||||
params[:merge_request].delete(:target_project_id)
|
||||
|
||||
if @merge_request.update_attributes(params[:merge_request].merge(author_id_of_changes: current_user.id))
|
||||
@merge_request.reload_code
|
||||
@merge_request.mark_as_unchecked
|
||||
@merge_request.reset_events_cache
|
||||
redirect_to [@merge_request.target_project, @merge_request], notice: 'Merge request was successfully updated.'
|
||||
else
|
||||
render "edit"
|
||||
@@ -157,14 +181,17 @@ class Projects::MergeRequestsController < Projects::ApplicationController
|
||||
end
|
||||
|
||||
def validates_merge_request
|
||||
# If source project was removed (Ex. mr from fork to origin)
|
||||
return invalid_mr unless @merge_request.source_project
|
||||
|
||||
# Show git not found page
|
||||
# if there is no saved commits between source & target branch
|
||||
if @merge_request.commits.blank?
|
||||
# and if source target doesn't exist
|
||||
return invalid_mr unless @merge_request.target_project.repository.branch_names.include?(@merge_request.target_branch)
|
||||
# and if target branch doesn't exist
|
||||
return invalid_mr unless @merge_request.target_branch_exists?
|
||||
|
||||
# or if source branch doesn't exist
|
||||
return invalid_mr unless @merge_request.source_project.repository.branch_names.include?(@merge_request.source_branch)
|
||||
# or if source branch doesn't exist
|
||||
return invalid_mr unless @merge_request.source_branch_exists?
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -34,11 +34,6 @@ class Projects::MilestonesController < Projects::ApplicationController
|
||||
@issues = @milestone.issues
|
||||
@users = @milestone.participants.uniq
|
||||
@merge_requests = @milestone.merge_requests
|
||||
|
||||
respond_to do |format|
|
||||
format.html
|
||||
format.js
|
||||
end
|
||||
end
|
||||
|
||||
def create
|
||||
|
||||
@@ -9,7 +9,7 @@ class Projects::NewTreeController < Projects::BaseTreeController
|
||||
result = Files::CreateContext.new(@project, current_user, params, @ref, file_path).execute
|
||||
|
||||
if result[:status] == :success
|
||||
flash[:notice] = "Your changes have been successfully commited"
|
||||
flash[:notice] = "Your changes have been successfully committed"
|
||||
redirect_to project_blob_path(@project, File.join(@ref, file_path))
|
||||
else
|
||||
flash[:alert] = result[:error]
|
||||
|
||||
@@ -14,7 +14,14 @@ class Projects::NotesController < Projects::ApplicationController
|
||||
@discussions = discussions_from_notes
|
||||
end
|
||||
|
||||
respond_with(@notes)
|
||||
respond_to do |format|
|
||||
format.html { redirect_to :back }
|
||||
format.json do
|
||||
render json: {
|
||||
html: view_to_html_string("projects/notes/_notes")
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def create
|
||||
@@ -32,6 +39,7 @@ class Projects::NotesController < Projects::ApplicationController
|
||||
@note = @project.notes.find(params[:id])
|
||||
return access_denied! unless can?(current_user, :admin_note, @note)
|
||||
@note.destroy
|
||||
@note.reset_events_cache
|
||||
|
||||
respond_to do |format|
|
||||
format.js { render nothing: true }
|
||||
@@ -43,6 +51,7 @@ class Projects::NotesController < Projects::ApplicationController
|
||||
return access_denied! unless can?(current_user, :admin_note, @note)
|
||||
|
||||
@note.update_attributes(params[:note])
|
||||
@note.reset_events_cache
|
||||
|
||||
respond_to do |format|
|
||||
format.js do
|
||||
|
||||
@@ -5,7 +5,7 @@ class ProjectsController < ApplicationController
|
||||
|
||||
# Authorize
|
||||
before_filter :authorize_read_project!, except: [:index, :new, :create]
|
||||
before_filter :authorize_admin_project!, only: [:edit, :update, :destroy, :transfer]
|
||||
before_filter :authorize_admin_project!, only: [:edit, :update, :destroy, :transfer, :archive, :unarchive]
|
||||
before_filter :require_non_empty_project, only: [:blob, :tree, :graph]
|
||||
|
||||
layout 'navless', only: [:new, :create, :fork]
|
||||
@@ -55,7 +55,7 @@ class ProjectsController < ApplicationController
|
||||
end
|
||||
|
||||
def show
|
||||
return authenticate_user! unless @project.public || current_user
|
||||
return authenticate_user! unless @project.public? || current_user
|
||||
|
||||
limit = (params[:limit] || 20).to_i
|
||||
@events = @project.events.recent
|
||||
@@ -73,7 +73,7 @@ class ProjectsController < ApplicationController
|
||||
render :show, layout: user_layout
|
||||
end
|
||||
end
|
||||
format.js
|
||||
format.json { pager_json("events/_events", @events.count) }
|
||||
end
|
||||
end
|
||||
|
||||
@@ -116,6 +116,24 @@ class ProjectsController < ApplicationController
|
||||
end
|
||||
end
|
||||
|
||||
def archive
|
||||
return access_denied! unless can?(current_user, :archive_project, project)
|
||||
project.archive!
|
||||
|
||||
respond_to do |format|
|
||||
format.html { redirect_to @project }
|
||||
end
|
||||
end
|
||||
|
||||
def unarchive
|
||||
return access_denied! unless can?(current_user, :archive_project, project)
|
||||
project.unarchive!
|
||||
|
||||
respond_to do |format|
|
||||
format.html { redirect_to @project }
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_title
|
||||
|
||||
@@ -6,7 +6,7 @@ class Public::ProjectsController < ApplicationController
|
||||
layout 'public'
|
||||
|
||||
def index
|
||||
@projects = Project.public_only
|
||||
@projects = Project.public_or_internal_only(current_user)
|
||||
@projects = @projects.search(params[:search]) if params[:search].present?
|
||||
@projects = @projects.includes(:namespace).order("namespaces.path, projects.name ASC").page(params[:page]).per(20)
|
||||
end
|
||||
|
||||
@@ -14,7 +14,7 @@ class SearchController < ApplicationController
|
||||
project_ids.select! { |id| id == project_id.to_i}
|
||||
end
|
||||
|
||||
result = SearchContext.new(project_ids, params).execute
|
||||
result = SearchContext.new(project_ids, current_user, params).execute
|
||||
|
||||
@projects = result[:projects]
|
||||
@merge_requests = result[:merge_requests]
|
||||
|
||||
@@ -62,7 +62,7 @@ module ApplicationHelper
|
||||
size = 40 if size.nil? || size <= 0
|
||||
|
||||
if !Gitlab.config.gravatar.enabled || user_email.blank?
|
||||
'no_avatar.png'
|
||||
'/assets/no_avatar.png'
|
||||
else
|
||||
gravatar_url = request.ssl? || gitlab_config.https ? Gitlab.config.gravatar.ssl_url : Gitlab.config.gravatar.plain_url
|
||||
user_email.strip!
|
||||
@@ -72,7 +72,7 @@ module ApplicationHelper
|
||||
|
||||
def last_commit(project)
|
||||
if project.repo_exists?
|
||||
time_ago_in_words(project.repository.commit.committed_date) + " ago"
|
||||
time_ago_with_tooltip(project.repository.commit.committed_date) + " ago"
|
||||
else
|
||||
"Never"
|
||||
end
|
||||
@@ -136,9 +136,9 @@ module ApplicationHelper
|
||||
Digest::SHA1.hexdigest string
|
||||
end
|
||||
|
||||
def project_last_activity project
|
||||
def project_last_activity(project)
|
||||
if project.last_activity_at
|
||||
time_ago_in_words(project.last_activity_at) + " ago"
|
||||
time_ago_with_tooltip(project.last_activity_at, 'bottom', 'last_activity_time_ago') + " ago"
|
||||
else
|
||||
"Never"
|
||||
end
|
||||
@@ -207,4 +207,22 @@ module ApplicationHelper
|
||||
def broadcast_message
|
||||
BroadcastMessage.current
|
||||
end
|
||||
|
||||
def highlight_js(&block)
|
||||
string = capture(&block)
|
||||
|
||||
content_tag :div, class: user_color_scheme_class do
|
||||
Pygments::Lexer[:js].highlight(string).html_safe
|
||||
end
|
||||
end
|
||||
|
||||
def time_ago_with_tooltip(date, placement = 'top', html_class = 'time_ago')
|
||||
capture_haml do
|
||||
haml_tag :time, time_ago_in_words(date),
|
||||
class: html_class, datetime: date, title: date.stamp("Aug 21, 2011 9:23pm"),
|
||||
data: { toggle: 'tooltip', placement: placement }
|
||||
|
||||
haml_tag :script, "$('." + html_class + "').tooltip()"
|
||||
end.html_safe
|
||||
end
|
||||
end
|
||||
|
||||
@@ -105,6 +105,10 @@ module CommitsHelper
|
||||
branches.sort.map { |branch| link_to(branch, project_tree_path(project, branch)) }.join(", ").html_safe
|
||||
end
|
||||
|
||||
def get_old_file(project, commit, diff)
|
||||
project.repository.blob_at(commit.parent_id, diff.old_path) if commit.parent_id
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
# Private: Returns a link to a person. If the person has a matching user and
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
module CompareHelper
|
||||
def compare_to_mr_button?
|
||||
params[:from].present? && params[:to].present? &&
|
||||
@project.merge_requests_enabled &&
|
||||
params[:from].present? &&
|
||||
params[:to].present? &&
|
||||
@repository.branch_names.include?(params[:from]) &&
|
||||
@repository.branch_names.include?(params[:to]) &&
|
||||
params[:from] != params[:to] &&
|
||||
|
||||
@@ -102,15 +102,11 @@ module EventsHelper
|
||||
end
|
||||
elsif event.note_project_snippet?
|
||||
link_to(project_snippet_path(event.project, event.note_target)) do
|
||||
content_tag :strong do
|
||||
"#{event.note_target_type} ##{truncate event.note_target_id}"
|
||||
end
|
||||
"#{event.note_target_type} ##{truncate event.note_target_id}"
|
||||
end
|
||||
else
|
||||
link_to event_note_target_path(event) do
|
||||
content_tag :strong do
|
||||
"#{event.note_target_type} ##{truncate event.note_target_iid}"
|
||||
end
|
||||
"#{event.note_target_type} ##{truncate event.note_target_iid}"
|
||||
end
|
||||
end
|
||||
elsif event.wall_note?
|
||||
|
||||
@@ -8,10 +8,14 @@ module IconsHelper
|
||||
end
|
||||
|
||||
def public_icon
|
||||
content_tag :i, nil, class: 'icon-globe cblue'
|
||||
content_tag :i, nil, class: 'icon-globe'
|
||||
end
|
||||
|
||||
def internal_icon
|
||||
content_tag :i, nil, class: 'icon-shield'
|
||||
end
|
||||
|
||||
def private_icon
|
||||
content_tag :i, nil, class: 'icon-lock cgreen'
|
||||
content_tag :i, nil, class: 'icon-lock'
|
||||
end
|
||||
end
|
||||
|
||||
@@ -68,4 +68,12 @@ module IssuesHelper
|
||||
false
|
||||
end
|
||||
end
|
||||
|
||||
def bulk_update_milestone_options
|
||||
options_for_select(["None (backlog)", nil]) + options_from_collection_for_select(project_active_milestones, "id", "title", params[:milestone_id])
|
||||
end
|
||||
|
||||
def bulk_update_assignee_options
|
||||
options_for_select(["None (unassigned)", nil]) + options_from_collection_for_select(@project.team.members, "id", "name", params[:assignee_id])
|
||||
end
|
||||
end
|
||||
|
||||
@@ -36,7 +36,7 @@ module MergeRequestsHelper
|
||||
|
||||
def merge_path_description(merge_request, separator)
|
||||
if merge_request.for_fork?
|
||||
"Project:Branches: #{@merge_request.source_project.path_with_namespace}:#{@merge_request.source_branch} #{separator} #{@merge_request.target_project.path_with_namespace}:#{@merge_request.target_branch}"
|
||||
"Project:Branches: #{@merge_request.source_project_path}:#{@merge_request.source_branch} #{separator} #{@merge_request.target_project.path_with_namespace}:#{@merge_request.target_branch}"
|
||||
else
|
||||
"Branches: #{@merge_request.source_branch} #{separator} #{@merge_request.target_branch}"
|
||||
end
|
||||
|
||||
@@ -31,8 +31,14 @@ module NotesHelper
|
||||
|
||||
def note_timestamp(note)
|
||||
# Shows the created at time and the updated at time if different
|
||||
ts = "#{time_ago_in_words(note.created_at)} ago"
|
||||
ts << content_tag(:small, " (Edited #{time_ago_in_words(note.updated_at)} ago)") if note.updated_at != note.created_at
|
||||
ts = "#{time_ago_with_tooltip(note.created_at, 'bottom', 'note_created_ago')} ago"
|
||||
if note.updated_at != note.created_at
|
||||
ts << capture_haml do
|
||||
haml_tag :small do
|
||||
haml_concat " (Edited #{time_ago_with_tooltip(note.updated_at, 'bottom', 'note_edited_ago')} ago)"
|
||||
end
|
||||
end
|
||||
end
|
||||
ts.html_safe
|
||||
end
|
||||
end
|
||||
|
||||
@@ -70,6 +70,8 @@ module ProjectsHelper
|
||||
scope: params[:scope],
|
||||
label_name: params[:label_name],
|
||||
milestone_id: params[:milestone_id],
|
||||
assignee_id: params[:assignee_id],
|
||||
sort: params[:sort],
|
||||
}
|
||||
|
||||
options = exist_opts.merge(options)
|
||||
@@ -80,7 +82,7 @@ module ProjectsHelper
|
||||
end
|
||||
|
||||
def project_active_milestones
|
||||
@project.milestones.active.order("due_date, title ASC").all
|
||||
@project.milestones.active.order("due_date, title ASC")
|
||||
end
|
||||
|
||||
def project_issues_trackers(current_tracker = nil)
|
||||
@@ -135,8 +137,8 @@ module ProjectsHelper
|
||||
end
|
||||
end
|
||||
|
||||
def repository_size
|
||||
"#{@project.repository.size} MB"
|
||||
def repository_size(project = nil)
|
||||
"#{(project || @project).repository.size} MB"
|
||||
rescue
|
||||
# In order to prevent 500 error
|
||||
# when application cannot allocate memory
|
||||
@@ -177,4 +179,12 @@ module ProjectsHelper
|
||||
|
||||
title
|
||||
end
|
||||
|
||||
def default_url_to_repo
|
||||
current_user ? @project.url_to_repo : @project.http_url_to_repo
|
||||
end
|
||||
|
||||
def default_clone_protocol
|
||||
current_user ? "ssh" : "http"
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,14 +1,16 @@
|
||||
module SearchHelper
|
||||
def search_autocomplete_source
|
||||
return unless current_user
|
||||
|
||||
[
|
||||
groups_autocomplete,
|
||||
projects_autocomplete,
|
||||
public_projects_autocomplete,
|
||||
default_autocomplete,
|
||||
project_autocomplete,
|
||||
help_autocomplete
|
||||
].flatten.to_json
|
||||
].flatten.uniq do |item|
|
||||
item[:label]
|
||||
end.to_json
|
||||
end
|
||||
|
||||
private
|
||||
@@ -71,7 +73,14 @@ module SearchHelper
|
||||
|
||||
# Autocomplete results for the current user's projects
|
||||
def projects_autocomplete
|
||||
current_user.authorized_projects.map do |p|
|
||||
current_user.authorized_projects.non_archived.map do |p|
|
||||
{ label: "project: #{simple_sanitize(p.name_with_namespace)}", url: project_path(p) }
|
||||
end
|
||||
end
|
||||
|
||||
# Autocomplete results for the current user's projects
|
||||
def public_projects_autocomplete
|
||||
Project.public_or_internal_only(current_user).non_archived.map do |p|
|
||||
{ label: "project: #{simple_sanitize(p.name_with_namespace)}", url: project_path(p) }
|
||||
end
|
||||
end
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
module VisibilityLevelHelper
|
||||
def visibility_level_color(level)
|
||||
case level
|
||||
when Gitlab::VisibilityLevel::PRIVATE
|
||||
'cgreen'
|
||||
when Gitlab::VisibilityLevel::INTERNAL
|
||||
'camber'
|
||||
when Gitlab::VisibilityLevel::PUBLIC
|
||||
'cblue'
|
||||
end
|
||||
end
|
||||
|
||||
def visibility_level_description(level)
|
||||
capture_haml do
|
||||
haml_tag :span do
|
||||
case level
|
||||
when Gitlab::VisibilityLevel::PRIVATE
|
||||
haml_concat "Project access must be granted explicitly for each user."
|
||||
when Gitlab::VisibilityLevel::INTERNAL
|
||||
haml_concat "The project can be cloned by"
|
||||
haml_concat "any logged in user."
|
||||
when Gitlab::VisibilityLevel::PUBLIC
|
||||
haml_concat "The project can be cloned"
|
||||
haml_concat "without any"
|
||||
haml_concat "authentication."
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def visibility_level_icon(level)
|
||||
case level
|
||||
when Gitlab::VisibilityLevel::PRIVATE
|
||||
private_icon
|
||||
when Gitlab::VisibilityLevel::INTERNAL
|
||||
internal_icon
|
||||
when Gitlab::VisibilityLevel::PUBLIC
|
||||
public_icon
|
||||
end
|
||||
end
|
||||
|
||||
def visibility_level_label(level)
|
||||
Project.visibility_levels.key(level)
|
||||
end
|
||||
|
||||
def restricted_visibility_levels
|
||||
current_user.is_admin? ? [] : gitlab_config.restricted_visibility_levels
|
||||
end
|
||||
end
|
||||
@@ -2,23 +2,27 @@ module Emails
|
||||
module MergeRequests
|
||||
def new_merge_request_email(recipient_id, merge_request_id)
|
||||
@merge_request = MergeRequest.find(merge_request_id)
|
||||
@project = @merge_request.project
|
||||
mail(to: recipient(recipient_id), subject: subject("New merge request ##{@merge_request.iid}", @merge_request.title))
|
||||
end
|
||||
|
||||
def reassigned_merge_request_email(recipient_id, merge_request_id, previous_assignee_id)
|
||||
@merge_request = MergeRequest.find(merge_request_id)
|
||||
@previous_assignee = User.find_by_id(previous_assignee_id) if previous_assignee_id
|
||||
@project = @merge_request.project
|
||||
mail(to: recipient(recipient_id), subject: subject("Changed merge request ##{@merge_request.iid}", @merge_request.title))
|
||||
end
|
||||
|
||||
def closed_merge_request_email(recipient_id, merge_request_id, updated_by_user_id)
|
||||
@merge_request = MergeRequest.find(merge_request_id)
|
||||
@updated_by = User.find updated_by_user_id
|
||||
@project = @merge_request.project
|
||||
mail(to: recipient(recipient_id), subject: subject("Closed merge request ##{@merge_request.iid}", @merge_request.title))
|
||||
end
|
||||
|
||||
def merged_merge_request_email(recipient_id, merge_request_id)
|
||||
@merge_request = MergeRequest.find(merge_request_id)
|
||||
@project = @merge_request.project
|
||||
mail(to: recipient(recipient_id), subject: subject("Accepted merge request ##{@merge_request.iid}", @merge_request.title))
|
||||
end
|
||||
end
|
||||
|
||||
@@ -13,5 +13,15 @@ module Emails
|
||||
mail(to: @user.email,
|
||||
subject: subject("Project was moved"))
|
||||
end
|
||||
|
||||
def repository_push_email(project_id, recipient, author_id, branch, compare)
|
||||
@project = Project.find(project_id)
|
||||
@author = User.find(author_id)
|
||||
@commits = Commit.decorate(compare.commits)
|
||||
@diffs = compare.diffs
|
||||
@branch = branch
|
||||
|
||||
mail(to: recipient, subject: subject("New push to repository"))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -16,6 +16,7 @@ class Notify < ActionMailer::Base
|
||||
default_url_options[:script_name] = Gitlab.config.gitlab.relative_url_root
|
||||
|
||||
default from: Gitlab.config.gitlab.email_from
|
||||
default reply_to: "noreply@#{Gitlab.config.gitlab.host}"
|
||||
|
||||
# Just send email with 3 seconds delay
|
||||
def self.delay
|
||||
|
||||
+30
-15
@@ -29,7 +29,7 @@ class Ability
|
||||
nil
|
||||
end
|
||||
|
||||
if project && project.public
|
||||
if project && project.public?
|
||||
[
|
||||
:read_project,
|
||||
:read_wiki,
|
||||
@@ -59,37 +59,41 @@ class Ability
|
||||
|
||||
# Rules based on role in project
|
||||
if team.masters.include?(user)
|
||||
rules << project_master_rules
|
||||
rules += project_master_rules
|
||||
|
||||
elsif team.developers.include?(user)
|
||||
rules << project_dev_rules
|
||||
rules += project_dev_rules
|
||||
|
||||
elsif team.reporters.include?(user)
|
||||
rules << project_report_rules
|
||||
rules += project_report_rules
|
||||
|
||||
elsif team.guests.include?(user)
|
||||
rules << project_guest_rules
|
||||
rules += project_guest_rules
|
||||
end
|
||||
|
||||
if project.public?
|
||||
rules << public_project_rules
|
||||
if project.public? || project.internal?
|
||||
rules += public_project_rules
|
||||
end
|
||||
|
||||
if project.owner == user || user.admin?
|
||||
rules << project_admin_rules
|
||||
rules += project_admin_rules
|
||||
end
|
||||
|
||||
if project.group && project.group.has_owner?(user)
|
||||
rules << project_admin_rules
|
||||
rules += project_admin_rules
|
||||
end
|
||||
|
||||
rules.flatten
|
||||
if project.archived?
|
||||
rules -= project_archived_rules
|
||||
end
|
||||
|
||||
rules
|
||||
end
|
||||
|
||||
def public_project_rules
|
||||
project_guest_rules + [
|
||||
:download_code,
|
||||
:fork_project,
|
||||
:fork_project
|
||||
]
|
||||
end
|
||||
|
||||
@@ -125,6 +129,16 @@ class Ability
|
||||
]
|
||||
end
|
||||
|
||||
def project_archived_rules
|
||||
[
|
||||
:write_merge_request,
|
||||
:push_code,
|
||||
:push_code_to_protected_branches,
|
||||
:modify_merge_request,
|
||||
:admin_merge_request
|
||||
]
|
||||
end
|
||||
|
||||
def project_master_rules
|
||||
project_dev_rules + [
|
||||
:push_code_to_protected_branches,
|
||||
@@ -145,9 +159,10 @@ class Ability
|
||||
def project_admin_rules
|
||||
project_master_rules + [
|
||||
:change_namespace,
|
||||
:change_public_mode,
|
||||
:change_visibility_level,
|
||||
:rename_project,
|
||||
:remove_project
|
||||
:remove_project,
|
||||
:archive_project
|
||||
]
|
||||
end
|
||||
|
||||
@@ -160,7 +175,7 @@ class Ability
|
||||
|
||||
# Only group owner and administrators can manage group
|
||||
if group.has_owner?(user) || user.admin?
|
||||
rules << [
|
||||
rules += [
|
||||
:manage_group,
|
||||
:manage_namespace
|
||||
]
|
||||
@@ -174,7 +189,7 @@ class Ability
|
||||
|
||||
# Only namespace owner and administrators can manage it
|
||||
if namespace.owner == user || user.admin?
|
||||
rules << [
|
||||
rules += [
|
||||
:manage_namespace
|
||||
]
|
||||
end
|
||||
|
||||
@@ -111,4 +111,11 @@ module Issuable
|
||||
end
|
||||
users.concat(mentions.reduce([], :|)).uniq
|
||||
end
|
||||
|
||||
def to_hook_data
|
||||
{
|
||||
object_kind: self.class.name.underscore,
|
||||
object_attributes: self.attributes
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
+2
-2
@@ -18,7 +18,7 @@ class Event < ActiveRecord::Base
|
||||
attr_accessible :project, :action, :data, :author_id, :project_id,
|
||||
:target_id, :target_type
|
||||
|
||||
default_scope where("author_id IS NOT NULL")
|
||||
default_scope { where.not(author_id: nil) }
|
||||
|
||||
CREATED = 1
|
||||
UPDATED = 2
|
||||
@@ -223,7 +223,7 @@ class Event < ActiveRecord::Base
|
||||
|
||||
# Max 20 commits from push DESC
|
||||
def commits
|
||||
@commits ||= data[:commits].reverse
|
||||
@commits ||= (data[:commits] || []).reverse
|
||||
end
|
||||
|
||||
def commits_count
|
||||
|
||||
@@ -33,7 +33,7 @@ class GollumWiki
|
||||
end
|
||||
|
||||
def http_url_to_repo
|
||||
http_url = [Gitlab.config.gitlab.url, "/", path_with_namespace, ".git"].join('')
|
||||
[Gitlab.config.gitlab.url, "/", path_with_namespace, ".git"].join('')
|
||||
end
|
||||
|
||||
# Returns the Gollum::Wiki object.
|
||||
|
||||
+1
-1
@@ -36,7 +36,7 @@ class Group < Namespace
|
||||
|
||||
def add_users(user_ids, group_access)
|
||||
user_ids.compact.each do |user_id|
|
||||
user = self.users_groups.find_or_initialize_by_user_id(user_id)
|
||||
user = self.users_groups.find_or_initialize_by(user_id: user_id)
|
||||
user.update_attributes(group_access: group_access)
|
||||
end
|
||||
end
|
||||
|
||||
+15
-4
@@ -28,7 +28,7 @@ class Issue < ActiveRecord::Base
|
||||
|
||||
scope :of_group, ->(group) { where(project_id: group.project_ids) }
|
||||
scope :of_user_team, ->(team) { where(project_id: team.project_ids, assignee_id: team.member_ids) }
|
||||
scope :opened, -> { with_state(:opened) }
|
||||
scope :opened, -> { with_state(:opened, :reopened) }
|
||||
scope :closed, -> { with_state(:closed) }
|
||||
|
||||
attr_accessible :title, :assignee_id, :position, :description,
|
||||
@@ -56,12 +56,23 @@ class Issue < ActiveRecord::Base
|
||||
state :closed
|
||||
end
|
||||
|
||||
# Both open and reopened issues should be listed as opened
|
||||
scope :opened, -> { with_state(:opened, :reopened) }
|
||||
|
||||
# Mentionable overrides.
|
||||
|
||||
def gfm_reference
|
||||
"issue ##{iid}"
|
||||
end
|
||||
|
||||
# Reset issue events cache
|
||||
#
|
||||
# Since we do cache @event we need to reset cache in special cases:
|
||||
# * when an issue is updated
|
||||
# Events cache stored like events/23-20130109142513.
|
||||
# The cache key includes updated_at timestamp.
|
||||
# Thus it will automatically generate a new fragment
|
||||
# when the event is updated because the key changes.
|
||||
def reset_events_cache
|
||||
Event.where(target_id: self.id, target_type: 'Issue').
|
||||
order('id DESC').limit(100).
|
||||
update_all(updated_at: Time.now)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -35,6 +35,10 @@ class MergeRequest < ActiveRecord::Base
|
||||
|
||||
attr_accessor :should_remove_source_branch
|
||||
|
||||
# When this attribute is true some MR validation is ignored
|
||||
# It allows us to close or modify broken merge requests
|
||||
attr_accessor :allow_broken
|
||||
|
||||
state_machine :state, initial: :opened do
|
||||
event :close do
|
||||
transition [:reopened, :opened] => :closed
|
||||
@@ -80,7 +84,7 @@ class MergeRequest < ActiveRecord::Base
|
||||
serialize :st_commits
|
||||
serialize :st_diffs
|
||||
|
||||
validates :source_project, presence: true
|
||||
validates :source_project, presence: true, unless: :allow_broken
|
||||
validates :source_branch, presence: true
|
||||
validates :target_project, presence: true
|
||||
validates :target_branch, presence: true
|
||||
@@ -262,7 +266,7 @@ class MergeRequest < ActiveRecord::Base
|
||||
# Return the set of issues that will be closed if this merge request is accepted.
|
||||
def closes_issues
|
||||
if target_branch == project.default_branch
|
||||
unmerged_commits.map { |c| c.closes_issues(project) }.flatten.uniq.sort_by(&:id)
|
||||
commits.map { |c| c.closes_issues(project) }.flatten.uniq.sort_by(&:id)
|
||||
else
|
||||
[]
|
||||
end
|
||||
@@ -273,6 +277,48 @@ class MergeRequest < ActiveRecord::Base
|
||||
"merge request !#{iid}"
|
||||
end
|
||||
|
||||
def target_project_path
|
||||
if target_project
|
||||
target_project.path_with_namespace
|
||||
else
|
||||
"(removed)"
|
||||
end
|
||||
end
|
||||
|
||||
def source_project_path
|
||||
if source_project
|
||||
source_project.path_with_namespace
|
||||
else
|
||||
"(removed)"
|
||||
end
|
||||
end
|
||||
|
||||
def source_branch_exists?
|
||||
return false unless self.source_project
|
||||
|
||||
self.source_project.repository.branch_names.include?(self.source_branch)
|
||||
end
|
||||
|
||||
def target_branch_exists?
|
||||
return false unless self.target_project
|
||||
|
||||
self.target_project.repository.branch_names.include?(self.target_branch)
|
||||
end
|
||||
|
||||
# Reset merge request events cache
|
||||
#
|
||||
# Since we do cache @event we need to reset cache in special cases:
|
||||
# * when a merge request is updated
|
||||
# Events cache stored like events/23-20130109142513.
|
||||
# The cache key includes updated_at timestamp.
|
||||
# Thus it will automatically generate a new fragment
|
||||
# when the event is updated because the key changes.
|
||||
def reset_events_cache
|
||||
Event.where(target_id: self.id, target_type: 'MergeRequest').
|
||||
order('id DESC').limit(100).
|
||||
update_all(updated_at: Time.now)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def dump_commits(commits)
|
||||
|
||||
+19
-2
@@ -157,7 +157,8 @@ class Note < ActiveRecord::Base
|
||||
# otherwise false is returned
|
||||
def downvote?
|
||||
votable? && (note.start_with?('-1') ||
|
||||
note.start_with?(':-1:')
|
||||
note.start_with?(':-1:') ||
|
||||
note.start_with?(':thumbsdown:')
|
||||
)
|
||||
end
|
||||
|
||||
@@ -206,7 +207,8 @@ class Note < ActiveRecord::Base
|
||||
# otherwise false is returned
|
||||
def upvote?
|
||||
votable? && (note.start_with?('+1') ||
|
||||
note.start_with?(':+1:')
|
||||
note.start_with?(':+1:') ||
|
||||
note.start_with?(':thumbsup:')
|
||||
)
|
||||
end
|
||||
|
||||
@@ -237,4 +239,19 @@ class Note < ActiveRecord::Base
|
||||
def noteable_type=(sType)
|
||||
super(sType.to_s.classify.constantize.base_class.to_s)
|
||||
end
|
||||
|
||||
# Reset notes events cache
|
||||
#
|
||||
# Since we do cache @event we need to reset cache in special cases:
|
||||
# * when a note is updated
|
||||
# * when a note is removed
|
||||
# Events cache stored like events/23-20130109142513.
|
||||
# The cache key includes updated_at timestamp.
|
||||
# Thus it will automatically generate a new fragment
|
||||
# when the event is updated because the key changes.
|
||||
def reset_events_cache
|
||||
Event.where(target_id: self.id, target_type: 'Note').
|
||||
order('id DESC').limit(100).
|
||||
update_all(updated_at: Time.now)
|
||||
end
|
||||
end
|
||||
|
||||
+58
-20
@@ -14,24 +14,25 @@
|
||||
# merge_requests_enabled :boolean default(TRUE), not null
|
||||
# wiki_enabled :boolean default(TRUE), not null
|
||||
# namespace_id :integer
|
||||
# public :boolean default(FALSE), not null
|
||||
# issues_tracker :string(255) default("gitlab"), not null
|
||||
# issues_tracker_id :string(255)
|
||||
# snippets_enabled :boolean default(TRUE), not null
|
||||
# last_activity_at :datetime
|
||||
# imported :boolean default(FALSE), not null
|
||||
# import_url :string(255)
|
||||
# visibility_level :integer default(0), not null
|
||||
#
|
||||
|
||||
class Project < ActiveRecord::Base
|
||||
include Gitlab::ShellAdapter
|
||||
include Gitlab::VisibilityLevel
|
||||
extend Enumerize
|
||||
|
||||
|
||||
ActsAsTaggableOn.strict_case_match = true
|
||||
|
||||
attr_accessible :name, :path, :description, :issues_tracker, :label_list,
|
||||
:issues_enabled, :wall_enabled, :merge_requests_enabled, :snippets_enabled, :issues_tracker_id,
|
||||
:wiki_enabled, :public, :import_url, :last_activity_at, as: [:default, :admin]
|
||||
:wiki_enabled, :visibility_level, :import_url, :last_activity_at, as: [:default, :admin]
|
||||
|
||||
attr_accessible :namespace_id, :creator_id, as: :admin
|
||||
|
||||
@@ -41,23 +42,29 @@ class Project < ActiveRecord::Base
|
||||
|
||||
# Relations
|
||||
belongs_to :creator, foreign_key: "creator_id", class_name: "User"
|
||||
belongs_to :group, foreign_key: "namespace_id", conditions: "type = 'Group'"
|
||||
belongs_to :group, -> { where(type: Group) }, foreign_key: "namespace_id"
|
||||
belongs_to :namespace
|
||||
|
||||
has_one :last_event, class_name: 'Event', order: 'events.created_at DESC', foreign_key: 'project_id'
|
||||
has_one :last_event, -> {order 'events.created_at DESC'}, class_name: 'Event', foreign_key: 'project_id'
|
||||
has_one :gitlab_ci_service, dependent: :destroy
|
||||
has_one :campfire_service, dependent: :destroy
|
||||
has_one :emails_on_push_service, dependent: :destroy
|
||||
has_one :pivotaltracker_service, dependent: :destroy
|
||||
has_one :hipchat_service, dependent: :destroy
|
||||
has_one :flowdock_service, dependent: :destroy
|
||||
has_one :assembla_service, dependent: :destroy
|
||||
has_one :forked_project_link, dependent: :destroy, foreign_key: "forked_to_project_id"
|
||||
has_one :forked_from_project, through: :forked_project_link
|
||||
|
||||
# Merge Requests for target project should be removed with it
|
||||
has_many :merge_requests, dependent: :destroy, foreign_key: "target_project_id"
|
||||
|
||||
# Merge requests from source project should be kept when source project was removed
|
||||
has_many :fork_merge_requests, foreign_key: "source_project_id", class_name: MergeRequest
|
||||
|
||||
has_many :issues, -> { order "state DESC, created_at DESC" }, dependent: :destroy
|
||||
has_many :services, dependent: :destroy
|
||||
has_many :events, dependent: :destroy
|
||||
has_many :merge_requests, dependent: :destroy, foreign_key: "target_project_id"
|
||||
has_many :fork_merge_requests,dependent: :destroy, foreign_key: "source_project_id", class_name: MergeRequest
|
||||
has_many :issues, dependent: :destroy, order: "state DESC, created_at DESC"
|
||||
has_many :milestones, dependent: :destroy
|
||||
has_many :notes, dependent: :destroy
|
||||
has_many :snippets, dependent: :destroy, class_name: "ProjectSnippet"
|
||||
@@ -77,8 +84,8 @@ class Project < ActiveRecord::Base
|
||||
delegate :members, to: :team, prefix: true
|
||||
|
||||
# Validations
|
||||
validates :creator, presence: true
|
||||
validates :description, length: { within: 0..2000 }
|
||||
validates :creator, presence: true, on: :create
|
||||
validates :description, length: { maximum: 2000 }, allow_blank: true
|
||||
validates :name, presence: true, length: { within: 0..255 },
|
||||
format: { with: Gitlab::Regex.project_name_regex,
|
||||
message: "only letters, digits, spaces & '_' '-' '.' allowed. Letter or digit should be first" }
|
||||
@@ -88,7 +95,7 @@ class Project < ActiveRecord::Base
|
||||
message: "only letters, digits & '_' '-' '.' allowed. Letter or digit should be first" }
|
||||
validates :issues_enabled, :wall_enabled, :merge_requests_enabled,
|
||||
:wiki_enabled, inclusion: { in: [true, false] }
|
||||
validates :issues_tracker_id, length: { within: 0..255 }
|
||||
validates :issues_tracker_id, length: { maximum: 255 }, allow_blank: true
|
||||
|
||||
validates :namespace, presence: true
|
||||
validates_uniqueness_of :name, scope: :namespace_id
|
||||
@@ -110,7 +117,10 @@ class Project < ActiveRecord::Base
|
||||
scope :sorted_by_activity, -> { reorder("projects.last_activity_at DESC") }
|
||||
scope :personal, ->(user) { where(namespace_id: user.namespace_id) }
|
||||
scope :joined, ->(user) { where("namespace_id != ?", user.namespace_id) }
|
||||
scope :public_only, -> { where(public: true) }
|
||||
scope :public_only, -> { where(visibility_level: PUBLIC) }
|
||||
scope :public_or_internal_only, ->(user) { where("visibility_level IN (:levels)", levels: user ? [ INTERNAL, PUBLIC ] : [ PUBLIC ]) }
|
||||
|
||||
scope :non_archived, -> { where(archived: false) }
|
||||
|
||||
enumerize :issues_tracker, in: (Gitlab.config.issues_tracker.keys).append(:gitlab), default: :gitlab
|
||||
|
||||
@@ -128,7 +138,7 @@ class Project < ActiveRecord::Base
|
||||
end
|
||||
|
||||
def search query
|
||||
joins(:namespace).where("projects.name LIKE :query OR projects.path LIKE :query OR namespaces.name LIKE :query OR projects.description LIKE :query", query: "%#{query}%")
|
||||
joins(:namespace).where("projects.archived = ?", false).where("projects.name LIKE :query OR projects.path LIKE :query OR namespaces.name LIKE :query OR projects.description LIKE :query", query: "%#{query}%")
|
||||
end
|
||||
|
||||
def find_with_namespace(id)
|
||||
@@ -142,6 +152,10 @@ class Project < ActiveRecord::Base
|
||||
where(path: id, namespace_id: nil).last
|
||||
end
|
||||
end
|
||||
|
||||
def visibility_levels
|
||||
Gitlab::VisibilityLevel.options
|
||||
end
|
||||
end
|
||||
|
||||
def team
|
||||
@@ -227,7 +241,7 @@ class Project < ActiveRecord::Base
|
||||
end
|
||||
|
||||
def available_services_names
|
||||
%w(gitlab_ci campfire hipchat pivotaltracker flowdock)
|
||||
%w(gitlab_ci campfire hipchat pivotaltracker flowdock assembla emails_on_push)
|
||||
end
|
||||
|
||||
def gitlab_ci?
|
||||
@@ -294,8 +308,10 @@ class Project < ActiveRecord::Base
|
||||
ProjectTransferService.new.transfer(self, new_namespace)
|
||||
end
|
||||
|
||||
def execute_hooks(data)
|
||||
hooks.each { |hook| hook.async_execute(data) }
|
||||
def execute_hooks(data, hooks_scope = :push_hooks)
|
||||
hooks.send(hooks_scope).each do |hook|
|
||||
hook.async_execute(data)
|
||||
end
|
||||
end
|
||||
|
||||
def execute_services(data)
|
||||
@@ -312,14 +328,14 @@ class Project < ActiveRecord::Base
|
||||
c_ids = self.repository.commits_between(oldrev, newrev).map(&:id)
|
||||
|
||||
# Update code for merge requests into project between project branches
|
||||
mrs = self.merge_requests.opened.by_branch(branch_name).all
|
||||
mrs = self.merge_requests.opened.by_branch(branch_name).to_a
|
||||
# Update code for merge requests between project and project fork
|
||||
mrs += self.fork_merge_requests.opened.by_branch(branch_name).all
|
||||
mrs += self.fork_merge_requests.opened.by_branch(branch_name).to_a
|
||||
|
||||
mrs.each { |merge_request| merge_request.reload_code; merge_request.mark_as_unchecked }
|
||||
|
||||
# Close merge requests
|
||||
mrs = self.merge_requests.opened.where(target_branch: branch_name).all
|
||||
mrs = self.merge_requests.opened.where(target_branch: branch_name).to_a
|
||||
mrs = mrs.select(&:last_commit).select { |mr| c_ids.include?(mr.last_commit.id) }
|
||||
mrs.each { |merge_request| merge_request.merge!(user.id) }
|
||||
|
||||
@@ -388,7 +404,7 @@ class Project < ActiveRecord::Base
|
||||
end
|
||||
|
||||
def http_url_to_repo
|
||||
http_url = [Gitlab.config.gitlab.url, "/", path_with_namespace, ".git"].join('')
|
||||
[Gitlab.config.gitlab.url, "/", path_with_namespace, ".git"].join('')
|
||||
end
|
||||
|
||||
# Check if current branch name is marked as protected in the system
|
||||
@@ -453,4 +469,26 @@ class Project < ActiveRecord::Base
|
||||
def default_branch
|
||||
@default_branch ||= repository.root_ref if repository.exists?
|
||||
end
|
||||
|
||||
def reload_default_branch
|
||||
@default_branch = nil
|
||||
default_branch
|
||||
end
|
||||
|
||||
def visibility_level_field
|
||||
visibility_level
|
||||
end
|
||||
|
||||
def archive!
|
||||
update_attribute(:archived, true)
|
||||
end
|
||||
|
||||
def unarchive!
|
||||
update_attribute(:archived, false)
|
||||
end
|
||||
|
||||
def change_head(branch)
|
||||
gitlab_shell.update_repository_head(self.path_with_namespace, branch)
|
||||
reload_default_branch
|
||||
end
|
||||
end
|
||||
|
||||
@@ -2,15 +2,24 @@
|
||||
#
|
||||
# Table name: web_hooks
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# url :string(255)
|
||||
# project_id :integer
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
# type :string(255) default("ProjectHook")
|
||||
# service_id :integer
|
||||
# id :integer not null, primary key
|
||||
# url :string(255)
|
||||
# project_id :integer
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
# type :string(255) default("ProjectHook")
|
||||
# service_id :integer
|
||||
# push_events :boolean default(TRUE), not null
|
||||
# issues_events :boolean default(FALSE), not null
|
||||
# merge_requests_events :boolean default(FALSE), not null
|
||||
#
|
||||
|
||||
class ProjectHook < WebHook
|
||||
belongs_to :project
|
||||
|
||||
attr_accessible :push_events, :issues_events, :merge_requests_events
|
||||
|
||||
scope :push_hooks, -> { where(push_events: true) }
|
||||
scope :issue_hooks, -> { where(issues_events: true) }
|
||||
scope :merge_request_hooks, -> { where(merge_requests_events: true) }
|
||||
end
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
# == Schema Information
|
||||
#
|
||||
# Table name: services
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# type :string(255)
|
||||
# title :string(255)
|
||||
# token :string(255)
|
||||
# project_id :integer not null
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
# active :boolean default(FALSE), not null
|
||||
# project_url :string(255)
|
||||
# subdomain :string(255)
|
||||
# room :string(255)
|
||||
#
|
||||
|
||||
class AssemblaService < Service
|
||||
include HTTParty
|
||||
|
||||
validates :token, presence: true, if: :activated?
|
||||
|
||||
def title
|
||||
'Assembla'
|
||||
end
|
||||
|
||||
def description
|
||||
'Project Management Software (Source Commits Endpoint)'
|
||||
end
|
||||
|
||||
def to_param
|
||||
'assembla'
|
||||
end
|
||||
|
||||
def fields
|
||||
[
|
||||
{ type: 'text', name: 'token', placeholder: '' }
|
||||
]
|
||||
end
|
||||
|
||||
def execute(push)
|
||||
url = "https://atlas.assembla.com/spaces/ouposp/github_tool?secret_key=#{token}"
|
||||
AssemblaService.post(url, body: { payload: push }.to_json, headers: { 'Content-Type' => 'application/json' })
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,44 @@
|
||||
# == Schema Information
|
||||
#
|
||||
# Table name: services
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# type :string(255)
|
||||
# title :string(255)
|
||||
# token :string(255)
|
||||
# project_id :integer not null
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
# active :boolean default(FALSE), not null
|
||||
# project_url :string(255)
|
||||
# subdomain :string(255)
|
||||
# room :string(255)
|
||||
#
|
||||
|
||||
class EmailsOnPushService < Service
|
||||
attr_accessible :recipients
|
||||
|
||||
validates :recipients, presence: true, if: :activated?
|
||||
|
||||
def title
|
||||
'Emails on push'
|
||||
end
|
||||
|
||||
def description
|
||||
'Email the commits and diff of each push to a list of recipients.'
|
||||
end
|
||||
|
||||
def to_param
|
||||
'emails_on_push'
|
||||
end
|
||||
|
||||
def execute(push_data)
|
||||
EmailsOnPushWorker.perform_async(project_id, recipients, push_data)
|
||||
end
|
||||
|
||||
def fields
|
||||
[
|
||||
{ type: 'textarea', name: 'recipients', placeholder: 'Emails separated by whitespace' },
|
||||
]
|
||||
end
|
||||
end
|
||||
@@ -87,9 +87,8 @@ class ProjectTeam
|
||||
def import(source_project)
|
||||
target_project = project
|
||||
|
||||
source_team = source_project.users_projects.all
|
||||
target_team = target_project.users_projects.all
|
||||
target_user_ids = target_team.map(&:user_id)
|
||||
source_team = source_project.users_projects.to_a
|
||||
target_user_ids = target_project.users_projects.pluck(:user_id)
|
||||
|
||||
source_team.reject! do |tm|
|
||||
# Skip if user already present in team
|
||||
|
||||
@@ -133,6 +133,7 @@ class Repository
|
||||
Rails.cache.delete(cache_key(:tag_names))
|
||||
Rails.cache.delete(cache_key(:commit_count))
|
||||
Rails.cache.delete(cache_key(:graph_log))
|
||||
Rails.cache.delete(cache_key(:readme))
|
||||
end
|
||||
|
||||
def graph_log
|
||||
@@ -159,4 +160,10 @@ class Repository
|
||||
def blob_at(sha, path)
|
||||
Gitlab::Git::Blob.find(self, sha, path)
|
||||
end
|
||||
|
||||
def readme
|
||||
Rails.cache.fetch(cache_key(:readme)) do
|
||||
Tree.new(self, self.root_ref).readme
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -2,13 +2,16 @@
|
||||
#
|
||||
# Table name: web_hooks
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# url :string(255)
|
||||
# project_id :integer
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
# type :string(255) default("ProjectHook")
|
||||
# service_id :integer
|
||||
# id :integer not null, primary key
|
||||
# url :string(255)
|
||||
# project_id :integer
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
# type :string(255) default("ProjectHook")
|
||||
# service_id :integer
|
||||
# push_events :boolean default(TRUE), not null
|
||||
# issues_events :boolean default(FALSE), not null
|
||||
# merge_requests_events :boolean default(FALSE), not null
|
||||
#
|
||||
|
||||
class ServiceHook < WebHook
|
||||
|
||||
@@ -2,13 +2,16 @@
|
||||
#
|
||||
# Table name: web_hooks
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# url :string(255)
|
||||
# project_id :integer
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
# type :string(255) default("ProjectHook")
|
||||
# service_id :integer
|
||||
# id :integer not null, primary key
|
||||
# url :string(255)
|
||||
# project_id :integer
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
# type :string(255) default("ProjectHook")
|
||||
# service_id :integer
|
||||
# push_events :boolean default(TRUE), not null
|
||||
# issues_events :boolean default(FALSE), not null
|
||||
# merge_requests_events :boolean default(FALSE), not null
|
||||
#
|
||||
|
||||
class SystemHook < WebHook
|
||||
|
||||
+23
-9
@@ -41,6 +41,7 @@
|
||||
# confirmed_at :datetime
|
||||
# confirmation_sent_at :datetime
|
||||
# unconfirmed_email :string(255)
|
||||
# hide_no_ssh_key :boolean default(FALSE), not null
|
||||
#
|
||||
|
||||
require 'carrierwave/orm/activerecord'
|
||||
@@ -52,7 +53,7 @@ class User < ActiveRecord::Base
|
||||
|
||||
attr_accessible :email, :password, :password_confirmation, :remember_me, :bio, :name, :username,
|
||||
:skype, :linkedin, :twitter, :color_scheme_id, :theme_id, :force_random_password,
|
||||
:extern_uid, :provider, :password_expires_at, :avatar,
|
||||
:extern_uid, :provider, :password_expires_at, :avatar, :hide_no_ssh_key,
|
||||
as: [:default, :admin]
|
||||
|
||||
attr_accessible :projects_limit, :can_create_group,
|
||||
@@ -72,7 +73,7 @@ class User < ActiveRecord::Base
|
||||
#
|
||||
|
||||
# Namespace for personal projects
|
||||
has_one :namespace, dependent: :destroy, foreign_key: :owner_id, class_name: "Namespace", conditions: 'type IS NULL'
|
||||
has_one :namespace, -> { where type: nil }, dependent: :destroy, foreign_key: :owner_id, class_name: "Namespace"
|
||||
|
||||
# Profile
|
||||
has_many :keys, dependent: :destroy
|
||||
@@ -80,8 +81,7 @@ class User < ActiveRecord::Base
|
||||
# Groups
|
||||
has_many :users_groups, dependent: :destroy
|
||||
has_many :groups, through: :users_groups
|
||||
has_many :owned_groups, through: :users_groups, source: :group, conditions: { users_groups: { group_access: UsersGroup::OWNER } }
|
||||
|
||||
has_many :owned_groups, -> { where users_groups: { group_access: UsersGroup::OWNER } }, through: :users_groups, source: :group
|
||||
# Projects
|
||||
has_many :groups_projects, through: :groups, source: :projects
|
||||
has_many :personal_projects, through: :namespace, source: :projects
|
||||
@@ -94,7 +94,7 @@ class User < ActiveRecord::Base
|
||||
has_many :notes, dependent: :destroy, foreign_key: :author_id
|
||||
has_many :merge_requests, dependent: :destroy, foreign_key: :author_id
|
||||
has_many :events, dependent: :destroy, foreign_key: :author_id, class_name: "Event"
|
||||
has_many :recent_events, foreign_key: :author_id, class_name: "Event", order: "id DESC"
|
||||
has_many :recent_events, -> { order "id DESC" }, foreign_key: :author_id, class_name: "Event"
|
||||
has_many :assigned_issues, dependent: :destroy, foreign_key: :assignee_id, class_name: "Issue"
|
||||
has_many :assigned_merge_requests, dependent: :destroy, foreign_key: :assignee_id, class_name: "MergeRequest"
|
||||
|
||||
@@ -104,7 +104,7 @@ class User < ActiveRecord::Base
|
||||
#
|
||||
validates :name, presence: true
|
||||
validates :email, presence: true, format: { with: /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/ }
|
||||
validates :bio, length: { within: 0..255 }
|
||||
validates :bio, length: { maximum: 255 }, allow_blank: true
|
||||
validates :extern_uid, allow_blank: true, uniqueness: {scope: :provider}
|
||||
validates :projects_limit, presence: true, numericality: {greater_than_or_equal_to: 0}
|
||||
validates :username, presence: true, uniqueness: true,
|
||||
@@ -164,7 +164,7 @@ class User < ActiveRecord::Base
|
||||
scope :alphabetically, -> { order('name ASC') }
|
||||
scope :in_team, ->(team){ where(id: team.member_ids) }
|
||||
scope :not_in_team, ->(team){ where('users.id NOT IN (:ids)', ids: team.member_ids) }
|
||||
scope :not_in_project, ->(project) { project.users.present? ? where("id not in (:ids)", ids: project.users.map(&:id) ) : scoped }
|
||||
scope :not_in_project, ->(project) { project.users.present? ? where("id not in (:ids)", ids: project.users.map(&:id) ) : all }
|
||||
scope :without_projects, -> { where('id NOT IN (SELECT DISTINCT(user_id) FROM users_projects)') }
|
||||
scope :ldap, -> { where(provider: 'ldap') }
|
||||
|
||||
@@ -199,7 +199,7 @@ class User < ActiveRecord::Base
|
||||
end
|
||||
|
||||
def by_username_or_id(name_or_id)
|
||||
where('username = ? OR id = ?', name_or_id, name_or_id).first
|
||||
where('users.username = ? OR users.id = ?', name_or_id, name_or_id.to_i).first
|
||||
end
|
||||
|
||||
def build_user(attrs = {}, options= {})
|
||||
@@ -377,7 +377,7 @@ class User < ActiveRecord::Base
|
||||
end
|
||||
|
||||
def accessible_deploy_keys
|
||||
DeployKey.in_projects(self.authorized_projects).uniq
|
||||
DeployKey.in_projects(self.authorized_projects.pluck(:id)).uniq
|
||||
end
|
||||
|
||||
def created_by
|
||||
@@ -413,4 +413,18 @@ class User < ActiveRecord::Base
|
||||
project.namespace != namespace &&
|
||||
project.project_member(self)
|
||||
end
|
||||
|
||||
# Reset project events cache related to this user
|
||||
#
|
||||
# Since we do cache @event we need to reset cache in special cases:
|
||||
# * when the user changes their avatar
|
||||
# Events cache stored like events/23-20130109142513.
|
||||
# The cache key includes updated_at timestamp.
|
||||
# Thus it will automatically generate a new fragment
|
||||
# when the event is updated because the key changes.
|
||||
def reset_events_cache
|
||||
Event.where(author_id: self.id).
|
||||
order('id DESC').limit(1000).
|
||||
update_all(updated_at: Time.now)
|
||||
end
|
||||
end
|
||||
|
||||
+10
-7
@@ -2,13 +2,16 @@
|
||||
#
|
||||
# Table name: web_hooks
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# url :string(255)
|
||||
# project_id :integer
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
# type :string(255) default("ProjectHook")
|
||||
# service_id :integer
|
||||
# id :integer not null, primary key
|
||||
# url :string(255)
|
||||
# project_id :integer
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
# type :string(255) default("ProjectHook")
|
||||
# service_id :integer
|
||||
# push_events :boolean default(TRUE), not null
|
||||
# issues_events :boolean default(FALSE), not null
|
||||
# merge_requests_events :boolean default(FALSE), not null
|
||||
#
|
||||
|
||||
class WebHook < ActiveRecord::Base
|
||||
|
||||
@@ -1,18 +1,19 @@
|
||||
class IssueObserver < BaseObserver
|
||||
def after_create(issue)
|
||||
notification.new_issue(issue, current_user)
|
||||
|
||||
issue.create_cross_references!(issue.project, current_user)
|
||||
execute_hooks(issue)
|
||||
end
|
||||
|
||||
def after_close(issue, transition)
|
||||
notification.close_issue(issue, current_user)
|
||||
|
||||
create_note(issue)
|
||||
execute_hooks(issue)
|
||||
end
|
||||
|
||||
def after_reopen(issue, transition)
|
||||
create_note(issue)
|
||||
execute_hooks(issue)
|
||||
end
|
||||
|
||||
def after_update(issue)
|
||||
@@ -21,6 +22,7 @@ class IssueObserver < BaseObserver
|
||||
end
|
||||
|
||||
issue.notice_added_references(issue.project, current_user)
|
||||
execute_hooks(issue)
|
||||
end
|
||||
|
||||
protected
|
||||
@@ -29,4 +31,8 @@ class IssueObserver < BaseObserver
|
||||
def create_note(issue)
|
||||
Note.create_status_change_note(issue, issue.project, current_user, issue.state, current_commit)
|
||||
end
|
||||
|
||||
def execute_hooks(issue)
|
||||
issue.project.execute_hooks(issue.to_hook_data, :issue_hooks)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -7,15 +7,15 @@ class MergeRequestObserver < ActivityObserver
|
||||
end
|
||||
|
||||
notification.new_merge_request(merge_request, current_user)
|
||||
|
||||
merge_request.create_cross_references!(merge_request.project, current_user)
|
||||
execute_hooks(merge_request)
|
||||
end
|
||||
|
||||
def after_close(merge_request, transition)
|
||||
create_event(merge_request, Event::CLOSED)
|
||||
Note.create_status_change_note(merge_request, merge_request.target_project, current_user, merge_request.state, nil)
|
||||
|
||||
notification.close_mr(merge_request, current_user)
|
||||
create_note(merge_request)
|
||||
execute_hooks(merge_request)
|
||||
end
|
||||
|
||||
def after_merge(merge_request, transition)
|
||||
@@ -31,17 +31,21 @@ class MergeRequestObserver < ActivityObserver
|
||||
action: Event::MERGED,
|
||||
author_id: merge_request.author_id_of_changes
|
||||
)
|
||||
|
||||
execute_hooks(merge_request)
|
||||
end
|
||||
|
||||
def after_reopen(merge_request, transition)
|
||||
create_event(merge_request, Event::REOPENED)
|
||||
Note.create_status_change_note(merge_request, merge_request.target_project, current_user, merge_request.state, nil)
|
||||
create_note(merge_request)
|
||||
execute_hooks(merge_request)
|
||||
end
|
||||
|
||||
def after_update(merge_request)
|
||||
notification.reassigned_merge_request(merge_request, current_user) if merge_request.is_being_reassigned?
|
||||
|
||||
merge_request.notice_added_references(merge_request.project, current_user)
|
||||
execute_hooks(merge_request)
|
||||
end
|
||||
|
||||
def create_event(record, status)
|
||||
@@ -53,4 +57,17 @@ class MergeRequestObserver < ActivityObserver
|
||||
author_id: current_user.id
|
||||
)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Create merge request note with service comment like 'Status changed to closed'
|
||||
def create_note(merge_request)
|
||||
Note.create_status_change_note(merge_request, merge_request.target_project, current_user, merge_request.state, nil)
|
||||
end
|
||||
|
||||
def execute_hooks(merge_request)
|
||||
if merge_request.project
|
||||
merge_request.project.execute_hooks(merge_request.to_hook_data, :merge_request_hooks)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user