Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.travis.yml4
-rw-r--r--CHANGELOG11
-rw-r--r--CONTRIBUTING.md34
-rw-r--r--Gemfile2
-rw-r--r--Gemfile.lock10
-rw-r--r--README.md2
-rw-r--r--VERSION2
-rw-r--r--app/assets/images/ajax_loader_gray.gifbin0 -> 8370 bytes
-rw-r--r--app/assets/images/logo.pngbin3001 -> 0 bytes
-rw-r--r--app/assets/images/logo_basic.pngbin3277 -> 0 bytes
-rw-r--r--app/assets/images/logo_text.pngbin4602 -> 0 bytes
-rw-r--r--app/assets/images/logo_text_tr.pngbin3290 -> 0 bytes
-rw-r--r--app/assets/images/logo_white.pngbin1517 -> 1920 bytes
-rw-r--r--app/assets/images/switch_icon.pngbin0 -> 1203 bytes
-rw-r--r--app/assets/javascripts/gfm_auto_complete.js.coffee76
-rw-r--r--app/assets/javascripts/issues.js73
-rw-r--r--app/assets/javascripts/main.js.coffee12
-rw-r--r--app/assets/javascripts/merge_requests.js11
-rw-r--r--app/assets/stylesheets/application.css10
-rw-r--r--app/assets/stylesheets/application.scss47
-rw-r--r--app/assets/stylesheets/common.scss180
-rw-r--r--app/assets/stylesheets/gitlab_bootstrap.scss26
-rw-r--r--app/assets/stylesheets/gitlab_bootstrap/blocks.scss28
-rw-r--r--app/assets/stylesheets/gitlab_bootstrap/common.scss23
-rw-r--r--app/assets/stylesheets/gitlab_bootstrap/fonts.scss (renamed from app/assets/stylesheets/fonts.scss)0
-rw-r--r--app/assets/stylesheets/gitlab_bootstrap/lists.scss54
-rw-r--r--app/assets/stylesheets/gitlab_bootstrap/mixins.scss (renamed from app/assets/stylesheets/mixins.scss)11
-rw-r--r--app/assets/stylesheets/gitlab_bootstrap/variables.scss (renamed from app/assets/stylesheets/variables.scss)2
-rw-r--r--app/assets/stylesheets/highlight/dark.scss1
-rw-r--r--app/assets/stylesheets/jquery.ui.gitlab.css113
-rw-r--r--app/assets/stylesheets/main.scss139
-rw-r--r--app/assets/stylesheets/sections/commits.scss16
-rw-r--r--app/assets/stylesheets/sections/events.scss10
-rw-r--r--app/assets/stylesheets/sections/header.scss14
-rw-r--r--app/assets/stylesheets/sections/issues.scss9
-rw-r--r--app/assets/stylesheets/sections/merge_requests.scss6
-rw-r--r--app/assets/stylesheets/sections/projects.scss43
-rw-r--r--app/assets/stylesheets/sections/snippets.scss9
-rw-r--r--app/assets/stylesheets/sections/votes.scss43
-rw-r--r--app/assets/stylesheets/themes/ui_basic.scss12
-rw-r--r--app/controllers/admin/groups_controller.rb2
-rw-r--r--app/controllers/admin/users_controller.rb4
-rw-r--r--app/controllers/groups_controller.rb1
-rw-r--r--app/controllers/issues_controller.rb14
-rw-r--r--app/controllers/merge_requests_controller.rb20
-rw-r--r--app/controllers/milestones_controller.rb10
-rw-r--r--app/controllers/omniauth_callbacks_controller.rb2
-rw-r--r--app/controllers/projects_controller.rb4
-rw-r--r--app/controllers/snippets_controller.rb4
-rw-r--r--app/helpers/application_helper.rb7
-rw-r--r--app/helpers/issues_helper.rb32
-rw-r--r--app/helpers/merge_requests_helper.rb26
-rw-r--r--app/helpers/projects_helper.rb42
-rw-r--r--app/mailers/notify.rb15
-rw-r--r--app/models/commit.rb12
-rw-r--r--app/models/event.rb23
-rw-r--r--app/models/gitlab_ci_service.rb18
-rw-r--r--app/models/merge_request.rb6
-rw-r--r--app/models/milestone.rb30
-rw-r--r--app/models/namespace.rb17
-rw-r--r--app/models/note.rb18
-rw-r--r--app/models/project.rb67
-rw-r--r--app/models/snippet.rb2
-rw-r--r--app/models/user.rb14
-rw-r--r--app/observers/activity_observer.rb27
-rw-r--r--app/observers/issue_observer.rb2
-rw-r--r--app/observers/note_observer.rb2
-rw-r--r--app/observers/project_observer.rb3
-rw-r--r--app/roles/account.rb16
-rw-r--r--app/roles/namespaced_project.rb59
-rw-r--r--app/roles/note_event.rb37
-rw-r--r--app/roles/push_observer.rb2
-rw-r--r--app/roles/repository.rb22
-rw-r--r--app/views/admin/groups/edit.html.haml19
-rw-r--r--app/views/admin/groups/index.html.haml17
-rw-r--r--app/views/admin/groups/show.html.haml17
-rw-r--r--app/views/admin/logs/show.html.haml16
-rw-r--r--app/views/admin/projects/_form.html.haml62
-rw-r--r--app/views/admin/projects/index.html.haml17
-rw-r--r--app/views/admin/projects/show.html.haml74
-rw-r--r--app/views/admin/users/index.html.haml30
-rw-r--r--app/views/admin/users/show.html.haml24
-rw-r--r--app/views/commits/_commits.html.haml2
-rw-r--r--app/views/compare/_form.html.haml31
-rw-r--r--app/views/compare/show.html.haml2
-rw-r--r--app/views/dashboard/_groups.html.haml6
-rw-r--r--app/views/dashboard/_projects.html.haml8
-rw-r--r--app/views/dashboard/index.atom.builder2
-rw-r--r--app/views/dashboard/issues.html.haml4
-rw-r--r--app/views/dashboard/merge_requests.html.haml9
-rw-r--r--app/views/devise/sessions/new.html.haml2
-rw-r--r--app/views/errors/gitolite.html.haml4
-rw-r--r--app/views/events/_event.html.haml14
-rw-r--r--app/views/events/_event_last_push.html.haml2
-rw-r--r--app/views/events/event/_note.html.haml25
-rw-r--r--app/views/events/event/_push.html.haml4
-rw-r--r--app/views/groups/_projects.html.haml6
-rw-r--r--app/views/groups/issues.html.haml2
-rw-r--r--app/views/groups/merge_requests.html.haml2
-rw-r--r--app/views/groups/people.html.haml4
-rw-r--r--app/views/groups/show.atom.builder2
-rw-r--r--app/views/hooks/index.html.haml13
-rw-r--r--app/views/issues/_form.html.haml53
-rw-r--r--app/views/issues/_issues.html.haml2
-rw-r--r--app/views/issues/_show.html.haml6
-rw-r--r--app/views/issues/create.js.haml10
-rw-r--r--app/views/issues/edit.js.haml4
-rw-r--r--app/views/issues/index.html.haml11
-rw-r--r--app/views/issues/new.js.haml3
-rw-r--r--app/views/issues/show.html.haml18
-rw-r--r--app/views/issues/update.js.haml10
-rw-r--r--app/views/kaminari/admin/_gap.html.haml5
-rw-r--r--app/views/labels/_label.html.haml2
-rw-r--r--app/views/labels/index.html.haml2
-rw-r--r--app/views/layouts/_init_auto_complete.html.haml2
-rw-r--r--app/views/layouts/notify.html.haml17
-rw-r--r--app/views/layouts/project_resource.html.haml4
-rw-r--r--app/views/merge_requests/_form.html.haml2
-rw-r--r--app/views/merge_requests/_merge_request.html.haml2
-rw-r--r--app/views/merge_requests/_show.html.haml4
-rw-r--r--app/views/merge_requests/index.html.haml2
-rw-r--r--app/views/merge_requests/show/_commits.html.haml6
-rw-r--r--app/views/merge_requests/show/_mr_box.html.haml31
-rw-r--r--app/views/merge_requests/show/_mr_ci.html.haml35
-rw-r--r--app/views/merge_requests/show/_mr_title.html.haml5
-rw-r--r--app/views/milestones/_milestone.html.haml33
-rw-r--r--app/views/milestones/index.html.haml7
-rw-r--r--app/views/milestones/show.html.haml72
-rw-r--r--app/views/notes/_common_form.html.haml1
-rw-r--r--app/views/notes/_per_line_form.html.haml1
-rw-r--r--app/views/notify/issue_status_changed_email.html.haml2
-rw-r--r--app/views/notify/new_issue_email.html.haml2
-rw-r--r--app/views/notify/new_merge_request_email.html.haml3
-rw-r--r--app/views/notify/project_access_granted_email.html.haml15
-rw-r--r--app/views/notify/project_was_moved_email.html.haml25
-rw-r--r--app/views/notify/reassigned_issue_email.html.haml2
-rw-r--r--app/views/notify/reassigned_merge_request_email.html.haml2
-rw-r--r--app/views/profiles/account.html.haml5
-rw-r--r--app/views/profiles/show.html.haml4
-rw-r--r--app/views/projects/_form.html.haml29
-rw-r--r--app/views/projects/create.js.haml1
-rw-r--r--app/views/projects/files.html.haml3
-rw-r--r--app/views/projects/graph.html.haml2
-rw-r--r--app/views/projects/update_failed.js.haml2
-rw-r--r--app/views/services/index.html.haml18
-rw-r--r--app/views/shared/_clone_panel.html.haml2
-rw-r--r--app/views/snippets/_form.html.haml59
-rw-r--r--app/views/snippets/_snippet.html.haml3
-rw-r--r--app/views/snippets/index.html.haml16
-rw-r--r--app/views/snippets/show.html.haml2
-rw-r--r--app/views/team_members/_show.html.haml2
-rw-r--r--app/views/team_members/_team.html.haml8
-rw-r--r--app/views/team_members/show.html.haml2
-rw-r--r--app/views/tree/_tree.html.haml9
-rw-r--r--app/workers/post_receive.rb10
-rw-r--r--config/database.yml.example39
-rw-r--r--config/database.yml.postgresql1
-rw-r--r--config/gitlab.yml.example85
-rw-r--r--config/initializers/1_settings.rb206
-rw-r--r--config/initializers/3_grit_ext.rb4
-rw-r--r--config/initializers/devise.rb24
-rw-r--r--config/routes.rb15
-rw-r--r--db/fixtures/development/002_project.rb13
-rw-r--r--db/fixtures/development/009_source_code.rb7
-rw-r--r--db/fixtures/development/010_groups.rb11
-rw-r--r--db/migrate/20121218164840_move_noteable_commit_to_own_field.rb20
-rw-r--r--db/migrate/20121219095402_indices_for_notes.rb6
-rw-r--r--db/schema.rb8
-rw-r--r--doc/api/issues.md19
-rw-r--r--doc/api/merge_requests.md9
-rw-r--r--doc/api/notes.md1
-rw-r--r--doc/api/projects.md5
-rw-r--r--doc/api/session.md1
-rw-r--r--doc/api/snippets.md1
-rw-r--r--doc/api/users.md7
-rw-r--r--doc/development.md36
-rw-r--r--doc/install/databases.md52
-rw-r--r--doc/install/installation.md319
-rw-r--r--doc/install/requirements.md52
-rw-r--r--doc/raketasks/backup_restore.md4
-rw-r--r--doc/raketasks/features.md6
-rw-r--r--doc/raketasks/maintenance.md94
-rw-r--r--doc/raketasks/user_management.md4
-rw-r--r--features/project/issues/issues.feature39
-rw-r--r--features/steps/project/project_browse_commits.rb4
-rw-r--r--features/steps/project/project_issues.rb4
-rw-r--r--features/support/env.rb8
-rw-r--r--lib/api/entities.rb4
-rw-r--r--lib/api/helpers.rb19
-rw-r--r--lib/api/projects.rb7
-rw-r--r--lib/api/users.rb2
-rw-r--r--lib/gitlab/auth.rb2
-rw-r--r--lib/gitlab/backend/gitolite.rb2
-rw-r--r--lib/gitlab/backend/gitolite_config.rb6
-rw-r--r--lib/gitlab/backend/grack_auth.rb4
-rw-r--r--lib/gitlab/logger.rb5
-rw-r--r--lib/gitlab/project_mover.rb4
-rwxr-xr-xlib/hooks/post-receive5
-rw-r--r--lib/tasks/bulk_add_permission.rake20
-rw-r--r--lib/tasks/gitlab/backup.rake148
-rw-r--r--lib/tasks/gitlab/bulk_add_permission.rake24
-rw-r--r--lib/tasks/gitlab/check.rake968
-rw-r--r--lib/tasks/gitlab/enable_automerge.rake25
-rw-r--r--lib/tasks/gitlab/enable_namespaces.rake (renamed from lib/tasks/gitlab/activate_namespaces.rake)4
-rw-r--r--lib/tasks/gitlab/import.rake2
-rw-r--r--lib/tasks/gitlab/info.rake37
-rw-r--r--lib/tasks/gitlab/setup.rake2
-rw-r--r--lib/tasks/gitlab/status.rake113
-rw-r--r--lib/tasks/resque.rake8
-rw-r--r--lib/tasks/travis.rake2
-rw-r--r--spec/helpers/application_helper_spec.rb4
-rw-r--r--spec/lib/gitolite_spec.rb2
-rw-r--r--spec/lib/project_mover_spec.rb2
-rw-r--r--spec/models/event_spec.rb2
-rw-r--r--spec/models/merge_request_spec.rb2
-rw-r--r--spec/models/note_spec.rb10
-rw-r--r--spec/models/project_hooks_spec.rb2
-rw-r--r--spec/models/project_spec.rb103
-rw-r--r--spec/models/user_spec.rb5
-rw-r--r--spec/observers/activity_observer_spec.rb24
-rw-r--r--spec/requests/api/projects_spec.rb8
-rw-r--r--spec/requests/issues_spec.rb12
-rw-r--r--spec/requests/snippets_spec.rb5
-rw-r--r--spec/roles/account_role_spec.rb44
-rw-r--r--spec/roles/repository_spec.rb89
-rw-r--r--spec/routing/project_routing_spec.rb3
-rw-r--r--spec/routing/routing_spec.rb5
-rw-r--r--spec/spec_helper.rb6
-rw-r--r--spec/workers/post_receive_spec.rb14
-rw-r--r--vendor/assets/javascripts/branch-graph.js2
230 files changed, 3415 insertions, 2037 deletions
diff --git a/.travis.yml b/.travis.yml
index 6a713ea1703..ad00ded07cb 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,4 +1,5 @@
env:
+ - DB=postgresql
- DB=mysql
before_install:
- sudo apt-get install libicu-dev -y
@@ -18,8 +19,7 @@ services:
before_script:
- "cp config/database.yml.$DB config/database.yml"
- "cp config/gitlab.yml.example config/gitlab.yml"
- - "bundle exec rake db:create RAILS_ENV=test"
- - "bundle exec rake db:migrate RAILS_ENV=test"
+ - "bundle exec rake db:setup RAILS_ENV=test"
- "bundle exec rake db:seed_fu RAILS_ENV=test"
- "sh -e /etc/init.d/xvfb start"
script: "bundle exec rake travis --trace"
diff --git a/CHANGELOG b/CHANGELOG
index 73933e0be4b..95ed6e8db1c 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,4 +1,15 @@
v 4.0.0
+ - Reorganized settings
+ - Fixed commits compare
+ - Refactored scss
+ - Improve status checks
+ - Validates presence of User#name
+ - Fixed postgres support
+ - Removed sqlite support
+ - Modified post-receive hook
+ - Milestones can be closed now
+ - Show comment events on dashboard
+ - Quick add team members via group#people page
- [API] expose created date for hooks and SSH keys
- [API] list, create issue notes
- [API] list, create snippet notes
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 5f8314462a2..00304dd3d64 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -1,26 +1,26 @@
-## Contribute to GitLab
+# Contact & support
-If you want to contribute to GitLab, follow this process:
+If you want quick help, head over to our [Support Forum](https://groups.google.com/forum/#!forum/gitlabhq).
+Otherwise you can follow our [Issue Submission Guide](https://github.com/gitlabhq/gitlabhq/wiki/Issue-Submission-Guide) for a more systematic and thorough guide to solving your issues.
-1. Fork the project
-2. Create a feature branch
-3. Code
-4. Create a pull request
-We will only accept pull requests if:
-* Your code has proper tests and all tests pass
-* Your code can be merged w/o problems
-* It won't break existing functionality
-* It's quality code
-* We like it :)
+# Contribute to GitLab
-For examples of feedback on pull requests please look at the [closed pull requests](https://github.com/gitlabhq/gitlabhq/pulls?direction=desc&page=1&sort=created&state=closed).
+## Recipes
-## Installation
+We collect user submitted installation scripts and config file templates for platforms we don't support officially.
+We believe there is merit in allowing a certain amount of diversity.
+You can get and submit your solution to running/configuring GitLab with your favorite OS/distro, database, web server, cloud hoster, configuration management tool, etc.
-Install the Gitlab development in a virtual machine with the [Gitlab Vagrant virtual machine](https://github.com/gitlabhq/gitlab-vagrant-vm). Installing it in a virtual machine makes it much easier to set up all the dependencies for integration testing.
+Help us improve the collection of [GitLab Recipes](https://github.com/gitlabhq/gitlab-recipes/)
-## Running tests
-For more information on running the tests please read the [development tips](https://github.com/gitlabhq/gitlabhq/blob/master/doc/development.md)
+## Feature suggestions
+
+Follow the [Issue Submission Guide](https://github.com/gitlabhq/gitlabhq/wiki/Issue-Submission-Guide) and support other peoples ideas or propose your own.
+
+
+## Code
+
+Follow our [Developer Guide](https://github.com/gitlabhq/gitlabhq/wiki/Developer-Guide) to set you up for hacking on GitLab.
diff --git a/Gemfile b/Gemfile
index fcda1353907..49fbcad04fc 100644
--- a/Gemfile
+++ b/Gemfile
@@ -124,7 +124,7 @@ group :development, :test do
gem "capybara"
gem "pry"
gem "awesome_print"
- gem "database_cleaner"
+ gem "database_cleaner", ref: "f89c34300e114be99532f14c115b2799a3380ac6", git: "https://github.com/bmabey/database_cleaner.git"
gem "launchy"
gem 'factory_girl_rails'
diff --git a/Gemfile.lock b/Gemfile.lock
index 7afacfce9cd..d8be14ba80a 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -1,4 +1,11 @@
GIT
+ remote: https://github.com/bmabey/database_cleaner.git
+ revision: f89c34300e114be99532f14c115b2799a3380ac6
+ ref: f89c34300e114be99532f14c115b2799a3380ac6
+ specs:
+ database_cleaner (0.9.1)
+
+GIT
remote: https://github.com/ctran/annotate_models.git
revision: be4e26825b521f0b2d86b181e2dff89901aa9b1e
specs:
@@ -140,7 +147,6 @@ GEM
colorize (0.5.8)
crack (0.3.1)
daemons (1.1.9)
- database_cleaner (0.9.1)
devise (2.1.2)
bcrypt-ruby (~> 3.0)
orm_adapter (~> 0.1)
@@ -458,7 +464,7 @@ DEPENDENCIES
chosen-rails (= 0.9.8)
coffee-rails (~> 3.2.2)
colored
- database_cleaner
+ database_cleaner!
devise (~> 2.1.0)
draper (~> 0.18.0)
email_spec
diff --git a/README.md b/README.md
index a8de834ceb6..629fcefcb32 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-# Welcome to GitLab [![build status](https://secure.travis-ci.org/gitlabhq/gitlabhq.png)](https://travis-ci.org/gitlabhq/gitlabhq) [![build status](https://secure.travis-ci.org/gitlabhq/grit.png)](https://travis-ci.org/gitlabhq/grit) [![Code Climate](https://codeclimate.com/badge.png)](https://codeclimate.com/github/gitlabhq/gitlabhq)
+# Welcome to GitLab [![build status](https://secure.travis-ci.org/gitlabhq/gitlabhq.png)](https://travis-ci.org/gitlabhq/gitlabhq) [![build status](https://secure.travis-ci.org/gitlabhq/grit.png)](https://travis-ci.org/gitlabhq/grit) [![Code Climate](https://codeclimate.com/badge.png)](https://codeclimate.com/github/gitlabhq/gitlabhq) [![Dependency Status](https://gemnasium.com/gitlabhq/gitlabhq.png)](https://gemnasium.com/gitlabhq/gitlabhq)
GitLab is a free project and repository management application
diff --git a/VERSION b/VERSION
index 0c042a83799..3cdeb6b85ee 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-4.0.0pre
+4.0.0rc1
diff --git a/app/assets/images/ajax_loader_gray.gif b/app/assets/images/ajax_loader_gray.gif
new file mode 100644
index 00000000000..af3f618bd0b
--- /dev/null
+++ b/app/assets/images/ajax_loader_gray.gif
Binary files differ
diff --git a/app/assets/images/logo.png b/app/assets/images/logo.png
deleted file mode 100644
index 2d08c9f6825..00000000000
--- a/app/assets/images/logo.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/logo_basic.png b/app/assets/images/logo_basic.png
deleted file mode 100644
index bc5ec128b90..00000000000
--- a/app/assets/images/logo_basic.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/logo_text.png b/app/assets/images/logo_text.png
deleted file mode 100644
index c74663930e4..00000000000
--- a/app/assets/images/logo_text.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/logo_text_tr.png b/app/assets/images/logo_text_tr.png
deleted file mode 100644
index fdb32ee29fe..00000000000
--- a/app/assets/images/logo_text_tr.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/logo_white.png b/app/assets/images/logo_white.png
index 366e3f3f3b9..e3415816558 100644
--- a/app/assets/images/logo_white.png
+++ b/app/assets/images/logo_white.png
Binary files differ
diff --git a/app/assets/images/switch_icon.png b/app/assets/images/switch_icon.png
new file mode 100644
index 00000000000..7c11f206593
--- /dev/null
+++ b/app/assets/images/switch_icon.png
Binary files differ
diff --git a/app/assets/javascripts/gfm_auto_complete.js.coffee b/app/assets/javascripts/gfm_auto_complete.js.coffee
index ffc4c409b54..1cc9d34dd80 100644
--- a/app/assets/javascripts/gfm_auto_complete.js.coffee
+++ b/app/assets/javascripts/gfm_auto_complete.js.coffee
@@ -1,52 +1,38 @@
# Creates the variables for setting up GFM auto-completion
window.GitLab ?= {}
-GitLab.GfmAutoComplete ?= {}
-
-# Emoji
-data = []
-template = "<li data-value='${insert}'>${name} <img alt='${name}' height='20' src='${image}' width='20' /></li>"
-GitLab.GfmAutoComplete.Emoji = {data, template}
-
-# Team Members
-data = []
-url = '';
-params = {private_token: '', page: 1}
-GitLab.GfmAutoComplete.Members = {data, url, params}
-
-# Add GFM auto-completion to all input fields, that accept GFM input.
-GitLab.GfmAutoComplete.setup = ->
- input = $('.js-gfm-input')
-
+GitLab.GfmAutoComplete =
# Emoji
- input.atWho ':',
- data: GitLab.GfmAutoComplete.Emoji.data,
- tpl: GitLab.GfmAutoComplete.Emoji.template
+ Emoji:
+ data: []
+ template: '<li data-value="${insert}">${name} <img alt="${name}" height="20" src="${image}" width="20" /></li>'
# Team Members
- input.atWho '@', (query, callback) ->
- (getMoreMembers = ->
- $.getJSON(GitLab.GfmAutoComplete.Members.url, GitLab.GfmAutoComplete.Members.params)
- .success (members) ->
- # pick the data we need
- newMembersData = $.map(members, (m) -> m.name )
-
- # add the new page of data to the rest
- $.merge(GitLab.GfmAutoComplete.Members.data, newMembersData)
-
- # show the pop-up with a copy of the current data
- callback(GitLab.GfmAutoComplete.Members.data[..])
-
- # are we past the last page?
- if newMembersData.length is 0
- # set static data and stop callbacks
- input.atWho '@',
- data: GitLab.GfmAutoComplete.Members.data
- callback: null
- else
- # get next page
- getMoreMembers()
+ Members:
+ data: []
+ url: ''
+ params:
+ private_token: ''
+ template: '<li data-value="${username}">${username} <small>${name}</small></li>'
+
+ # Add GFM auto-completion to all input fields, that accept GFM input.
+ setup: ->
+ input = $('.js-gfm-input')
+
+ # Emoji
+ input.atWho ':',
+ data: @Emoji.data
+ tpl: @Emoji.template
+
+ # Team Members
+ input.atWho '@',
+ tpl: @Members.template
+ callback: (query, callback) =>
+ request_params = $.extend({}, @Members.params, query: query)
+ $.getJSON(@Members.url, request_params).done (members) =>
+ new_members_data = $.map(members, (m) ->
+ username: m.username,
+ name: m.name
+ )
+ callback(new_members_data)
- # so the next request gets the next page
- GitLab.GfmAutoComplete.Members.params.page += 1
- ).call()
diff --git a/app/assets/javascripts/issues.js b/app/assets/javascripts/issues.js
index e2fe1075903..719d2c176c1 100644
--- a/app/assets/javascripts/issues.js
+++ b/app/assets/javascripts/issues.js
@@ -1,43 +1,3 @@
-function switchToNewIssue(){
- $(".issues_content").hide("fade", { direction: "left" }, 150, function(){
- $('select#issue_assignee_id').chosen();
- $('select#issue_milestone_id').chosen();
- $("#new_issue_dialog").show("fade", { direction: "right" }, 150);
- $('.top-tabs .add_new').hide();
- disableButtonIfEmptyField("#issue_title", ".save-btn");
- GitLab.GfmAutoComplete.setup();
- });
-}
-
-function switchToEditIssue(){
- $(".issues_content").hide("fade", { direction: "left" }, 150, function(){
- $('select#issue_assignee_id').chosen();
- $('select#issue_milestone_id').chosen();
- $("#edit_issue_dialog").show("fade", { direction: "right" }, 150);
- $('.add_new').hide();
- disableButtonIfEmptyField("#issue_title", ".save-btn");
- GitLab.GfmAutoComplete.setup();
- });
-}
-
-function switchFromNewIssue(){
- backToIssues();
-}
-
-function switchFromEditIssue(){
- backToIssues();
-}
-
-function backToIssues(){
- $("#edit_issue_dialog, #new_issue_dialog").hide("fade", { direction: "right" }, 150, function(){
- $(".issues_content").show("fade", { direction: "left" }, 150, function() {
- $("#edit_issue_dialog").html("");
- $("#new_issue_dialog").html("");
- $('.add_new').show();
- });
- });
-}
-
function initIssuesSearch() {
var href = $('#issue_search_form').attr('action');
var last_terms = '';
@@ -76,23 +36,15 @@ function issuesPage(){
$(this).closest("form").submit();
});
- $("#new_issue_link").click(function(){
- updateNewIssueURL();
- });
-
- $('body').on('ajax:success', '.close_issue, .reopen_issue, #new_issue', function(){
+ $('body').on('ajax:success', '.close_issue, .reopen_issue', function(){
var t = $(this),
totalIssues,
- reopen = t.hasClass('reopen_issue'),
- newIssue = false;
- if( this.id == 'new_issue' ){
- newIssue = true;
- }
- $('.issue_counter, #new_issue').each(function(){
+ reopen = t.hasClass('reopen_issue');
+ $('.issue_counter').each(function(){
var issue = $(this);
totalIssues = parseInt( $(this).html(), 10 );
- if( newIssue || ( reopen && issue.closest('.main_menu').length ) ){
+ if( reopen && issue.closest('.main_menu').length ){
$(this).html( totalIssues+1 );
}else {
$(this).html( totalIssues-1 );
@@ -126,20 +78,3 @@ function issuesCheckChanged() {
$('.issues_filters').show();
}
}
-
-function updateNewIssueURL(){
- var new_issue_link = $("#new_issue_link");
- var milestone_id = $("#milestone_id").val();
- var assignee_id = $("#assignee_id").val();
- var new_href = "";
- if(milestone_id){
- new_href = "issue[milestone_id]=" + milestone_id + "&";
- }
- if(assignee_id){
- new_href = new_href + "issue[assignee_id]=" + assignee_id;
- }
- if(new_href.length){
- new_href = new_issue_link.attr("href") + "?" + new_href;
- new_issue_link.attr("href", new_href);
- }
-};
diff --git a/app/assets/javascripts/main.js.coffee b/app/assets/javascripts/main.js.coffee
index bdb83f49474..f6c398c0acf 100644
--- a/app/assets/javascripts/main.js.coffee
+++ b/app/assets/javascripts/main.js.coffee
@@ -7,6 +7,18 @@ window.slugify = (text) ->
window.ajaxGet = (url) ->
$.ajax({type: "GET", url: url, dataType: "script"})
+window.errorMessage = (message) ->
+ ehtml = $("<p>")
+ ehtml.addClass("error_message")
+ ehtml.html(message)
+ ehtml
+
+window.split = (val) ->
+ return val.split( /,\s*/ )
+
+window.extractLast = (term) ->
+ return split( term ).pop()
+
# Disable button if text field is empty
window.disableButtonIfEmptyField = (field_selector, button_selector) ->
field = $(field_selector)
diff --git a/app/assets/javascripts/merge_requests.js b/app/assets/javascripts/merge_requests.js
index 170a0479de7..ee714f9cabb 100644
--- a/app/assets/javascripts/merge_requests.js
+++ b/app/assets/javascripts/merge_requests.js
@@ -26,6 +26,12 @@ var MergeRequest = {
self.showState(data.state);
}, "json");
}
+
+ if(self.opts.ci_enable){
+ $.get(self.opts.url_to_ci_check, function(data){
+ self.showCiState(data.status);
+ }, "json");
+ }
},
initTabs:
@@ -79,6 +85,11 @@ var MergeRequest = {
$(".automerge_widget." + state).show();
},
+ showCiState:
+ function(state){
+ $(".ci_widget").hide();
+ $(".ci_widget.ci-" + state).show();
+ },
loadDiff:
function() {
diff --git a/app/assets/stylesheets/application.css b/app/assets/stylesheets/application.css
deleted file mode 100644
index a23d4532915..00000000000
--- a/app/assets/stylesheets/application.css
+++ /dev/null
@@ -1,10 +0,0 @@
-/*
- * This is a manifest file that'll automatically include all the stylesheets available in this directory
- * and any sub-directories. You're free to add application-wide styles to this file and they'll appear at
- * the top of the compiled file, but it's generally better to create a new file per style scope.
- *= require jquery.ui.gitlab
- *= require jquery.atwho
- *= require chosen
- *= require_self
- *= require main
-*/
diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss
new file mode 100644
index 00000000000..54690e73f81
--- /dev/null
+++ b/app/assets/stylesheets/application.scss
@@ -0,0 +1,47 @@
+/*
+ * This is a manifest file that'll automatically include all the stylesheets available in this directory
+ * and any sub-directories. You're free to add application-wide styles to this file and they'll appear at
+ * the top of the compiled file, but it's generally better to create a new file per style scope.
+ *= require jquery.ui.gitlab
+ *= require jquery.atwho
+ *= require chosen
+ *= require_self
+*/
+
+/**
+ * GitLab bootstrap:
+ */
+@import "gitlab_bootstrap.scss";
+
+@import "common.scss";
+@import "ref_select.scss";
+
+@import "sections/header.scss";
+@import "sections/nav.scss";
+@import "sections/commits.scss";
+@import "sections/issues.scss";
+@import "sections/projects.scss";
+@import "sections/snippets.scss";
+@import "sections/votes.scss";
+@import "sections/merge_requests.scss";
+@import "sections/graph.scss";
+@import "sections/events.scss";
+@import "sections/themes.scss";
+@import "sections/tree.scss";
+@import "sections/notes.scss";
+@import "sections/profile.scss";
+@import "sections/login.scss";
+@import "sections/editor.scss";
+
+@import "highlight/white.scss";
+@import "highlight/dark.scss";
+
+/**
+ * UI themes:
+ */
+@import "themes/ui_basic.scss";
+@import "themes/ui_mars.scss";
+@import "themes/ui_modern.scss";
+@import "themes/ui_gray.scss";
+@import "themes/ui_color.scss";
+
diff --git a/app/assets/stylesheets/common.scss b/app/assets/stylesheets/common.scss
index 738ec2bf1dc..dcdfcdb289c 100644
--- a/app/assets/stylesheets/common.scss
+++ b/app/assets/stylesheets/common.scss
@@ -13,20 +13,12 @@ body {
margin: 0 0;
}
-.container .sidebar {
- width: 200px;
- height: 100%;
- min-height: 450px;
- float: right;
-}
-
-
.visible_link,
.author_link {
color: $link_color;
}
-.help li { color:#111 }
+.help li { color:$style_color; }
.back_link {
text-decoration: underline;
@@ -65,6 +57,9 @@ table a code {
background: url(ajax_loader.gif) no-repeat center center;
width: 40px;
height: 40px;
+ &.loading-gray {
+ background: url(ajax_loader_gray.gif) no-repeat center center;
+ }
}
/** FLASH message **/
@@ -96,28 +91,17 @@ table a code {
margin-right:50px
}
-.handle:hover {
- cursor: move;
-}
-
span.update-author {
display: block;
-}
-span.update-author {
color: #999;
font-weight: normal;
font-style: italic;
-}
-span.update-author strong {
- font-weight: bold;
- font-style: normal;
+ strong {
+ font-weight: bold;
+ font-style: normal;
+ }
}
-/** UPDATE ITEM **/
-span.update-author {
- display: block;
-}
-/** END UPDATE ITEM **/
.dashboard-loader {
float: left;
margin: 10px;
@@ -264,21 +248,6 @@ input.git_clone_url {
}
-/** bordered list **/
-ul.bordered-list {
- margin: 5px 0px;
- padding: 0px;
- li {
- padding: 5px 0;
- border-bottom: 1px solid #EEE;
- overflow: hidden;
- display: block;
- margin: 0px;
- }
-}
-
-ul.bordered-list li:last-child { border:none }
-
.line_holder {
&:hover {
td {
@@ -316,98 +285,6 @@ p.time {
}
-.ico {
- background: url("images.png") no-repeat -85px -77px;
- width: 19px;
- height: 16px;
- float: left;
- position: relative;
- margin-right: 10px;
- top: 8px;
-
- &.project {
- background-position: -37px -77px;
- }
-
- &.activities {
- background-position:-162px -22px;
- }
- &.projects {
- background-position:-209px -21px;
- }
-}
-
-.leftbar {
- h5, .title {
- padding: 5px 10px;
- }
-
- h4 {
- font-size: 14px;
- padding: 2px 10px;
- color: #666;
- border-bottom: 1px solid #f1f1f1;
- }
- a:last-child h4 { border: none; }
-
- a:hover {
- h4 {
- color: #111;
- background: $hover;
- border-color: #CCC;
- .ico.project {
- background-position:-209px -21px;
- }
- }
- }
- .bottom {
- padding: 10px;
- }
-}
-
-.votes {
- font-size: 13px;
- line-height: 15px;
- .progress {
- height: 4px;
- margin: 0;
- .bar {
- float: left;
- height: 100%;
- }
- .bar-success {
- @include linear-gradient(#62C462, #51A351);
- background-color: #468847;
- }
- .bar-danger {
- @include linear-gradient(#EE5F5B, #BD362F);
- background-color: #B94A48;
- }
- }
- .upvotes {
- display: inline-block;
- color: #468847;
- }
- .downvotes {
- display: inline-block;
- color: #B94A48;
- }
-}
-.votes-block {
- margin: 14px 6px 6px 0;
- .downvotes {
- float: right;
- }
-}
-.votes-inline {
- display: inline-block;
- margin: 0 8px;
- .progress {
- display: inline-block;
- padding: 0 0 2px;
- width: 45px;
- }
-}
/* Fix for readme code (stopped it from being yellow) */
.readme {
@@ -420,7 +297,6 @@ p.time {
}
}
-
.highlight_word {
background: #EEDC94;
}
@@ -428,23 +304,16 @@ p.time {
.status_info {
font-size: 14px;
padding: 5px 15px;
- line-height: 24px;
- width: 60px;
+ line-height: 26px;
text-align: center;
- float: left;
- margin-right: 20px;
+ float: right;
+ position: relative;
+ top: -5px;
+ @include border-radius(4px);
- &.success {
- background: #5BB75B;
- color: white;
- text-shadow: 0 1px #111;
- border-color: #9A9;
- }
&.error {
background: #DA4E49;
- border-color: #BD362F;
- color: white;
- text-shadow: 0 1px #111;
+ color: #FFF;
}
}
@@ -463,16 +332,6 @@ p.time {
height: 150px;
}
-.gitlab_pagination {
- span a { color: $link_color; }
- .prev, .next, .current, .page a {
- padding: 10px;
- }
- .current {
- border-bottom: 2px solid $style_color;
- }
-}
-
// Fixes alignment on notes.
.new_note {
label {
@@ -647,9 +506,14 @@ pre {
}
}
-.milestone .progress {
- margin-bottom: 0;
- margin-top: 4px;
+.milestone {
+ &.milestone-closed {
+ background: #eee;
+ }
+ .progress {
+ margin-bottom: 0;
+ margin-top: 4px;
+ }
}
.float-link {
diff --git a/app/assets/stylesheets/gitlab_bootstrap.scss b/app/assets/stylesheets/gitlab_bootstrap.scss
new file mode 100644
index 00000000000..f53e0e50bab
--- /dev/null
+++ b/app/assets/stylesheets/gitlab_bootstrap.scss
@@ -0,0 +1,26 @@
+/** Override bootstrap variables **/
+$baseFontSize: 13px !default;
+$baseLineHeight: 18px !default;
+
+// BOOTSTRAP
+@import "bootstrap";
+@import "bootstrap/responsive-utilities";
+@import "bootstrap/responsive-1200px-min";
+
+@import "font-awesome";
+
+/**
+ * GitLab bootstrap.
+ * Overrides some styles of twitter bootstrap.
+ * Also give some common classes for GitLab app
+ */
+@import "gitlab_bootstrap/variables.scss";
+@import "gitlab_bootstrap/fonts.scss";
+@import "gitlab_bootstrap/mixins.scss";
+@import "gitlab_bootstrap/common.scss";
+@import "gitlab_bootstrap/typography.scss";
+@import "gitlab_bootstrap/buttons.scss";
+@import "gitlab_bootstrap/blocks.scss";
+@import "gitlab_bootstrap/files.scss";
+@import "gitlab_bootstrap/tables.scss";
+@import "gitlab_bootstrap/lists.scss";
diff --git a/app/assets/stylesheets/gitlab_bootstrap/blocks.scss b/app/assets/stylesheets/gitlab_bootstrap/blocks.scss
index f08e5dc7904..f9c8b7b05ea 100644
--- a/app/assets/stylesheets/gitlab_bootstrap/blocks.scss
+++ b/app/assets/stylesheets/gitlab_bootstrap/blocks.scss
@@ -41,6 +41,15 @@
}
}
+ .top_box_content {
+ .box-title {
+ color: $style_color;
+ font-size: 18px;
+ font-weight: normal;
+ line-height: 28px;
+ }
+ }
+
.middle_box_content {
@include border-radius(0);
border: none;
@@ -65,7 +74,7 @@
border: 1px solid #eaeaea;
@include border-radius(4px);
-
+
border-color: #CCC;
@include solid-shade;
@@ -84,6 +93,10 @@
border-top: 1px solid #eaeaea;
border-bottom: 1px solid #bbb;
+ > a {
+ text-shadow: 0 1px 1px #fff;
+ }
+
&.small {
line-height: 28px;
font-size: 14px;
@@ -139,19 +152,6 @@
}
}
- li, .wll {
- padding: 10px;
- &:first-child {
- @include border-radius(4px 4px 0 0);
- border-top: none;
- }
-
- &:last-child {
- @include border-radius(0 0 4px 4px);
- border: none;
- }
- }
-
.ui-box-body {
padding: 10px;
}
diff --git a/app/assets/stylesheets/gitlab_bootstrap/common.scss b/app/assets/stylesheets/gitlab_bootstrap/common.scss
index d6089cea6dc..3bb7cdbf706 100644
--- a/app/assets/stylesheets/gitlab_bootstrap/common.scss
+++ b/app/assets/stylesheets/gitlab_bootstrap/common.scss
@@ -10,11 +10,6 @@
/** COMMON CLASSES **/
.left { float:left }
.right { float:right!important }
-.width-50p { width:50% }
-.width-49p { width:49% }
-.width-30p { width:30% }
-.width-65p { width:65% }
-.width-100p { width:100% }
.append-bottom-10 { margin-bottom:10px }
.append-bottom-20 { margin-bottom:20px }
.prepend-top-10 { margin-top:10px }
@@ -30,6 +25,7 @@
.borders { border: 1px solid #ccc; @include shade; }
.hint { font-style: italic; color: #999; }
.light { color: #888 }
+.tiny { font-weight: normal }
/** PILLS & TABS**/
.nav-pills a:hover { background-color: #888; }
@@ -99,4 +95,21 @@ input[type='search'].search-text-input {
border: 1px solid #ccc;
}
+input[type='text'].danger {
+ background: #F2DEDE!important;
+ border-color: #D66;
+ text-shadow: 0 1px 1px #fff
+}
+
fieldset legend { font-size: 17px; }
+
+/** PAGINATION **/
+.gitlab_pagination {
+ span a { color: $link_color; }
+ .prev, .next, .current, .page a {
+ padding: 10px;
+ }
+ .current {
+ border-bottom: 2px solid $style_color;
+ }
+}
diff --git a/app/assets/stylesheets/fonts.scss b/app/assets/stylesheets/gitlab_bootstrap/fonts.scss
index 88c966d18f7..88c966d18f7 100644
--- a/app/assets/stylesheets/fonts.scss
+++ b/app/assets/stylesheets/gitlab_bootstrap/fonts.scss
diff --git a/app/assets/stylesheets/gitlab_bootstrap/lists.scss b/app/assets/stylesheets/gitlab_bootstrap/lists.scss
index 5bd087b080e..edaf3cef2cf 100644
--- a/app/assets/stylesheets/gitlab_bootstrap/lists.scss
+++ b/app/assets/stylesheets/gitlab_bootstrap/lists.scss
@@ -1,23 +1,38 @@
-/** LISTS **/
-
-ul {
- /**
- * List li block element #1
- *
- */
- .wll {
+/**
+ * Well styled list
+ *
+ */
+.well-list {
+ margin: 0;
+ list-style: none;
+ li {
background-color: #FFF;
- padding: 10px 5px;
+ padding: 10px;
min-height: 20px;
border-bottom: 1px solid #eee;
border-bottom: 1px solid rgba(0, 0, 0, 0.05);
+ &.disabled {
+ color: #888;
+ }
+
&.smoke { background-color: #f5f5f5; }
+
&:hover {
background: $hover;
border-bottom: 1px solid #ADF;
}
- &:last-child { border:none }
+
+ &:first-child {
+ @include border-radius(4px 4px 0 0);
+ border-top: none;
+ }
+
+ &:last-child {
+ @include border-radius(0 0 4px 4px);
+ border: none;
+ }
+
.author { color: #999; }
p {
@@ -29,6 +44,11 @@ ul {
top: 3px;
}
}
+
+ .well-title {
+ font-size: 14px;
+ line-height: 18px;
+ }
}
}
@@ -39,3 +59,17 @@ ol, ul {
}
}
}
+
+/** light list with border-bottom between li **/
+ul.bordered-list {
+ margin: 5px 0px;
+ padding: 0px;
+ li {
+ padding: 5px 0;
+ border-bottom: 1px solid #EEE;
+ overflow: hidden;
+ display: block;
+ margin: 0px;
+ &:last-child { border:none }
+ }
+}
diff --git a/app/assets/stylesheets/mixins.scss b/app/assets/stylesheets/gitlab_bootstrap/mixins.scss
index 441a85f3410..81830368c4c 100644
--- a/app/assets/stylesheets/mixins.scss
+++ b/app/assets/stylesheets/gitlab_bootstrap/mixins.scss
@@ -57,4 +57,13 @@
@mixin solid-shade {
@include box-shadow(0 0 0 3px #f1f1f1);
-} \ No newline at end of file
+}
+
+@mixin header-font {
+ color: $style_color;
+ text-shadow: 0 1px 1px #FFF;
+ font-family: 'Korolev', sans-serif;
+ font-size: 28px;
+ line-height: 48px;
+ font-weight: normal;
+}
diff --git a/app/assets/stylesheets/variables.scss b/app/assets/stylesheets/gitlab_bootstrap/variables.scss
index ba78c8351f4..869eb168c0d 100644
--- a/app/assets/stylesheets/variables.scss
+++ b/app/assets/stylesheets/gitlab_bootstrap/variables.scss
@@ -2,4 +2,4 @@
$primary_color: #2FA0BB;
$link_color: #3A89A3;
$style_color: #474D57;
-$hover: #D9EDF7; \ No newline at end of file
+$hover: #D9EDF7;
diff --git a/app/assets/stylesheets/highlight/dark.scss b/app/assets/stylesheets/highlight/dark.scss
index 4196ea7ad29..178bd583aec 100644
--- a/app/assets/stylesheets/highlight/dark.scss
+++ b/app/assets/stylesheets/highlight/dark.scss
@@ -2,6 +2,7 @@
pre {
background-color: #333;
color: #eee;
+ float: left;
}
.hll { display: block; background-color: darken($hover, 65%) }
diff --git a/app/assets/stylesheets/jquery.ui.gitlab.css b/app/assets/stylesheets/jquery.ui.gitlab.css
index 171857657b6..5c51600ba67 100644
--- a/app/assets/stylesheets/jquery.ui.gitlab.css
+++ b/app/assets/stylesheets/jquery.ui.gitlab.css
@@ -1,27 +1,3 @@
-/*
- * jQuery UI CSS Framework 1.8.7
- *
- * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT or GPL Version 2 licenses.
- * http://jquery.org/license
- *
- * http://docs.jquery.com/UI/Theming/API
- */
-
-/* Layout helpers
-----------------------------------*/
-.ui-helper-hidden { display: none; }
-.ui-helper-hidden-accessible { position: absolute !important; clip: rect(1px 1px 1px 1px); clip: rect(1px,1px,1px,1px); }
-.ui-helper-reset { margin: 0; padding: 0; border: 0; outline: 0; line-height: 1.3; text-decoration: none; font-size: 100%; list-style: none; }
-.ui-helper-clearfix:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; }
-.ui-helper-clearfix { display: inline-block; }
-/* required comment for clearfix to work in Opera \*/
-* html .ui-helper-clearfix { height:1%; }
-.ui-helper-clearfix { display:block; }
-/* end clearfix */
-.ui-helper-zfix { width: 100%; height: 100%; top: 0; left: 0; position: absolute; opacity: 0; filter:Alpha(Opacity=0); }
-
-
/* Interaction Cues
----------------------------------*/
.ui-state-disabled { cursor: default !important; }
@@ -141,26 +117,6 @@
.ui-widget-overlay { background: #262b33; opacity: .70;filter:Alpha(Opacity=70); }
.ui-widget-shadow { margin: -8px 0 0 -8px; padding: 8px; background: #000000; opacity: .30;filter:Alpha(Opacity=30); -moz-border-radius: 8px; -webkit-border-radius: 8px; border-radius: 8px; }
/*
- * jQuery UI Resizable 1.8.7
- *
- * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT or GPL Version 2 licenses.
- * http://jquery.org/license
- *
- * http://docs.jquery.com/UI/Resizable#theming
- */
-.ui-resizable { position: relative;}
-.ui-resizable-handle { position: absolute; font-size: 0.1px; z-index: 999; display: block;}
-.ui-resizable-disabled .ui-resizable-handle, .ui-resizable-autohide .ui-resizable-handle { display: none; }
-.ui-resizable-n { cursor: n-resize; height: 7px; width: 100%; top: -5px; left: 0; }
-.ui-resizable-s { cursor: s-resize; height: 7px; width: 100%; bottom: -5px; left: 0; }
-.ui-resizable-e { cursor: e-resize; width: 7px; right: -5px; top: 0; height: 100%; }
-.ui-resizable-w { cursor: w-resize; width: 7px; left: -5px; top: 0; height: 100%; }
-.ui-resizable-se { cursor: se-resize; width: 12px; height: 12px; right: 1px; bottom: 1px; }
-.ui-resizable-sw { cursor: sw-resize; width: 9px; height: 9px; left: -5px; bottom: -5px; }
-.ui-resizable-nw { cursor: nw-resize; width: 9px; height: 9px; left: -5px; top: -5px; }
-.ui-resizable-ne { cursor: ne-resize; width: 9px; height: 9px; right: -5px; top: -5px;}
-/*
* jQuery UI Selectable 1.8.7
*
* Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
@@ -240,34 +196,7 @@
cursor: pointer;
font-weight: bold;
}
-/*
- * jQuery UI Slider 1.8.7
- *
- * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT or GPL Version 2 licenses.
- * http://jquery.org/license
- *
- * http://docs.jquery.com/UI/Slider#theming
- */
-.ui-slider { position: relative; text-align: left; background: #d7d7d7; z-index: 1; }
-.ui-slider { -moz-box-shadow: 0 1px 2px rgba(0,0,0,0.5) inset; -webkit-box-shadow: 0 1px 2px rgba(0,0,0,0.5) inset; box-shadow: 0 1px 2px rgba(0,0,0,0.5) inset; }
-.ui-slider .ui-slider-handle { background: url(slider_handles.png) 0px -23px no-repeat; position: absolute; z-index: 2; width: 23px; height: 23px; cursor: default; border: none; outline: none; -moz-box-shadow: none; -webkit-box-shadow: none; box-shadow: none; }
-.ui-slider .ui-state-hover, .ui-slider .ui-state-active { background-position: 0 0; }
-.ui-slider .ui-slider-range { background: #a3cae0; position: absolute; z-index: 1; font-size: .7em; display: block; border: 0; background-position: 0 0; }
-.ui-slider .ui-slider-range { -moz-box-shadow: 0 1px 2px rgba(17,35,45,0.6) inset; -webkit-box-shadow: 0 1px 2px rgba(17,35,45,0.6) inset; box-shadow: 0 1px 2px rgba(17,35,45,0.6) inset; }
-
-.ui-slider-horizontal { height: 5px; }
-.ui-slider-horizontal .ui-slider-handle { top: -8px; margin-left: -13px; }
-.ui-slider-horizontal .ui-slider-range { top: 0; height: 100%; }
-.ui-slider-horizontal .ui-slider-range-min { left: 0; }
-.ui-slider-horizontal .ui-slider-range-max { right: 0; }
-
-.ui-slider-vertical { width: 5px; height: 100px; }
-.ui-slider-vertical .ui-slider-handle { left: -8px; margin-left: 0; margin-bottom: -13px; }
-.ui-slider-vertical .ui-slider-range { left: 0; width: 100%; }
-.ui-slider-vertical .ui-slider-range-min { bottom: 0; }
-.ui-slider-vertical .ui-slider-range-max { top: 0; }
/*
* jQuery UI Datepicker 1.8.7
*
@@ -326,45 +255,3 @@
.ui-datepicker table .ui-state-highlight { border-color: #ADE; }
.ui-datepicker-calendar .ui-state-default { background: transparent; border-color: #FFF; }
.ui-datepicker-calendar .ui-state-active { background: #D9EDF7; border-color: #ADE; color: #3A89A3; font-weight: bold; text-shadow: 0 1px 1px #fff; }
-
-/* with multiple calendars */
-.ui-datepicker.ui-datepicker-multi { width:auto; }
-.ui-datepicker-multi .ui-datepicker-group { float:left; }
-.ui-datepicker-multi .ui-datepicker-group table { width:95%; margin:0 auto .4em; }
-.ui-datepicker-multi-2 .ui-datepicker-group { width:50%; }
-.ui-datepicker-multi-3 .ui-datepicker-group { width:33.3%; }
-.ui-datepicker-multi-4 .ui-datepicker-group { width:25%; }
-.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header { border-left-width:0; }
-.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header { border-left-width:0; }
-.ui-datepicker-multi .ui-datepicker-buttonpane { clear:left; }
-.ui-datepicker-row-break { clear:both; width:100%; }
-
-
-/* Extra Input Field Styling */
-.ui-form textarea, .ui-form input:not([type="submit"]):not([type="button"]):not([type="checkbox"]):not([type="radio"]):not([type="file"]):not([type="range"]) {
- padding: 3px;
- -webkit-border-radius: 2px;
- -moz-border-radius: 2px;
- border-radius: 2px;
- border: 1px solid #cecece;
- outline: none;
- -webkit-box-shadow: 0 1px 3px rgba(0,0,0,0.1) inset, 0 1px 0 rgba(255,255,255,0.2);
- -moz-box-shadow: 0 1px 3px rgba(0,0,0,0.1) inset, 0 1px 0 rgba(255,255,255,0.2);
- box-shadow: 0 1px 3px rgba(0,0,0,0.1) inset, 0 1px 0 rgba(255,255,255,0.2);
- -webkit-transition: all 250ms ease-in-out;
- -moz-transition: all 250ms ease-in-out;
- -o-transition: all 250ms ease-in-out;
- transition: all 250ms ease-in-out;
-}
-.ui-form textarea:hover, .ui-form input:not([type="submit"]):not([type="button"]):not([type="checkbox"]):not([type="radio"]):not([type="file"]):not([type="range"]):hover {
- border: 1px solid #bdbdbd;
- -webkit-box-shadow: 0 1px 3px rgba(0,0,0,0.2) inset, 0 1px 0 rgba(255,255,255,0.2);
- -moz-box-shadow: 0 1px 3px rgba(0,0,0,0.2) inset, 0 1px 0 rgba(255,255,255,0.2);
- box-shadow: 0 1px 3px rgba(0,0,0,0.2) inset, 0 1px 0 rgba(255,255,255,0.2);
-}
-.ui-form textarea:focus, .ui-form input:not([type="submit"]):not([type="button"]):not([type="checkbox"]):not([type="radio"]):not([type="file"]):not([type="range"]):focus {
- border: 1px solid #95bdd4;
- -webkit-box-shadow: 0 2px 3px rgba(161,202,226,0.5) inset, 0 1px 0 rgba(255,255,255,0.2);
- -moz-box-shadow: 0 2px 3px rgba(161,202,226,0.5) inset, 0 1px 0 rgba(255,255,255,0.2);
- box-shadow: 0 2px 3px rgba(161,202,226,0.5) inset, 0 1px 0 rgba(255,255,255,0.2);
-}
diff --git a/app/assets/stylesheets/main.scss b/app/assets/stylesheets/main.scss
deleted file mode 100644
index bc7a74406ef..00000000000
--- a/app/assets/stylesheets/main.scss
+++ /dev/null
@@ -1,139 +0,0 @@
-/** Override bootstrap variables **/
-$baseFontSize: 13px !default;
-$baseLineHeight: 18px !default;
-
-// BOOTSTRAP
-@import "bootstrap";
-@import "bootstrap/responsive-utilities";
-@import "bootstrap/responsive-1200px-min";
-
-// FONT AWESOME
-@import "font-awesome";
-
-/**
- * Variables
- * Contains colors
- */
-@import "variables.scss";
-
-/**
- * Custom fonts
- * Contains @font-face font Korolev and default $monotype
- */
-@import "fonts.scss";
-
-/**
- * General mixins.
- * Contains rounded borders, gradients and shades
- */
-@import "mixins.scss";
-
-/**
- * Header of application.
- * Contain application logo, search panel, profile icon
- */
-@import "sections/header.scss";
-
-/**
- * Navigation menu of application.
- * Panel with links to pages depends on project, profile or admin area
- */
-@import "sections/nav.scss";
-
-/**
- * This file represent some UI that can be changed
- * during web app restyle or theme select.
- *
- * Next items should be placed there
- * - link, button colors
- * - header restyles
- * - main menu restyles
- *
- */
-@import "themes/ui_basic.scss";
-
-/**
- * UI themes:
- */
-@import "themes/ui_mars.scss";
-@import "themes/ui_modern.scss";
-@import "themes/ui_gray.scss";
-@import "themes/ui_color.scss";
-
-/**
- * GitLab bootstrap.
- * Overrides some styles of twitter bootstrap.
- * Also give some common classes for GitLab app
- */
-@import "gitlab_bootstrap/common.scss";
-@import "gitlab_bootstrap/typography.scss";
-@import "gitlab_bootstrap/buttons.scss";
-@import "gitlab_bootstrap/blocks.scss";
-@import "gitlab_bootstrap/files.scss";
-@import "gitlab_bootstrap/tables.scss";
-@import "gitlab_bootstrap/lists.scss";
-
-
-/**
- * Most of application styles placed here.
- * This file represent common UI that should not be changed between themes
- * or project restyling like form width or user avatar class or commit title
- *
- * TODO: clean it
- */
-@import "common.scss";
-
-/**
- * Styles related to specific part of app
- */
-@import "sections/commits.scss";
-@import "sections/issues.scss";
-@import "sections/projects.scss";
-@import "sections/merge_requests.scss";
-@import "sections/graph.scss";
-@import "sections/events.scss";
-@import "sections/themes.scss";
-
-/**
- * This scss file redefine chozen selectbox styles for
- * project Branch/Tag select element
- */
-@import "ref_select.scss";
-
-/**
- * Code (files list) styles. Browsing project files there
- */
-@import "sections/tree.scss";
-
-/**
- * This file represent notes(comments) styles
- */
-@import "sections/notes.scss";
-
-/**
- * This file represent profile styles
- */
-@import "sections/profile.scss";
-
-/**
- * Devise styles
- */
-@import "sections/login.scss";
-
-/**
- * CODE HIGHTLIGHT BASE
- *
- */
-@import "highlight/white.scss";
-
-/**
- * CODE HIGHTLIGHT DARK schema
- *
- */
-@import "highlight/dark.scss";
-
-/**
- * File Editor styles
- *
- */
-@import "sections/editor.scss";
diff --git a/app/assets/stylesheets/sections/commits.scss b/app/assets/stylesheets/sections/commits.scss
index bf405bfcd51..7ed53333f8c 100644
--- a/app/assets/stylesheets/sections/commits.scss
+++ b/app/assets/stylesheets/sections/commits.scss
@@ -229,8 +229,6 @@
/** COMMIT ROW **/
.commit {
- @extend .wll;
-
.browse_code_link_holder {
@extend .span2;
float: right;
@@ -302,3 +300,17 @@
color: #fff;
font-family: $monospace;
}
+
+
+.commits-compare-switch{
+ background: url("switch_icon.png") no-repeat center center;
+ width: 16px;
+ height: 18px;
+ text-indent: -9999px;
+ float: left;
+ margin-right: 9px;
+ border: 1px solid #DDD;
+ @include border-radius(4px);
+ padding: 4px;
+ background-color: #EEE;
+}
diff --git a/app/assets/stylesheets/sections/events.scss b/app/assets/stylesheets/sections/events.scss
index 28551d9a6ee..071a9c35468 100644
--- a/app/assets/stylesheets/sections/events.scss
+++ b/app/assets/stylesheets/sections/events.scss
@@ -31,7 +31,6 @@
*
*/
.event-item {
- min-height: 40px;
border-bottom: 1px solid #eee;
.event-title {
color: #333;
@@ -50,14 +49,18 @@
}
}
.avatar {
- width: 32px;
+ position: relative;
+ top: -3px;
}
.event_icon {
+ position: relative;
float: right;
border: 1px solid #EEE;
padding: 5px;
@include border-radius(5px);
background: #F9F9F9;
+ margin-left: 10px;
+ top: -6px;
img {
width: 20px;
}
@@ -71,9 +74,8 @@
}
}
- padding: 15px 5px;
+ padding: 16px 5px;
&:last-child { border:none }
- .wll:hover { background:none }
.event_commits {
margin-top: 5px;
diff --git a/app/assets/stylesheets/sections/header.scss b/app/assets/stylesheets/sections/header.scss
index 1efe23a127f..c1b210be1ab 100644
--- a/app/assets/stylesheets/sections/header.scss
+++ b/app/assets/stylesheets/sections/header.scss
@@ -44,14 +44,9 @@ header {
background: url('logo_dark.png') no-repeat 0px 2px;
float: left;
margin-left: 2px;
- font-size: 30px;
- line-height: 48px;
- font-weight: normal;
- color: $style_color;
- text-shadow: 0 1px 1px #FFF;
padding-left: 45px;
height: 40px;
- font-family: 'Korolev', sans-serif;
+ @include header-font;
}
}
}
@@ -66,12 +61,7 @@ header {
float: left;
margin: 0;
margin-right: 30px;
- font-size: 30px;
- line-height: 48px;
- font-weight: normal;
- color: $style_color;
- text-shadow: 0 1px 1px #FFF;
- font-family: 'Korolev', sans-serif;
+ @include header-font;
}
/**
diff --git a/app/assets/stylesheets/sections/issues.scss b/app/assets/stylesheets/sections/issues.scss
index ef3821f23ef..fd995728978 100644
--- a/app/assets/stylesheets/sections/issues.scss
+++ b/app/assets/stylesheets/sections/issues.scss
@@ -121,12 +121,3 @@ input.check_all_issues {
#update_status {
width: 100px;
}
-
-
-/**
- * Milestones list
- *
- */
-.milestone {
- @extend .wll;
-}
diff --git a/app/assets/stylesheets/sections/merge_requests.scss b/app/assets/stylesheets/sections/merge_requests.scss
index a5ec1756e5f..4808117d02a 100644
--- a/app/assets/stylesheets/sections/merge_requests.scss
+++ b/app/assets/stylesheets/sections/merge_requests.scss
@@ -136,9 +136,3 @@ li.merge_request {
}
}
}
-
-.status-badge {
- height: 32px;
- width: 100%;
- @include border-radius(5px);
-}
diff --git a/app/assets/stylesheets/sections/projects.scss b/app/assets/stylesheets/sections/projects.scss
index 3f4b591a5dd..717f85024cc 100644
--- a/app/assets/stylesheets/sections/projects.scss
+++ b/app/assets/stylesheets/sections/projects.scss
@@ -8,7 +8,7 @@
.groups_box,
.projects_box {
- h5 {
+ > h5 {
color: $style_color;
font-size: 16px;
text-shadow: 0 1px 1px #fff;
@@ -16,37 +16,22 @@
line-height: 32px;
font-size: 14px;
}
- ul {
- li {
- padding: 0;
- a {
- display: block;
- .group_name {
- font-size: 14px;
- line-height: 18px;
- }
- .project_name {
- color: #4fa2bd;
- font-size: 14px;
- line-height: 18px;
- }
- .arrow {
- float: right;
- padding: 10px;
- margin: 0;
- }
- .last_activity {
- padding-top: 5px;
- display: block;
- span, strong {
- font-size: 12px;
- color: #666;
- }
- }
+ .nav-projects-tabs li { padding: 0; }
+ .well-list {
+ .arrow {
+ float: right;
+ padding: 10px;
+ margin: 0;
+ }
+ .last_activity {
+ padding-top: 5px;
+ display: block;
+ span, strong {
+ font-size: 12px;
+ color: #666;
}
}
}
- @extend .leftbar;
@extend .ui-box;
}
}
diff --git a/app/assets/stylesheets/sections/snippets.scss b/app/assets/stylesheets/sections/snippets.scss
new file mode 100644
index 00000000000..3944814fc3e
--- /dev/null
+++ b/app/assets/stylesheets/sections/snippets.scss
@@ -0,0 +1,9 @@
+.snippet.file_holder {
+ .file_title {
+ .snippet-file-name {
+ position: relative;
+ top: -4px;
+ left: -4px;
+ }
+ }
+}
diff --git a/app/assets/stylesheets/sections/votes.scss b/app/assets/stylesheets/sections/votes.scss
new file mode 100644
index 00000000000..4686f5422dc
--- /dev/null
+++ b/app/assets/stylesheets/sections/votes.scss
@@ -0,0 +1,43 @@
+.votes {
+ font-size: 13px;
+ line-height: 15px;
+ .progress {
+ height: 4px;
+ margin: 0;
+ .bar {
+ float: left;
+ height: 100%;
+ }
+ .bar-success {
+ @include linear-gradient(#62C462, #51A351);
+ background-color: #468847;
+ }
+ .bar-danger {
+ @include linear-gradient(#EE5F5B, #BD362F);
+ background-color: #B94A48;
+ }
+ }
+ .upvotes {
+ display: inline-block;
+ color: #468847;
+ }
+ .downvotes {
+ display: inline-block;
+ color: #B94A48;
+ }
+}
+.votes-block {
+ margin: 14px 6px 6px 0;
+ .downvotes {
+ float: right;
+ }
+}
+.votes-inline {
+ display: inline-block;
+ margin: 0 8px;
+ .progress {
+ display: inline-block;
+ padding: 0 0 2px;
+ width: 45px;
+ }
+}
diff --git a/app/assets/stylesheets/themes/ui_basic.scss b/app/assets/stylesheets/themes/ui_basic.scss
index fee179899ce..b377727779a 100644
--- a/app/assets/stylesheets/themes/ui_basic.scss
+++ b/app/assets/stylesheets/themes/ui_basic.scss
@@ -4,18 +4,6 @@
*
*/
.ui_basic {
- /*
- * Common styles
- *
- */
- a {
- color: $link_color;
- &:hover {
- text-decoration: none;
- color: $primary_color;
- }
- }
-
.app_logo {
.separator {
margin-left: 0;
diff --git a/app/controllers/admin/groups_controller.rb b/app/controllers/admin/groups_controller.rb
index 4fad8d2bdea..a492e66611f 100644
--- a/app/controllers/admin/groups_controller.rb
+++ b/app/controllers/admin/groups_controller.rb
@@ -2,7 +2,7 @@ class Admin::GroupsController < AdminController
before_filter :group, only: [:edit, :show, :update, :destroy, :project_update]
def index
- @groups = Group.scoped
+ @groups = Group.order('name ASC')
@groups = @groups.search(params[:name]) if params[:name].present?
@groups = @groups.page(params[:page]).per(20)
end
diff --git a/app/controllers/admin/users_controller.rb b/app/controllers/admin/users_controller.rb
index 744b1912a6c..5f259bd7e27 100644
--- a/app/controllers/admin/users_controller.rb
+++ b/app/controllers/admin/users_controller.rb
@@ -3,7 +3,7 @@ class Admin::UsersController < AdminController
@admin_users = User.scoped
@admin_users = @admin_users.filter(params[:filter])
@admin_users = @admin_users.search(params[:name]) if params[:name].present?
- @admin_users = @admin_users.order("updated_at DESC").page(params[:page])
+ @admin_users = @admin_users.order("name ASC").page(params[:page])
end
def show
@@ -30,7 +30,7 @@ class Admin::UsersController < AdminController
def new
- @admin_user = User.new({ projects_limit: Gitlab.config.default_projects_limit }, as: :admin)
+ @admin_user = User.new({ projects_limit: Gitlab.config.gitlab.default_projects_limit }, as: :admin)
end
def edit
diff --git a/app/controllers/groups_controller.rb b/app/controllers/groups_controller.rb
index 93c495363d9..0aecd9c6a11 100644
--- a/app/controllers/groups_controller.rb
+++ b/app/controllers/groups_controller.rb
@@ -49,6 +49,7 @@ class GroupsController < ApplicationController
def people
@project = group.projects.find(params[:project_id]) if params[:project_id]
@users = @project ? @project.users : group.users
+ @users.sort_by!(&:name)
if @project
@team_member = @project.users_projects.new
diff --git a/app/controllers/issues_controller.rb b/app/controllers/issues_controller.rb
index 0f28fc3a111..5a1ce2cfcc4 100644
--- a/app/controllers/issues_controller.rb
+++ b/app/controllers/issues_controller.rb
@@ -1,6 +1,6 @@
class IssuesController < ProjectResourceController
before_filter :module_enabled
- before_filter :issue, only: [:edit, :update, :destroy, :show]
+ before_filter :issue, only: [:edit, :update, :show]
# Allow read any issue
before_filter :authorize_read_issue!
@@ -11,9 +11,6 @@ class IssuesController < ProjectResourceController
# Allow modify issue
before_filter :authorize_modify_issue!, only: [:edit, :update]
- # Allow destroy issue
- before_filter :authorize_admin_issue!, only: [:destroy]
-
respond_to :js, :html
def index
@@ -77,15 +74,6 @@ class IssuesController < ProjectResourceController
end
end
- def destroy
- @issue.destroy
-
- respond_to do |format|
- format.html { redirect_to project_issues_path }
- format.js { render nothing: true }
- end
- end
-
def sort
return render_404 unless can?(current_user, :admin_issue, @project)
diff --git a/app/controllers/merge_requests_controller.rb b/app/controllers/merge_requests_controller.rb
index 362962707fd..fa4eaff8469 100644
--- a/app/controllers/merge_requests_controller.rb
+++ b/app/controllers/merge_requests_controller.rb
@@ -1,6 +1,6 @@
class MergeRequestsController < ProjectResourceController
before_filter :module_enabled
- before_filter :merge_request, only: [:edit, :update, :destroy, :show, :commits, :diffs, :automerge, :automerge_check]
+ before_filter :merge_request, only: [:edit, :update, :show, :commits, :diffs, :automerge, :automerge_check, :ci_status]
before_filter :validates_merge_request, only: [:show, :diffs]
before_filter :define_show_vars, only: [:show, :diffs]
@@ -13,9 +13,6 @@ class MergeRequestsController < ProjectResourceController
# Allow modify merge_request
before_filter :authorize_modify_merge_request!, only: [:close, :edit, :update, :sort]
- # Allow destroy merge_request
- before_filter :authorize_admin_merge_request!, only: [:destroy]
-
def index
@merge_requests = MergeRequestsLoadContext.new(project, current_user, params).execute
end
@@ -85,14 +82,6 @@ class MergeRequestsController < ProjectResourceController
end
end
- def destroy
- @merge_request.destroy
-
- respond_to do |format|
- format.html { redirect_to project_merge_requests_url(@project) }
- end
- end
-
def branch_from
@commit = project.commit(params[:ref])
@commit = CommitDecorator.decorate(@commit)
@@ -103,6 +92,13 @@ class MergeRequestsController < ProjectResourceController
@commit = CommitDecorator.decorate(@commit)
end
+ def ci_status
+ status = project.gitlab_ci_service.commit_status(merge_request.last_commit.sha)
+ response = { status: status }
+
+ render json: response
+ end
+
protected
def merge_request
diff --git a/app/controllers/milestones_controller.rb b/app/controllers/milestones_controller.rb
index fadfee2dc06..a0c824e8abb 100644
--- a/app/controllers/milestones_controller.rb
+++ b/app/controllers/milestones_controller.rb
@@ -12,11 +12,12 @@ class MilestonesController < ProjectResourceController
def index
@milestones = case params[:f]
- when 'all'; @project.milestones
- else @project.milestones.active
+ when 'all'; @project.milestones.order("closed, due_date DESC")
+ when 'closed'; @project.milestones.closed.order("due_date DESC")
+ else @project.milestones.active.order("due_date ASC")
end
- @milestones = @milestones.includes(:project).order("due_date")
+ @milestones = @milestones.includes(:project)
@milestones = @milestones.page(params[:page]).per(20)
end
@@ -42,6 +43,7 @@ class MilestonesController < ProjectResourceController
def create
@milestone = @project.milestones.new(params[:milestone])
+ @milestone.author_id_of_changes = current_user.id
if @milestone.save
redirect_to project_milestone_path(@project, @milestone)
@@ -51,7 +53,7 @@ class MilestonesController < ProjectResourceController
end
def update
- @milestone.update_attributes(params[:milestone])
+ @milestone.update_attributes(params[:milestone].merge(author_id_of_changes: current_user.id))
respond_to do |format|
format.js
diff --git a/app/controllers/omniauth_callbacks_controller.rb b/app/controllers/omniauth_callbacks_controller.rb
index 2fb783b289b..c4ebf0e4889 100644
--- a/app/controllers/omniauth_callbacks_controller.rb
+++ b/app/controllers/omniauth_callbacks_controller.rb
@@ -1,5 +1,5 @@
class OmniauthCallbacksController < Devise::OmniauthCallbacksController
- Gitlab.config.omniauth_providers.each do |provider|
+ Gitlab.config.omniauth.providers.each do |provider|
define_method provider['name'] do
handle_omniauth
end
diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb
index d6c6a1bdbd7..271647c783c 100644
--- a/app/controllers/projects_controller.rb
+++ b/app/controllers/projects_controller.rb
@@ -46,6 +46,10 @@ class ProjectsController < ProjectResourceController
format.js
end
end
+
+ rescue Project::TransferError => ex
+ @error = ex
+ render :update_failed
end
def show
diff --git a/app/controllers/snippets_controller.rb b/app/controllers/snippets_controller.rb
index 7324a4594eb..d037ad11ef1 100644
--- a/app/controllers/snippets_controller.rb
+++ b/app/controllers/snippets_controller.rb
@@ -16,7 +16,7 @@ class SnippetsController < ProjectResourceController
respond_to :html
def index
- @snippets = @project.snippets
+ @snippets = @project.snippets.fresh
end
def new
@@ -60,7 +60,7 @@ class SnippetsController < ProjectResourceController
redirect_to project_snippets_path(@project)
end
- def raw
+ def raw
send_data(
@snippet.content,
type: "text/plain",
diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
index 81be62421c3..52715a265bd 100644
--- a/app/helpers/application_helper.rb
+++ b/app/helpers/application_helper.rb
@@ -34,10 +34,10 @@ module ApplicationHelper
def gravatar_icon(user_email = '', size = nil)
size = 40 if size.nil? || size <= 0
- if Gitlab.config.disable_gravatar? || user_email.blank?
+ if !Gitlab.config.gravatar.enabled || user_email.blank?
'no_avatar.png'
else
- gravatar_url = request.ssl? ? Gitlab.config.gravatar_ssl_url : Gitlab.config.gravatar_url
+ gravatar_url = request.ssl? ? Gitlab.config.gravatar.ssl_url : Gitlab.config.gravatar.plain_url
user_email.strip!
sprintf(gravatar_url, {:hash => Digest::MD5.hexdigest(user_email.downcase), :email => URI.escape(user_email), :size => size})
end
@@ -48,7 +48,7 @@ module ApplicationHelper
end
def web_app_url
- "#{request_protocol}://#{Gitlab.config.web_host}/"
+ "#{request_protocol}://#{Gitlab.config.gitlab.host}/"
end
def last_commit(project)
@@ -95,6 +95,7 @@ module ApplicationHelper
{ label: "API Help", url: help_api_path },
{ label: "Markdown Help", url: help_markdown_path },
{ label: "SSH Keys Help", url: help_ssh_path },
+ { label: "Gitlab Rake Tasks Help", url: help_raketasks_path },
]
project_nav = []
diff --git a/app/helpers/issues_helper.rb b/app/helpers/issues_helper.rb
index 99ea9ef2975..2825787fd2f 100644
--- a/app/helpers/issues_helper.rb
+++ b/app/helpers/issues_helper.rb
@@ -4,28 +4,6 @@ module IssuesHelper
project_issues_path project, params
end
- def link_to_issue_assignee(issue)
- project = issue.project
-
- tm = project.team_member_by_id(issue.assignee_id)
- if tm
- link_to issue.assignee_name, project_team_member_path(project, tm), class: "author_link"
- else
- issue.assignee_name
- end
- end
-
- def link_to_issue_author(issue)
- project = issue.project
-
- tm = project.team_member_by_id(issue.author_id)
- if tm
- link_to issue.author_name, project_team_member_path(project, tm), class: "author_link"
- else
- issue.author_name
- end
- end
-
def issue_css_classes issue
classes = "issue"
classes << " closed" if issue.closed
@@ -52,4 +30,14 @@ module IssuesHelper
open: "open"
}
end
+
+ def labels_autocomplete_source
+ labels = @project.issues_labels.order('count DESC')
+ labels = labels.map{ |l| { label: l.name, value: l.name } }
+ labels.to_json
+ end
+
+ def issues_active_milestones
+ @project.milestones.active.order("id desc").all
+ end
end
diff --git a/app/helpers/merge_requests_helper.rb b/app/helpers/merge_requests_helper.rb
index b23c4a8f0df..f48425bd6de 100644
--- a/app/helpers/merge_requests_helper.rb
+++ b/app/helpers/merge_requests_helper.rb
@@ -1,26 +1,4 @@
module MergeRequestsHelper
- def link_to_merge_request_assignee(merge_request)
- project = merge_request.project
-
- tm = project.team_member_by_id(merge_request.assignee_id)
- if tm
- link_to merge_request.assignee_name, project_team_member_path(project, tm), class: "author_link"
- else
- merge_request.assignee_name
- end
- end
-
- def link_to_merge_request_author(merge_request)
- project = merge_request.project
-
- tm = project.team_member_by_id(merge_request.author_id)
- if tm
- link_to merge_request.author_name, project_team_member_path(project, tm), class: "author_link"
- else
- merge_request.author_name
- end
- end
-
def new_mr_path_from_push_event(event)
new_project_merge_request_path(
event.project,
@@ -39,7 +17,7 @@ module MergeRequestsHelper
classes
end
- def ci_status_path
- @project.gitlab_ci_service.commit_badge_path(@merge_request.last_commit.sha)
+ def ci_build_details_path merge_request
+ merge_request.project.gitlab_ci_service.build_page(merge_request.last_commit.sha)
end
end
diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb
index 7c302ef4176..425dd471b36 100644
--- a/app/helpers/projects_helper.rb
+++ b/app/helpers/projects_helper.rb
@@ -8,11 +8,49 @@ module ProjectsHelper
end
def link_to_project project
- link_to project.name, project
+ link_to project do
+ title = content_tag(:strong, project.name)
+
+ if project.namespace
+ namespace = content_tag(:span, "#{project.namespace.human_name} / ", class: 'tiny')
+ title = namespace + title
+ end
+
+ title
+ end
+ end
+
+ def link_to_member(project, author)
+ return "(deleted)" unless author
+
+ # Build avatar image tag
+ avatar = image_tag(gravatar_icon(author.try(:email)), width: 16, class: "lil_av")
+
+ # Build name strong tag
+ name = content_tag :strong, author.name, class: 'author'
+
+ author_html = avatar + name
+
+ tm = project.team_member_by_id(author)
+
+ content_tag :span, class: 'member-link' do
+ if tm
+ link_to author_html, project_team_member_path(project, tm), class: "author_link"
+ else
+ author_html
+ end
+ end
end
def tm_path team_member
project_team_member_path(@project, team_member)
end
-end
+ def project_title project
+ if project.group
+ project.name_with_namespace
+ else
+ project.name
+ end
+ end
+end
diff --git a/app/mailers/notify.rb b/app/mailers/notify.rb
index 29cebadaf94..5cd9b82900c 100644
--- a/app/mailers/notify.rb
+++ b/app/mailers/notify.rb
@@ -3,11 +3,11 @@ class Notify < ActionMailer::Base
add_template_helper ApplicationHelper
add_template_helper GitlabMarkdownHelper
- default_url_options[:host] = Gitlab.config.web_host
- default_url_options[:protocol] = Gitlab.config.web_protocol
- default_url_options[:port] = Gitlab.config.web_port if Gitlab.config.web_custom_port?
+ default_url_options[:host] = Gitlab.config.gitlab.host
+ default_url_options[:protocol] = Gitlab.config.gitlab.protocol
+ default_url_options[:port] = Gitlab.config.gitlab.port if Gitlab.config.gitlab_on_non_standard_port?
- default from: Gitlab.config.email_from
+ default from: Gitlab.config.gitlab.email_from
@@ -31,6 +31,7 @@ class Notify < ActionMailer::Base
def issue_status_changed_email(recipient_id, issue_id, status, updated_by_user_id)
@issue = Issue.find issue_id
@issue_status = status
+ @project = @issue.project
@updated_by = User.find updated_by_user_id
mail(to: recipient(recipient_id),
subject: subject("changed issue ##{@issue.id}", @issue.title))
@@ -102,6 +103,12 @@ class Notify < ActionMailer::Base
end
+ def project_was_moved_email(user_project_id)
+ @users_project = UsersProject.find user_project_id
+ @project = @users_project.project
+ mail(to: @users_project.user.email,
+ subject: subject("project was moved"))
+ end
#
# User
diff --git a/app/models/commit.rb b/app/models/commit.rb
index 200c915a335..ee16bf084de 100644
--- a/app/models/commit.rb
+++ b/app/models/commit.rb
@@ -87,14 +87,10 @@ class Commit
last = project.commit(from.try(:strip))
if first && last
- commits = [first, last].sort_by(&:created_at)
- younger = commits.first
- older = commits.last
-
- result[:same] = (younger.id == older.id)
- result[:commits] = project.repo.commits_between(younger.id, older.id).map {|c| Commit.new(c)}
- result[:diffs] = project.repo.diff(younger.id, older.id) rescue []
- result[:commit] = Commit.new(older)
+ result[:same] = (first.id == last.id)
+ result[:commits] = project.repo.commits_between(last.id, first.id).map {|c| Commit.new(c)}
+ result[:diffs] = project.repo.diff(last.id, first.id) rescue []
+ result[:commit] = Commit.new(first)
end
result
diff --git a/app/models/event.rb b/app/models/event.rb
index 2b92783ceac..90376e73753 100644
--- a/app/models/event.rb
+++ b/app/models/event.rb
@@ -15,6 +15,7 @@
#
class Event < ActiveRecord::Base
+ include NoteEvent
include PushEvent
attr_accessible :project, :action, :data, :author_id, :project_id,
@@ -58,12 +59,14 @@ class Event < ActiveRecord::Base
end
end
- # Next events currently enabled for system
- # - push
- # - new issue
- # - merge request
- def allowed?
- push? || issue? || merge_request? || membership_changed?
+ def proper?
+ if push?
+ true
+ elsif membership_changed?
+ true
+ else
+ (issue? || merge_request? || note? || milestone?) && target
+ end
end
def project_name
@@ -94,6 +97,14 @@ class Event < ActiveRecord::Base
action == self.class::Reopened
end
+ def milestone?
+ target_type == "Milestone"
+ end
+
+ def note?
+ target_type == "Note"
+ end
+
def issue?
target_type == "Issue"
end
diff --git a/app/models/gitlab_ci_service.rb b/app/models/gitlab_ci_service.rb
index 24b70323098..a2f5634a86f 100644
--- a/app/models/gitlab_ci_service.rb
+++ b/app/models/gitlab_ci_service.rb
@@ -36,4 +36,22 @@ class GitlabCiService < Service
def commit_badge_path sha
project_url + "/status?sha=#{sha}"
end
+
+ def commit_status_path sha
+ project_url + "/builds/#{sha}/status.json?token=#{token}"
+ end
+
+ def commit_status sha
+ response = HTTParty.get(commit_status_path(sha))
+
+ if response.code == 200 and response["status"]
+ response["status"]
+ else
+ :error
+ end
+ end
+
+ def build_page sha
+ project_url + "/builds/#{sha}"
+ end
end
diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb
index 8039813ad1c..052e0850d96 100644
--- a/app/models/merge_request.rb
+++ b/app/models/merge_request.rb
@@ -204,7 +204,7 @@ class MergeRequest < ActiveRecord::Base
def mr_and_commit_notes
commit_ids = commits.map(&:id)
- Note.where("(noteable_type = 'MergeRequest' AND noteable_id = :mr_id) OR (noteable_type = 'Commit' AND noteable_id IN (:commit_ids))", mr_id: id, commit_ids: commit_ids)
+ Note.where("(noteable_type = 'MergeRequest' AND noteable_id = :mr_id) OR (noteable_type = 'Commit' AND commit_id IN (:commit_ids))", mr_id: id, commit_ids: commit_ids)
end
# Returns the raw diff for this merge request
@@ -220,4 +220,8 @@ class MergeRequest < ActiveRecord::Base
def to_patch
project.repo.git.format_patch({timeout: 30, raise: true, stdout: true}, "#{target_branch}..#{source_branch}")
end
+
+ def last_commit_short_sha
+ @last_commit_short_sha ||= last_commit.sha[0..10]
+ end
end
diff --git a/app/models/milestone.rb b/app/models/milestone.rb
index a50831a2241..4fac9bec259 100644
--- a/app/models/milestone.rb
+++ b/app/models/milestone.rb
@@ -13,18 +13,26 @@
#
class Milestone < ActiveRecord::Base
- attr_accessible :title, :description, :due_date, :closed
+ attr_accessible :title, :description, :due_date, :closed, :author_id_of_changes
+ attr_accessor :author_id_of_changes
belongs_to :project
has_many :issues
has_many :merge_requests
+ scope :active, where(closed: false)
+ scope :closed, where(closed: true)
+
validates :title, presence: true
validates :project, presence: true
validates :closed, inclusion: { in: [true, false] }
- def self.active
- where("due_date > ? OR due_date IS NULL", Date.today)
+ def expired?
+ if due_date
+ due_date < Date.today
+ else
+ false
+ end
end
def participants
@@ -52,4 +60,20 @@ class Milestone < ActiveRecord::Base
def expires_at
"expires at #{due_date.stamp("Aug 21, 2011")}" if due_date
end
+
+ def can_be_closed?
+ open? && issues.opened.count.zero?
+ end
+
+ def is_empty?
+ total_items_count.zero?
+ end
+
+ def open?
+ !closed
+ end
+
+ def author_id
+ author_id_of_changes
+ end
end
diff --git a/app/models/namespace.rb b/app/models/namespace.rb
index e1c24de949a..8c90f5aee26 100644
--- a/app/models/namespace.rb
+++ b/app/models/namespace.rb
@@ -48,23 +48,30 @@ class Namespace < ActiveRecord::Base
end
def ensure_dir_exist
- namespace_dir_path = File.join(Gitlab.config.git_base_path, path)
+ namespace_dir_path = File.join(Gitlab.config.gitolite.repos_path, path)
system("mkdir -m 770 #{namespace_dir_path}") unless File.exists?(namespace_dir_path)
end
def move_dir
if path_changed?
- old_path = File.join(Gitlab.config.git_base_path, path_was)
- new_path = File.join(Gitlab.config.git_base_path, path)
+ old_path = File.join(Gitlab.config.gitolite.repos_path, path_was)
+ new_path = File.join(Gitlab.config.gitolite.repos_path, path)
if File.exists?(new_path)
raise "Already exists"
end
- system("mv #{old_path} #{new_path}")
+
+ if system("mv #{old_path} #{new_path}")
+ send_update_instructions
+ end
end
end
def rm_dir
- dir_path = File.join(Gitlab.config.git_base_path, path)
+ dir_path = File.join(Gitlab.config.gitolite.repos_path, path)
system("rm -rf #{dir_path}")
end
+
+ def send_update_instructions
+ projects.each(&:send_move_instructions)
+ end
end
diff --git a/app/models/note.rb b/app/models/note.rb
index da15a173566..28b3879239f 100644
--- a/app/models/note.rb
+++ b/app/models/note.rb
@@ -20,7 +20,7 @@ require 'file_size_validator'
class Note < ActiveRecord::Base
attr_accessible :note, :noteable, :noteable_id, :noteable_type, :project_id,
- :attachment, :line_code
+ :attachment, :line_code, :commit_id
attr_accessor :notify
attr_accessor :notify_author
@@ -35,10 +35,14 @@ class Note < ActiveRecord::Base
validates :note, :project, presence: true
validates :attachment, file_size: { maximum: 10.megabytes.to_i }
+ validates :noteable_id, presence: true, if: ->(n) { n.noteable_type.present? && n.noteable_type != 'Commit' }
+ validates :commit_id, presence: true, if: ->(n) { n.noteable_type == 'Commit' }
+
mount_uploader :attachment, AttachmentUploader
# Scopes
- scope :common, ->{ where(noteable_id: nil) }
+ scope :for_commits, ->{ where(noteable_type: "Commit") }
+ scope :common, ->{ where(noteable_id: nil, commit_id: nil) }
scope :today, ->{ where("created_at >= :date", date: Date.today) }
scope :last_week, ->{ where("created_at >= :date", date: (Date.today - 7.days)) }
scope :since, ->(day) { where("created_at >= :date", date: (day)) }
@@ -66,7 +70,7 @@ class Note < ActiveRecord::Base
# override to return commits, which are not active record
def noteable
if for_commit?
- project.commit(noteable_id)
+ project.commit(commit_id)
else
super
end
@@ -121,4 +125,12 @@ class Note < ActiveRecord::Base
def downvote?
note.start_with?('-1') || note.start_with?(':-1:')
end
+
+ def noteable_type_name
+ if noteable_type.present?
+ noteable_type.downcase
+ else
+ "wall"
+ end
+ end
end
diff --git a/app/models/project.rb b/app/models/project.rb
index 372b94d2066..3e5c912e0b4 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -25,6 +25,9 @@ class Project < ActiveRecord::Base
include PushObserver
include Authority
include Team
+ include NamespacedProject
+
+ class TransferError < StandardError; end
attr_accessible :name, :path, :description, :default_branch, :issues_enabled,
:wall_enabled, :merge_requests_enabled, :wiki_enabled, as: [:default, :admin]
@@ -101,7 +104,7 @@ class Project < ActiveRecord::Base
namespace_id = Namespace.find_by_path(id.first).id
where(namespace_id: namespace_id).find_by_path(id.last)
else
- find_by_path(id)
+ where(path: id, namespace_id: nil).last
end
end
@@ -176,7 +179,7 @@ class Project < ActiveRecord::Base
end
def repo_name
- denied_paths = %w(gitolite-admin groups projects dashboard)
+ denied_paths = %w(gitolite-admin admin dashboard groups help profile projects search)
if denied_paths.include?(path)
errors.add(:path, "like #{path} is not allowed")
@@ -192,7 +195,7 @@ class Project < ActiveRecord::Base
end
def web_url
- [Gitlab.config.url, path].join("/")
+ [Gitlab.config.gitlab.url, path_with_namespace].join("/")
end
def common_notes
@@ -200,15 +203,15 @@ class Project < ActiveRecord::Base
end
def build_commit_note(commit)
- notes.new(noteable_id: commit.id, noteable_type: "Commit")
+ notes.new(commit_id: commit.id, noteable_type: "Commit")
end
def commit_notes(commit)
- notes.where(noteable_id: commit.id, noteable_type: "Commit", line_code: nil)
+ notes.where(commit_id: commit.id, noteable_type: "Commit", line_code: nil)
end
def commit_line_notes(commit)
- notes.where(noteable_id: commit.id, noteable_type: "Commit").where("line_code IS NOT NULL")
+ notes.where(commit_id: commit.id, noteable_type: "Commit").where("line_code IS NOT NULL")
end
def public?
@@ -243,51 +246,11 @@ class Project < ActiveRecord::Base
gitlab_ci_service && gitlab_ci_service.active
end
- def path_with_namespace
- if namespace
- namespace.path + '/' + path
- else
- path
- end
- end
-
# For compatibility with old code
def code
path
end
- def transfer(new_namespace)
- Project.transaction do
- old_namespace = namespace
- self.namespace = new_namespace
-
- old_dir = old_namespace.try(:path) || ''
- new_dir = new_namespace.try(:path) || ''
-
- old_repo = if old_dir.present?
- File.join(old_dir, self.path)
- else
- self.path
- end
-
- Gitlab::ProjectMover.new(self, old_dir, new_dir).execute
-
- git_host.move_repository(old_repo, self)
-
- save!
- end
- end
-
- def name_with_namespace
- @name_with_namespace ||= begin
- if namespace
- namespace.human_name + " / " + name
- else
- name
- end
- end
- end
-
def items_for entity
case entity
when 'issue' then
@@ -297,15 +260,9 @@ class Project < ActiveRecord::Base
end
end
- def namespace_owner
- namespace.try(:owner)
- end
-
- def chief
- if namespace
- namespace_owner
- else
- owner
+ def send_move_instructions
+ self.users_projects.each do |member|
+ Notify.project_was_moved_email(member.id).deliver
end
end
end
diff --git a/app/models/snippet.rb b/app/models/snippet.rb
index 997c19bdb6b..8d7eb788abb 100644
--- a/app/models/snippet.rb
+++ b/app/models/snippet.rb
@@ -22,7 +22,7 @@ class Snippet < ActiveRecord::Base
belongs_to :author, class_name: "User"
has_many :notes, as: :noteable, dependent: :destroy
- delegate :name, :email, to: :author, prefix: true
+ delegate :name, :email, to: :author, prefix: true, allow_nil: true
validates :author, presence: true
validates :project, presence: true
diff --git a/app/models/user.rb b/app/models/user.rb
index 3f2d7c92ea8..1bc070f040d 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -56,12 +56,12 @@ class User < ActiveRecord::Base
has_many :issues, foreign_key: :author_id, dependent: :destroy
has_many :notes, foreign_key: :author_id, dependent: :destroy
has_many :merge_requests, foreign_key: :author_id, dependent: :destroy
- has_many :my_own_projects, class_name: "Project", foreign_key: :owner_id
has_many :events, class_name: "Event", foreign_key: :author_id, dependent: :destroy
has_many :recent_events, class_name: "Event", foreign_key: :author_id, order: "id DESC"
has_many :assigned_issues, class_name: "Issue", foreign_key: :assignee_id, dependent: :destroy
has_many :assigned_merge_requests, class_name: "MergeRequest", foreign_key: :assignee_id, dependent: :destroy
+ validates :name, presence: true
validates :bio, length: { within: 0..255 }
validates :extern_uid, allow_blank: true, uniqueness: {scope: :provider}
validates :projects_limit, presence: true, numericality: {greater_than_or_equal_to: 0}
@@ -123,16 +123,4 @@ class User < ActiveRecord::Base
self.password = self.password_confirmation = Devise.friendly_token.first(8)
end
end
-
- def authorized_groups
- @authorized_groups ||= begin
- groups = Group.where(id: self.projects.pluck(:namespace_id)).all
- groups = groups + self.groups
- groups.uniq
- end
- end
-
- def authorized_projects
- Project.authorized_for(self)
- end
end
diff --git a/app/observers/activity_observer.rb b/app/observers/activity_observer.rb
index 48351bac667..c188e5720ac 100644
--- a/app/observers/activity_observer.rb
+++ b/app/observers/activity_observer.rb
@@ -1,18 +1,27 @@
class ActivityObserver < ActiveRecord::Observer
- observe :issue, :merge_request
+ observe :issue, :merge_request, :note, :milestone
def after_create(record)
- Event.create(
- project: record.project,
- target_id: record.id,
- target_type: record.class.name,
- action: Event.determine_action(record),
- author_id: record.author_id
- )
+ event_author_id = record.author_id
+
+ # Skip status notes
+ if record.kind_of?(Note) && record.note.include?("_Status changed to ")
+ return true
+ end
+
+ if event_author_id
+ Event.create(
+ project: record.project,
+ target_id: record.id,
+ target_type: record.class.name,
+ action: Event.determine_action(record),
+ author_id: event_author_id
+ )
+ end
end
def after_save(record)
- if record.changed.include?("closed")
+ if record.changed.include?("closed") && record.author_id_of_changes
Event.create(
project: record.project,
target_id: record.id,
diff --git a/app/observers/issue_observer.rb b/app/observers/issue_observer.rb
index 9f9762aea07..131336be8b6 100644
--- a/app/observers/issue_observer.rb
+++ b/app/observers/issue_observer.rb
@@ -16,7 +16,7 @@ class IssueObserver < ActiveRecord::Observer
if status
Note.create_status_change_note(issue, current_user, status)
[issue.author, issue.assignee].compact.each do |recipient|
- Notify.issue_status_changed_email(recipient.id, issue.id, status, current_user)
+ Notify.issue_status_changed_email(recipient.id, issue.id, status, current_user.id).deliver
end
end
end
diff --git a/app/observers/note_observer.rb b/app/observers/note_observer.rb
index 083aa7058d5..fe01efcaac2 100644
--- a/app/observers/note_observer.rb
+++ b/app/observers/note_observer.rb
@@ -21,7 +21,7 @@ class NoteObserver < ActiveRecord::Observer
# Notifies the whole team except the author of note
def notify_team(note)
# Note: wall posts are not "attached" to anything, so fall back to "Wall"
- noteable_type = note.noteable_type || "Wall"
+ noteable_type = note.noteable_type.presence || "Wall"
notify_method = "note_#{noteable_type.underscore}_email".to_sym
if Notify.respond_to? notify_method
diff --git a/app/observers/project_observer.rb b/app/observers/project_observer.rb
index bd41e51e8e4..b1c694569d7 100644
--- a/app/observers/project_observer.rb
+++ b/app/observers/project_observer.rb
@@ -3,7 +3,8 @@ class ProjectObserver < ActiveRecord::Observer
project.update_repository
end
- def after_save(project)
+ def after_update(project)
+ project.send_move_instructions if project.namespace_id_changed?
end
def after_destroy(project)
diff --git a/app/roles/account.rb b/app/roles/account.rb
index 8157898fef1..72fa9ebf9d9 100644
--- a/app/roles/account.rb
+++ b/app/roles/account.rb
@@ -105,4 +105,20 @@ module Account
def namespace_id
namespace.try :id
end
+
+ def authorized_groups
+ @authorized_groups ||= begin
+ groups = Group.where(id: self.projects.pluck(:namespace_id)).all
+ groups = groups + self.groups
+ groups.uniq
+ end
+ end
+
+ def authorized_projects
+ Project.authorized_for(self)
+ end
+
+ def my_own_projects
+ Project.personal(self)
+ end
end
diff --git a/app/roles/namespaced_project.rb b/app/roles/namespaced_project.rb
new file mode 100644
index 00000000000..8656890a456
--- /dev/null
+++ b/app/roles/namespaced_project.rb
@@ -0,0 +1,59 @@
+module NamespacedProject
+ def transfer(new_namespace)
+ Project.transaction do
+ old_namespace = namespace
+ self.namespace = new_namespace
+
+ old_dir = old_namespace.try(:path) || ''
+ new_dir = new_namespace.try(:path) || ''
+
+ old_repo = if old_dir.present?
+ File.join(old_dir, self.path)
+ else
+ self.path
+ end
+
+ if Project.where(path: self.path, namespace_id: new_namespace.try(:id)).present?
+ raise TransferError.new("Project with same path in target namespace already exists")
+ end
+
+ Gitlab::ProjectMover.new(self, old_dir, new_dir).execute
+
+ git_host.move_repository(old_repo, self)
+
+ save!
+ end
+ rescue Gitlab::ProjectMover::ProjectMoveError => ex
+ raise TransferError.new(ex.message)
+ end
+
+ def name_with_namespace
+ @name_with_namespace ||= begin
+ if namespace
+ namespace.human_name + " / " + name
+ else
+ name
+ end
+ end
+ end
+
+ def namespace_owner
+ namespace.try(:owner)
+ end
+
+ def chief
+ if namespace
+ namespace_owner
+ else
+ owner
+ end
+ end
+
+ def path_with_namespace
+ if namespace
+ namespace.path + '/' + path
+ else
+ path
+ end
+ end
+end
diff --git a/app/roles/note_event.rb b/app/roles/note_event.rb
new file mode 100644
index 00000000000..db4ced0c095
--- /dev/null
+++ b/app/roles/note_event.rb
@@ -0,0 +1,37 @@
+module NoteEvent
+ def note_commit_id
+ target.commit_id
+ end
+
+ def note_short_commit_id
+ note_commit_id[0..8]
+ end
+
+ def note_commit?
+ target.noteable_type == "Commit"
+ end
+
+ def note_target
+ target.noteable
+ end
+
+ def note_target_id
+ if note_commit?
+ target.commit_id
+ else
+ target.noteable_id.to_s
+ end
+ end
+
+ def wall_note?
+ target.noteable_type.blank?
+ end
+
+ def note_target_type
+ if target.noteable_type.present?
+ target.noteable_type.titleize
+ else
+ "Wall"
+ end.downcase
+ end
+end
diff --git a/app/roles/push_observer.rb b/app/roles/push_observer.rb
index c5c5203d7a6..dda18267207 100644
--- a/app/roles/push_observer.rb
+++ b/app/roles/push_observer.rb
@@ -114,7 +114,7 @@ module PushObserver
id: commit.id,
message: commit.safe_message,
timestamp: commit.date.xmlschema,
- url: "#{Gitlab.config.url}/#{path}/commits/#{commit.id}",
+ url: "#{Gitlab.config.gitlab.url}/#{path_with_namespace}/commit/#{commit.id}",
author: {
name: commit.author_name,
email: commit.author_email
diff --git a/app/roles/repository.rb b/app/roles/repository.rb
index 74cae5c8d5d..78190ca96d0 100644
--- a/app/roles/repository.rb
+++ b/app/roles/repository.rb
@@ -45,8 +45,22 @@ module Repository
end
def has_post_receive_file?
- hook_file = File.join(path_to_repo, 'hooks', 'post-receive')
- File.exists?(hook_file)
+ !!hook_file
+ end
+
+ def valid_post_receive_file?
+ valid_hook_file == hook_file
+ end
+
+ def valid_hook_file
+ @valid_hook_file ||= File.read(Rails.root.join('lib', 'hooks', 'post-receive'))
+ end
+
+ def hook_file
+ @hook_file ||= begin
+ hook_path = File.join(path_to_repo, 'hooks', 'post-receive')
+ File.read(hook_path) if File.exists?(hook_path)
+ end
end
# Returns an Array of branch names
@@ -83,7 +97,7 @@ module Repository
end
def path_to_repo
- File.join(Gitlab.config.git_base_path, "#{path_with_namespace}.git")
+ File.join(Gitlab.config.gitolite.repos_path, "#{path_with_namespace}.git")
end
def namespace_dir
@@ -185,7 +199,7 @@ module Repository
end
def http_url_to_repo
- http_url = [Gitlab.config.url, "/", path_with_namespace, ".git"].join('')
+ http_url = [Gitlab.config.gitlab.url, "/", path_with_namespace, ".git"].join('')
end
# Check if current branch name is marked as protected in the system
diff --git a/app/views/admin/groups/edit.html.haml b/app/views/admin/groups/edit.html.haml
index 4026817496a..901d07e74f3 100644
--- a/app/views/admin/groups/edit.html.haml
+++ b/app/views/admin/groups/edit.html.haml
@@ -1,9 +1,5 @@
%h3.page_title Rename Group
%hr
-.alert
- Renaming group can have unintended side effects.
- %br
- Renaming group will rename directory for all related projects
= form_for [:admin, @group] do |f|
- if @group.errors.any?
.alert-message.block-message.error
@@ -14,6 +10,19 @@
.input
= f.text_field :name, placeholder: "Example Group", class: "xxlarge"
+
+
+ .clearfix.group_name_holder
+ = f.label :path do
+ %span.cred Group path is
+ .input
+ = f.text_field :path, placeholder: "example-group", class: "xxlarge danger"
+ %ul.cred
+ %li Changing group path can have unintended side effects.
+ %li Renaming group path will rename directory for all related projects
+ %li It will change web url for access group and group projects.
+ %li It will change the git path to repositories under this group.
+
.form-actions
- = f.submit 'Rename group', class: "btn save-btn"
+ = f.submit 'Rename group', class: "btn danger"
= link_to 'Cancel', admin_groups_path, class: "btn cancel-btn"
diff --git a/app/views/admin/groups/index.html.haml b/app/views/admin/groups/index.html.haml
index 455730a06c4..49acedc8c79 100644
--- a/app/views/admin/groups/index.html.haml
+++ b/app/views/admin/groups/index.html.haml
@@ -12,16 +12,23 @@
%table
%thead
- %th Name
- %th Path
- %th Projects
- %th.cred Danger Zone!
+ %tr
+ %th
+ Name
+ %i.icon-sort-down
+ %th Path
+ %th Projects
+ %th Owner
+ %th.cred Danger Zone!
- @groups.each do |group|
%tr
- %td= link_to group.name, [:admin, group]
+ %td
+ %strong= link_to group.name, [:admin, group]
%td= group.path
%td= group.projects.count
+ %td
+ = link_to group.owner_name, admin_user_path(group.owner_id)
%td.bgred
= link_to 'Rename', edit_admin_group_path(group), id: "edit_#{dom_id(group)}", class: "btn small"
= link_to 'Destroy', [:admin, group], confirm: "REMOVE #{group.name}? Are you sure?", method: :delete, class: "btn small danger"
diff --git a/app/views/admin/groups/show.html.haml b/app/views/admin/groups/show.html.haml
index 4b6fedfd360..41f6d9b3516 100644
--- a/app/views/admin/groups/show.html.haml
+++ b/app/views/admin/groups/show.html.haml
@@ -22,7 +22,7 @@
%b
Path:
%td
- %span.monospace= File.join(Gitlab.config.git_base_path, @group.path)
+ %span.monospace= File.join(Gitlab.config.gitolite.repos_path, @group.path)
%tr
%td
%b
@@ -33,12 +33,17 @@
= link_to "#", class: "btn btn-small change-owner-link" do
%i.icon-edit
Change owner
- .change-owner-holder.hide
- = form_for [:admin, @group] do |f|
- = f.select :owner_id, User.all.map { |user| [user.name, user.id] }, {}, {class: 'chosen'}
- = f.submit 'Save', class: "btn btn-small save-btn"
- = link_to "Cancel", "#", class: "btn btn-small change-owner-cancel-link"
+ %tr.change-owner-holder.hide
+ %td.bgred
+ %b.cred
+ New Owner:
+ %td.bgred
+ = form_for [:admin, @group] do |f|
+ = f.select :owner_id, User.all.map { |user| [user.name, user.id] }, {}, {class: 'chosen'}
+ %div
+ = f.submit 'Change Owner', class: "btn danger"
+ = link_to "Cancel", "#", class: "btn change-owner-cancel-link"
%fieldset
%legend Projects (#{@group.projects.count})
%table
diff --git a/app/views/admin/logs/show.html.haml b/app/views/admin/logs/show.html.haml
index e33c5468555..25644d6321a 100644
--- a/app/views/admin/logs/show.html.haml
+++ b/app/views/admin/logs/show.html.haml
@@ -3,6 +3,8 @@
= link_to "githost.log", "#githost", 'data-toggle' => 'tab'
%li
= link_to "application.log", "#application", 'data-toggle' => 'tab'
+ %li
+ = link_to "production.log", "#production", 'data-toggle' => 'tab'
%p.light To prevent perfomance issues admin logs output the last 2000 lines
.tab-content
@@ -34,3 +36,17 @@
- Gitlab::AppLogger.read_latest.each do |line|
%li
%p= line
+ .tab-pane#production
+ .file_holder#README
+ .file_title
+ %i.icon-file
+ production.log
+ .right
+ = link_to '#', class: 'log-bottom' do
+ %i.icon-arrow-down
+ Scroll down
+ .file_content.logs
+ %ol
+ - Gitlab::Logger.read_latest_for('production.log').each do |line|
+ %li
+ %p= line
diff --git a/app/views/admin/projects/_form.html.haml b/app/views/admin/projects/_form.html.haml
index d90d4a03d67..27c22872d50 100644
--- a/app/views/admin/projects/_form.html.haml
+++ b/app/views/admin/projects/_form.html.haml
@@ -19,43 +19,47 @@
.input
= text_field_tag :ppath, @project.path_to_repo, class: "xlarge", disabled: true
- - unless project.new_record?
+ - if project.repo_exists?
.clearfix
- = f.label :namespace_id
- .input
- = f.select :namespace_id, namespaces_options(@project.namespace_id, :all), {}, {class: 'chosen'}
- &nbsp;
- %span.cred Be careful. Changing project namespace can have unintended side effects
+ = f.label :default_branch, "Default Branch"
+ .input= f.select(:default_branch, project.heads.map(&:name), {}, style: "width:210px;")
- - if project.repo_exists?
- .clearfix
- = f.label :default_branch, "Default Branch"
- .input= f.select(:default_branch, project.heads.map(&:name), {}, style: "width:210px;")
+ %fieldset.adv_settings
+ %legend Features:
- - unless project.new_record?
- %fieldset.adv_settings
- %legend Features:
+ .clearfix
+ = f.label :issues_enabled, "Issues"
+ .input= f.check_box :issues_enabled
- .clearfix
- = f.label :issues_enabled, "Issues"
- .input= f.check_box :issues_enabled
+ .clearfix
+ = f.label :merge_requests_enabled, "Merge Requests"
+ .input= f.check_box :merge_requests_enabled
- .clearfix
- = f.label :merge_requests_enabled, "Merge Requests"
- .input= f.check_box :merge_requests_enabled
+ .clearfix
+ = f.label :wall_enabled, "Wall"
+ .input= f.check_box :wall_enabled
- .clearfix
- = f.label :wall_enabled, "Wall"
- .input= f.check_box :wall_enabled
+ .clearfix
+ = f.label :wiki_enabled, "Wiki"
+ .input= f.check_box :wiki_enabled
+
+ %fieldset.features
+ %legend Transfer:
+ .control-group
+ = f.label :namespace_id do
+ %span Namespace
+ .controls
+ = f.select :namespace_id, namespaces_options(@project.namespace_id, :all), {}, {class: 'chosen'}
+ %br
+ %ul.prepend-top-10.cred
+ %li Be careful. Changing project namespace can have unintended side effects
+ %li You can transfer project only to namespaces you can manage
+ %li You will need to update your local repositories to point to the new location.
- .clearfix
- = f.label :wiki_enabled, "Wiki"
- .input= f.check_box :wiki_enabled
- - unless project.new_record?
- .actions
- = f.submit 'Save Project', class: "btn save-btn"
- = link_to 'Cancel', admin_projects_path, class: "btn cancel-btn"
+ .actions
+ = f.submit 'Save Project', class: "btn save-btn"
+ = link_to 'Cancel', admin_projects_path, class: "btn cancel-btn"
diff --git a/app/views/admin/projects/index.html.haml b/app/views/admin/projects/index.html.haml
index 9bbcbc71111..310cfa53890 100644
--- a/app/views/admin/projects/index.html.haml
+++ b/app/views/admin/projects/index.html.haml
@@ -1,5 +1,5 @@
%h3.page_title
- Projects
+ Projects (#{@projects.count})
= link_to 'New Project', new_project_path, class: "btn small right"
%br
= form_tag admin_projects_path, method: :get, class: 'form-inline' do
@@ -9,12 +9,15 @@
%table
%thead
- %th Name
- %th Path
- %th Team Members
- %th Last Commit
- %th Edit
- %th.cred Danger Zone!
+ %tr
+ %th
+ Name
+ %i.icon-sort-down
+ %th Path
+ %th Team Members
+ %th Last Commit
+ %th Edit
+ %th.cred Danger Zone!
- @projects.each do |project|
%tr
diff --git a/app/views/admin/projects/show.html.haml b/app/views/admin/projects/show.html.haml
index 47185308f41..634b1836754 100644
--- a/app/views/admin/projects/show.html.haml
+++ b/app/views/admin/projects/show.html.haml
@@ -4,14 +4,24 @@
%i.icon-edit
Edit
-- if !@project.has_post_receive_file? && @project.has_commits?
- %br
- .alert.alert-error
- %span
- %strong Important!
- Project has commits but missing post-receive file.
- %br
- If you exported project manually - copy post-receive hook to bare repository
+- if @project.has_commits?
+ - if !@project.has_post_receive_file?
+ %br
+ .alert.alert-error
+ %span
+ %strong Project has commits but missing post-receive file.
+ %br
+ If you exported project manually - make a link of post-receive hook file from gitolite to project repository
+ - elsif !@project.valid_post_receive_file?
+ %br
+ .alert.alert-error
+ %span
+ %strong Project has invalid post-receive file.
+ %br
+ 1. Make sure your gitolite instace has latest post-receive file.
+ %br
+ 2. Make a link of post-receive hook file from gitolite to project repository
+
%br
%table.zebra-striped
@@ -37,9 +47,12 @@
%tr
%td
%b
- Path:
+ Owned by:
%td
- %code= @project.path_to_repo
+ - if @project.chief
+ = link_to @project.chief.name, admin_user_path(@project.chief)
+ - else
+ (deleted)
%tr
%td
%b
@@ -49,11 +62,48 @@
%tr
%td
%b
+ Created at:
+ %td
+ = @project.created_at.stamp("March 1, 1999")
+
+%table.zebra-striped
+ %thead
+ %tr
+ %th Repository
+ %th
+ %tr
+ %td
+ %b
+ FS Path:
+ %td
+ %code= @project.path_to_repo
+ %tr
+ %td
+ %b
+ Smart HTTP:
+ %td
+ = link_to @project.http_url_to_repo
+ %tr
+ %td
+ %b
+ SSH:
+ %td
+ = link_to @project.ssh_url_to_repo
+ %tr
+ %td
+ %b
+ Last commit at:
+ %td
+ = last_commit(@project)
+ %tr
+ %td
+ %b
Post Receive File:
%td
= check_box_tag :post_receive_file, 1, @project.has_post_receive_file?, disabled: true
+
%br
-%h3
+%h5
Team
%small
(#{@project.users_projects.count})
@@ -75,7 +125,7 @@
%td= link_to 'Remove from team', admin_team_member_path(tm), confirm: 'Are you sure?', method: :delete, class: "btn danger small"
%br
-%h3 Add new team member
+%h5 Add new team member
%br
= form_tag team_update_admin_project_path(@project), class: "bulk_import", method: :put do
%table.zebra-striped
diff --git a/app/views/admin/users/index.html.haml b/app/views/admin/users/index.html.haml
index 5d0f6fe1153..1df4f590bcb 100644
--- a/app/views/admin/users/index.html.haml
+++ b/app/views/admin/users/index.html.haml
@@ -1,5 +1,5 @@
%h3.page_title
- Users
+ Users (#{@admin_users.count})
= link_to 'New User', new_admin_user_path, class: "btn small right"
%br
@@ -21,13 +21,16 @@
%table
%thead
- %th Admin
- %th Name
- %th Username
- %th Email
- %th Projects
- %th Edit
- %th.cred Danger Zone!
+ %tr
+ %th Admin
+ %th
+ Name
+ %i.icon-sort-down
+ %th Username
+ %th Email
+ %th Projects
+ %th Edit
+ %th.cred Danger Zone!
- @admin_users.each do |user|
%tr
@@ -38,10 +41,13 @@
%td= user.users_projects.count
%td= link_to 'Edit', edit_admin_user_path(user), id: "edit_#{dom_id(user)}", class: "btn small"
%td.bgred
- - if user.blocked
- = link_to 'Unblock', unblock_admin_user_path(user), method: :put, class: "btn small success"
+ - if user == current_user
+ %span.cred It's you!
- else
- = link_to 'Block', block_admin_user_path(user), confirm: 'USER WILL BE BLOCKED! Are you sure?', method: :put, class: "btn small danger"
- = link_to 'Destroy', [:admin, user], confirm: "USER #{user.name} WILL BE REMOVED! Are you sure?", method: :delete, class: "btn small danger"
+ - if user.blocked
+ = link_to 'Unblock', unblock_admin_user_path(user), method: :put, class: "btn small success"
+ - else
+ = link_to 'Block', block_admin_user_path(user), confirm: 'USER WILL BE BLOCKED! Are you sure?', method: :put, class: "btn small danger"
+ = link_to 'Destroy', [:admin, user], confirm: "USER #{user.name} WILL BE REMOVED! Are you sure?", method: :delete, class: "btn small danger"
= paginate @admin_users, theme: "admin"
diff --git a/app/views/admin/users/show.html.haml b/app/views/admin/users/show.html.haml
index f9410161453..852aead79e2 100644
--- a/app/views/admin/users/show.html.haml
+++ b/app/views/admin/users/show.html.haml
@@ -40,6 +40,12 @@
%tr
%td
%b
+ Created at:
+ %td
+ = @admin_user.created_at.stamp("March 1, 1999")
+ %tr
+ %td
+ %b
Projects limit:
%td
= @admin_user.projects_limit
@@ -66,7 +72,7 @@
= @admin_user.twitter
%br
-%h3 Add User to Projects
+%h5 Add User to Projects
%br
= form_tag team_update_admin_user_path(@admin_user), class: "bulk_import", method: :put do
%table
@@ -86,8 +92,22 @@
%strong= link_to "here", help_permissions_path, class: "vlink"
%br
+- if @admin_user.groups.present?
+ %h5 Owner of groups:
+ %br
+
+ %table.zebra-striped
+ %thead
+ %tr
+ %th Name
+
+ - @admin_user.groups.each do |group|
+ %tr
+ %td= link_to group.name, admin_group_path(group)
+
+
- if @admin_user.projects.present?
- %h3 Projects
+ %h5 Projects:
%br
%table.zebra-striped
diff --git a/app/views/commits/_commits.html.haml b/app/views/commits/_commits.html.haml
index c3c7d49ce74..c9217989884 100644
--- a/app/views/commits/_commits.html.haml
+++ b/app/views/commits/_commits.html.haml
@@ -3,4 +3,4 @@
%h5.small
%i.icon-calendar
= day.stamp("28 Aug, 2010")
- %ul.unstyled= render commits
+ %ul.well-list= render commits
diff --git a/app/views/compare/_form.html.haml b/app/views/compare/_form.html.haml
index 07f1c818e4d..7e3a2a0e1f5 100644
--- a/app/views/compare/_form.html.haml
+++ b/app/views/compare/_form.html.haml
@@ -1,23 +1,30 @@
%div
- %p.slead
- Fill input field with commit id like
- %code.label_branch 4eedf23
- or branch/tag name like
- %code.label_branch master
- and press compare button for commits list, code diff.
+ - unless params[:to]
+ %p.slead
+ Fill input field with commit id like
+ %code.label_branch 4eedf23
+ or branch/tag name like
+ %code.label_branch master
+ and press compare button for commits list, code diff.
- %br
+ %br
= form_tag project_compare_index_path(@project), method: :post do
.clearfix
- = text_field_tag :from, params[:from], placeholder: "master", class: "xlarge"
- = "..."
- = text_field_tag :to, params[:to], placeholder: "aa8b4ef", class: "xlarge"
+ .pull-left
+ - if params[:to] && params[:from]
+ = link_to 'switch', {from: params[:to], to: params[:from]}, {class: 'commits-compare-switch has_tooltip', title: 'Switch base of comparison'}
+ = text_field_tag :from, params[:from], placeholder: "master", class: "xlarge"
+ = "..."
+ = text_field_tag :to, params[:to], placeholder: "aa8b4ef", class: "xlarge"
+ .pull-left
+ &nbsp;
+ = submit_tag "Compare", class: "btn primary wide commits-compare-btn"
- if @refs_are_same
.alert
%span Refs are the same
- .actions
- = submit_tag "Compare", class: "btn primary wide commits-compare-btn"
+
+
:javascript
$(function() {
diff --git a/app/views/compare/show.html.haml b/app/views/compare/show.html.haml
index 528c8b44af4..2abbd3fc0ee 100644
--- a/app/views/compare/show.html.haml
+++ b/app/views/compare/show.html.haml
@@ -9,7 +9,7 @@
- if @commits.present?
%div.ui-box
%h5.small Commits (#{@commits.count})
- %ul.unstyled= render @commits
+ %ul.well-list= render @commits
- unless @diffs.empty?
%h4 Diff
diff --git a/app/views/dashboard/_groups.html.haml b/app/views/dashboard/_groups.html.haml
index 8f66742098a..9e3401e51b8 100644
--- a/app/views/dashboard/_groups.html.haml
+++ b/app/views/dashboard/_groups.html.haml
@@ -8,11 +8,11 @@
= link_to new_admin_group_path, class: "btn very_small info" do
%i.icon-plus
New Group
- %ul.unstyled
+ %ul.well-list
- groups.each do |group|
- %li.wll
+ %li
= link_to group_path(id: group.path), class: dom_class(group) do
- %strong.group_name= truncate(group.name, length: 25)
+ %strong.well-title= truncate(group.name, length: 35)
%span.arrow
&rarr;
%span.last_activity
diff --git a/app/views/dashboard/_projects.html.haml b/app/views/dashboard/_projects.html.haml
index d92983ff6a5..cffafb5445c 100644
--- a/app/views/dashboard/_projects.html.haml
+++ b/app/views/dashboard/_projects.html.haml
@@ -16,14 +16,14 @@
= nav_tab :scope, 'joined' do
= link_to "Joined", dashboard_path(scope: 'joined')
- %ul.unstyled
+ %ul.well-list
- projects.each do |project|
- %li.wll
+ %li
= link_to project_path(project), class: dom_class(project) do
- if project.namespace
= project.namespace.human_name
\/
- %strong.project_name
+ %strong.well-title
= truncate(project.name, length: 25)
%span.arrow
&rarr;
@@ -31,6 +31,6 @@
%strong Last activity:
%span= project_last_activity(project)
- if projects.blank?
- %li.wll
+ %li
%h3.nothing_here_message There are no projects here.
.bottom= paginate projects, theme: "gitlab"
diff --git a/app/views/dashboard/index.atom.builder b/app/views/dashboard/index.atom.builder
index ffa15258f07..2bb42a65bac 100644
--- a/app/views/dashboard/index.atom.builder
+++ b/app/views/dashboard/index.atom.builder
@@ -7,7 +7,7 @@ xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://sear
xml.updated @events.maximum(:updated_at).strftime("%Y-%m-%dT%H:%M:%SZ") if @events.any?
@events.each do |event|
- if event.allowed?
+ if event.proper?
event = EventDecorator.decorate(event)
xml.entry do
event_link = event.feed_url
diff --git a/app/views/dashboard/issues.html.haml b/app/views/dashboard/issues.html.haml
index e3093bcfe2a..52863229644 100644
--- a/app/views/dashboard/issues.html.haml
+++ b/app/views/dashboard/issues.html.haml
@@ -13,8 +13,8 @@
- @issues.group_by(&:project).each do |group|
%div.ui-box
- @project = group[0]
- %h5= link_to(@project.name, project_path(@project))
- %ul.unstyled.issues_table
+ %h5= link_to_project @project
+ %ul.well-list.issues_table
- group[1].each do |issue|
= render(partial: 'issues/show', locals: {issue: issue})
%hr
diff --git a/app/views/dashboard/merge_requests.html.haml b/app/views/dashboard/merge_requests.html.haml
index 8454cfdc120..ea7c8c9a3d5 100644
--- a/app/views/dashboard/merge_requests.html.haml
+++ b/app/views/dashboard/merge_requests.html.haml
@@ -10,11 +10,12 @@
.span9
- if @merge_requests.any?
- @merge_requests.group_by(&:project).each do |group|
- %ul.unstyled.ui-box
+ .ui-box
- @project = group[0]
- %h5= @project.name
- - group[1].each do |merge_request|
- = render(partial: 'merge_requests/merge_request', locals: {merge_request: merge_request})
+ %h5= link_to_project @project
+ %ul.well-list
+ - group[1].each do |merge_request|
+ = render(partial: 'merge_requests/merge_request', locals: {merge_request: merge_request})
%hr
= paginate @merge_requests, theme: "gitlab"
diff --git a/app/views/devise/sessions/new.html.haml b/app/views/devise/sessions/new.html.haml
index 38192d7107d..474e7ef746c 100644
--- a/app/views/devise/sessions/new.html.haml
+++ b/app/views/devise/sessions/new.html.haml
@@ -3,7 +3,7 @@
- else
= form_for(resource, :as => resource_name, :url => session_path(resource_name), :html => { :class => "login-box" }) do |f|
= image_tag "login-logo.png", :width => "304", :height => "66", :class => "login-logo", :alt => "Login Logo"
- = f.text_field :email, :class => "text top", :placeholder => "Email"
+ = f.email_field :email, :class => "text top", :placeholder => "Email", :autofocus => "autofocus"
= f.password_field :password, :class => "text bottom", :placeholder => "Password"
- if devise_mapping.rememberable?
.clearfix.inputs-list
diff --git a/app/views/errors/gitolite.html.haml b/app/views/errors/gitolite.html.haml
index 2670f2d3fda..590bca71dd4 100644
--- a/app/views/errors/gitolite.html.haml
+++ b/app/views/errors/gitolite.html.haml
@@ -21,5 +21,5 @@
Permissions:
%pre
= preserve do
- sudo chmod -R 770 #{Gitlab.config.git_base_path}
- sudo chown -R git:git #{Gitlab.config.git_base_path}
+ sudo chown -R git:git #{Gitlab.config.gitolite.repos_path}
+ sudo chmod -R ug+rwXs #{Gitlab.config.gitolite.repos_path}
diff --git a/app/views/events/_event.html.haml b/app/views/events/_event.html.haml
index 2446b764e4d..191aed0747e 100644
--- a/app/views/events/_event.html.haml
+++ b/app/views/events/_event.html.haml
@@ -1,15 +1,15 @@
-- if event.allowed?
+- if event.proper?
%div.event-item
- = event_image(event)
+ %span.cgray.right
+ #{time_ago_in_words(event.created_at)} ago.
+
= image_tag gravatar_icon(event.author_email), class: "avatar s24"
- if event.push?
= render "events/event/push", event: event
+ .clearfix
+ - elsif event.note?
+ = render "events/event/note", event: event
- else
= render "events/event/common", event: event
- .clearfix
- %span.cgray.right
- = time_ago_in_words(event.created_at)
- ago.
- .clearfix
diff --git a/app/views/events/_event_last_push.html.haml b/app/views/events/_event_last_push.html.haml
index e15f1ac063c..b2376019c8e 100644
--- a/app/views/events/_event_last_push.html.haml
+++ b/app/views/events/_event_last_push.html.haml
@@ -6,7 +6,7 @@
= link_to project_commits_path(event.project, event.ref_name) do
%strong= truncate(event.ref_name, length: 28)
at
- %strong= link_to event.project.name, event.project
+ %strong= link_to_project event.project
%span
= time_ago_in_words(event.created_at)
ago.
diff --git a/app/views/events/event/_note.html.haml b/app/views/events/event/_note.html.haml
new file mode 100644
index 00000000000..8c12969345f
--- /dev/null
+++ b/app/views/events/event/_note.html.haml
@@ -0,0 +1,25 @@
+.event-title
+ %span.author_name= link_to_author event
+ %span.event_label commented on #{event.note_target_type}
+ - if event.note_target
+ - if event.note_commit?
+ = link_to event.note_short_commit_id, project_commit_path(event.project, event.note_commit_id), class: "commit_short_id"
+ - else
+ = link_to [event.project, event.note_target] do
+ %strong= truncate event.note_target_id
+
+ - elsif event.wall_note?
+ -# nothing here
+ - else
+ %strong (deleted)
+ at
+ - if event.project
+ = link_to_project event.project
+ - else
+ = event.project_name
+
+.event-body
+ %span.hint
+ &nbsp;
+ %i.icon-comment
+ = truncate event.target.note, length: 70
diff --git a/app/views/events/event/_push.html.haml b/app/views/events/event/_push.html.haml
index 869321ed699..119b8e828d0 100644
--- a/app/views/events/event/_push.html.haml
+++ b/app/views/events/event/_push.html.haml
@@ -7,12 +7,12 @@
= link_to project_commits_path(event.project, event.ref_name) do
%strong= event.ref_name
at
- %strong= link_to event.project.name, event.project
+ %strong= link_to_project event.project
- if event.push_with_commits?
- project = event.project
.event-body
- %ul.unstyled.event_commits
+ %ul.well-list.event_commits
- few_commits = event.commits[0...2]
- few_commits.each do |commit|
= render "events/commit", commit: commit, project: project
diff --git a/app/views/groups/_projects.html.haml b/app/views/groups/_projects.html.haml
index 39c0b6af685..0b491879fe0 100644
--- a/app/views/groups/_projects.html.haml
+++ b/app/views/groups/_projects.html.haml
@@ -8,13 +8,13 @@
= link_to new_project_path(namespace_id: @group.id), class: "btn very_small info" do
%i.icon-plus
New Project
- %ul.unstyled
+ %ul.well-list
- if projects.blank?
%p.nothing_here_message This groups has no projects yet
- projects.each do |project|
- %li.wll
+ %li
= link_to project_path(project), class: dom_class(project) do
- %strong.project_name= truncate(project.name, length: 25)
+ %strong.well-title= truncate(project.name, length: 25)
%span.arrow
&rarr;
%span.last_activity
diff --git a/app/views/groups/issues.html.haml b/app/views/groups/issues.html.haml
index cc488d57e9e..0daf4d752a8 100644
--- a/app/views/groups/issues.html.haml
+++ b/app/views/groups/issues.html.haml
@@ -10,7 +10,7 @@
%div.ui-box
- @project = group[0]
%h5= @project.name
- %ul.unstyled.issues_table
+ %ul.well-list.issues_table
- group[1].each do |issue|
= render(partial: 'issues/show', locals: {issue: issue})
%hr
diff --git a/app/views/groups/merge_requests.html.haml b/app/views/groups/merge_requests.html.haml
index 23a7e7222d7..72aa4ad11e1 100644
--- a/app/views/groups/merge_requests.html.haml
+++ b/app/views/groups/merge_requests.html.haml
@@ -6,7 +6,7 @@
%br
- if @merge_requests.any?
- @merge_requests.group_by(&:project).each do |group|
- %ul.unstyled.ui-box
+ %ul.well-list.ui-box
- @project = group[0]
%h5= @project.name
- group[1].each do |merge_request|
diff --git a/app/views/groups/people.html.haml b/app/views/groups/people.html.haml
index 68102b6a85a..be3dd7a4d78 100644
--- a/app/views/groups/people.html.haml
+++ b/app/views/groups/people.html.haml
@@ -9,9 +9,9 @@
Team
%small
(#{@users.size})
- %ul.unstyled
+ %ul.well-list
- @users.each do |user|
- %li.wll
+ %li
= image_tag gravatar_icon(user.email, 16), class: "avatar s16"
%strong= user.name
%span.cgray= user.email
diff --git a/app/views/groups/show.atom.builder b/app/views/groups/show.atom.builder
index fa3bfade28b..9aa52ea5593 100644
--- a/app/views/groups/show.atom.builder
+++ b/app/views/groups/show.atom.builder
@@ -7,7 +7,7 @@ xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://sear
xml.updated @events.maximum(:updated_at).strftime("%Y-%m-%dT%H:%M:%SZ") if @events.any?
@events.each do |event|
- if event.allowed?
+ if event.proper?
event = EventDecorator.decorate(event)
xml.entry do
event_link = event.feed_url
diff --git a/app/views/hooks/index.html.haml b/app/views/hooks/index.html.haml
index 1b59c8e81ab..6a36c749123 100644
--- a/app/views/hooks/index.html.haml
+++ b/app/views/hooks/index.html.haml
@@ -22,22 +22,21 @@
%hr
-if @hooks.any?
- %h3
- Hooks
- %small (#{@hooks.count})
+ %h3.page_title
+ Hooks (#{@hooks.count})
%br
%table
%thead
%tr
%th URL
- %th Method
%th
- @hooks.each do |hook|
%tr
%td
+ %span.badge.badge-info POST
= link_to project_hook_path(@project, hook) do
%strong= hook.url
- = link_to 'Test Hook', test_project_hook_path(@project, hook), class: "btn small right"
- %td POST
%td
- = link_to 'Remove', project_hook_path(@project, hook), confirm: 'Are you sure?', method: :delete, class: "danger btn small right"
+ .right
+ = link_to 'Test Hook', test_project_hook_path(@project, hook), class: "btn small grouped"
+ = link_to 'Remove', project_hook_path(@project, hook), confirm: 'Are you sure?', method: :delete, class: "danger btn small grouped"
diff --git a/app/views/issues/_form.html.haml b/app/views/issues/_form.html.haml
index 670b4e059f4..030f797c088 100644
--- a/app/views/issues/_form.html.haml
+++ b/app/views/issues/_form.html.haml
@@ -1,18 +1,18 @@
%div.issue-form-holder
%h3.page_title= @issue.new_record? ? "New Issue" : "Edit Issue ##{@issue.id}"
- = form_for [@project, @issue], remote: request.xhr? do |f|
+ = form_for [@project, @issue] do |f|
-if @issue.errors.any?
.alert-message.block-message.error
- %ul
- - @issue.errors.full_messages.each do |msg|
- %li= msg
+ - @issue.errors.full_messages.each do |msg|
+ %span= msg
+ %br
.issue_form_box
.issue_title
.clearfix
= f.label :title do
%strong= "Subject *"
.input
- = f.text_field :title, maxlength: 255, class: "xxlarge js-gfm-input", autofocus: true
+ = f.text_field :title, maxlength: 255, class: "xxlarge js-gfm-input", autofocus: true, required: true
.issue_middle_block
.issue_assignee
= f.label :assignee_id do
@@ -47,11 +47,38 @@
-else
= f.submit 'Save changes', class: "save-btn btn"
- - cancel_class = 'btn cancel-btn'
- - if request.xhr?
- = link_to "Cancel", "#back", onclick: "backToIssues();", class: cancel_class
- - else
- - if @issue.new_record?
- = link_to "Cancel", project_issues_path(@project), class: cancel_class
- - else
- = link_to "Cancel", project_issue_path(@project, @issue), class: cancel_class
+ - cancel_path = @issue.new_record? ? project_issues_path(@project) : project_issue_path(@project, @issue)
+ = link_to "Cancel", cancel_path, class: 'btn cancel-btn'
+
+
+
+
+:javascript
+ $(function(){
+ $("#issue_label_list")
+ .bind( "keydown", function( event ) {
+ if ( event.keyCode === $.ui.keyCode.TAB &&
+ $( this ).data( "autocomplete" ).menu.active ) {
+ event.preventDefault();
+ }
+ })
+ .autocomplete({
+ minLength: 0,
+ source: function( request, response ) {
+ response( $.ui.autocomplete.filter(
+ #{raw labels_autocomplete_source}, extractLast( request.term ) ) );
+ },
+ focus: function() {
+ return false;
+ },
+ select: function(event, ui) {
+ var terms = split( this.value );
+ terms.pop();
+ terms.push( ui.item.value );
+ terms.push( "" );
+ this.value = terms.join( ", " );
+ return false;
+ }
+ });
+ });
+
diff --git a/app/views/issues/_issues.html.haml b/app/views/issues/_issues.html.haml
index f82ae8bde58..d7ba4300ce7 100644
--- a/app/views/issues/_issues.html.haml
+++ b/app/views/issues/_issues.html.haml
@@ -6,7 +6,7 @@
.row
.span7= paginate @issues, remote: true, theme: "gitlab"
.span3.right
- %span.cgray.right
+ %span.cgray.right
%span.issue_counter #{@issues.total_count}
issues for this filter
- else
diff --git a/app/views/issues/_show.html.haml b/app/views/issues/_show.html.haml
index 8aa92ebfd6a..4641e8bdc63 100644
--- a/app/views/issues/_show.html.haml
+++ b/app/views/issues/_show.html.haml
@@ -1,4 +1,4 @@
-%li.wll{ id: dom_id(issue), class: issue_css_classes(issue), url: project_issue_path(issue.project, issue) }
+%li{ id: dom_id(issue), class: issue_css_classes(issue), url: project_issue_path(issue.project, issue) }
- if controller.controller_name == 'issues'
.issue_check
= check_box_tag dom_id(issue,"selected"), nil, false, 'data-id' => issue.id, class: "selected_issue", disabled: !can?(current_user, :modify_issue, issue)
@@ -16,7 +16,7 @@
= link_to 'Reopen', project_issue_path(issue.project, issue, issue: {closed: false }, status_only: true), method: :put, class: "btn small grouped reopen_issue", remote: true
- else
= link_to 'Close', project_issue_path(issue.project, issue, issue: {closed: true }, status_only: true), method: :put, class: "btn small grouped close_issue", remote: true
- = link_to edit_project_issue_path(issue.project, issue), class: "btn small edit-issue-link grouped", remote: true do
+ = link_to edit_project_issue_path(issue.project, issue), class: "btn small edit-issue-link grouped" do
%i.icon-edit
Edit
@@ -28,7 +28,7 @@
%p= link_to_gfm truncate(issue.title, length: 100), project_issue_path(issue.project, issue), class: "row_title"
%span.update-author
- %small.cdark= "##{issue.id}"
+ %span.cdark= "##{issue.id}"
- if issue.assignee
assigned to #{issue.assignee_name}
- else
diff --git a/app/views/issues/create.js.haml b/app/views/issues/create.js.haml
deleted file mode 100644
index d90cbf0d30c..00000000000
--- a/app/views/issues/create.js.haml
+++ /dev/null
@@ -1,10 +0,0 @@
-- if @issue.valid?
- :plain
- switchFromNewIssue();
- $("#issues-table").prepend("#{escape_javascript(render(partial: 'show', locals: {issue: @issue}))}");
- $.ajax({type: "GET", url: location.href, dataType: "script"});
-- else
- :plain
- $("#new_issue_dialog").empty();
- $("#new_issue_dialog").append("#{escape_javascript(render('form'))}");
- $('select#issue_assignee_id').chosen();
diff --git a/app/views/issues/edit.js.haml b/app/views/issues/edit.js.haml
deleted file mode 100644
index a994572f9b9..00000000000
--- a/app/views/issues/edit.js.haml
+++ /dev/null
@@ -1,4 +0,0 @@
-:plain
- $("#edit_issue_dialog").html("#{escape_javascript(render('form'))}");
- switchToEditIssue();
-
diff --git a/app/views/issues/index.html.haml b/app/views/issues/index.html.haml
index d89b183d360..08d4393b201 100644
--- a/app/views/issues/index.html.haml
+++ b/app/views/issues/index.html.haml
@@ -6,7 +6,7 @@
.right
.span5
- if can? current_user, :write_issue, @project
- = link_to new_project_issue_path(@project), class: "right btn", title: "New Issue", remote: true, id: "new_issue_link" do
+ = link_to new_project_issue_path(@project, issue: { assignee_id: params[:assignee_id], milestone_id: params[:milestone_id]}), class: "right btn", title: "New Issue", id: "new_issue_link" do
%i.icon-plus
New Issue
= form_tag search_project_issues_path(@project), method: :get, remote: true, id: "issue_search_form", class: :right do
@@ -27,7 +27,7 @@
.left
= select_tag('update[status]', options_for_select(['open', 'closed']), prompt: "Status")
= select_tag('update[assignee_id]', options_from_collection_for_select(@project.users.all, "id", "name", params[:assignee_id]), prompt: "Assignee")
- = select_tag('update[milestone_id]', options_from_collection_for_select(@project.milestones.order("id desc").all, "id", "title", params[:milestone_id]), prompt: "Milestone")
+ = select_tag('update[milestone_id]', options_from_collection_for_select(issues_active_milestones, "id", "title", params[:milestone_id]), prompt: "Milestone")
= hidden_field_tag 'update[issues_ids]', []
= hidden_field_tag :f, params[:f]
= button_tag "Save", class: "btn update_selected_issues"
@@ -51,16 +51,13 @@
= form_tag project_issues_path(@project), method: :get, class: :right do
= select_tag(:label_name, options_for_select(issue_tags, params[:label_name]), prompt: "Labels")
= select_tag(:assignee_id, options_from_collection_for_select([unassigned_filter] + @project.users.all, "id", "name", params[:assignee_id]), prompt: "Assignee")
- = select_tag(:milestone_id, options_from_collection_for_select([unassigned_filter] + @project.milestones.order("id desc").all, "id", "title", params[:milestone_id]), prompt: "Milestone")
+ = select_tag(:milestone_id, options_from_collection_for_select([unassigned_filter] + issues_active_milestones, "id", "title", params[:milestone_id]), prompt: "Milestone")
= hidden_field_tag :f, params[:f]
.clearfix
- %ul#issues-table.unstyled.issues_table
+ %ul#issues-table.well-list.issues_table
= render "issues"
-#new_issue_dialog
-#edit_issue_dialog
-
:javascript
$(function(){
issuesPage();
diff --git a/app/views/issues/new.js.haml b/app/views/issues/new.js.haml
deleted file mode 100644
index 4cbcc563e28..00000000000
--- a/app/views/issues/new.js.haml
+++ /dev/null
@@ -1,3 +0,0 @@
-:plain
- $("#new_issue_dialog").html("#{escape_javascript(render('form'))}");
- switchToNewIssue();
diff --git a/app/views/issues/show.html.haml b/app/views/issues/show.html.haml
index 9114febdd02..1d4d6a13c2b 100644
--- a/app/views/issues/show.html.haml
+++ b/app/views/issues/show.html.haml
@@ -26,22 +26,16 @@
.main_box
.top_box_content
- %h4
+ %h4.box-title
- if @issue.closed
- .alert-message.error.status_info Closed
- - else
- .alert-message.success.status_info Open
+ .error.status_info Closed
= gfm escape_once(@issue.title)
.middle_box_content
- %cite.cgray Created by
- = image_tag gravatar_icon(@issue.author_email), width: 16, class: "lil_av"
- %strong.author= link_to_issue_author(@issue)
-
- - if @issue.assignee
- %cite.cgray and currently assigned to
- = image_tag gravatar_icon(@issue.assignee_email), width: 16, class: "lil_av"
- %strong.author= link_to_issue_assignee(@issue)
+ %cite.cgray
+ Created by #{link_to_member(@project, @issue.author)}
+ - if @issue.assignee
+ \ and currently assigned to #{link_to_member(@project, @issue.assignee)}
- if @issue.milestone
- milestone = @issue.milestone
diff --git a/app/views/issues/update.js.haml b/app/views/issues/update.js.haml
index 44722895025..7f66022a2de 100644
--- a/app/views/issues/update.js.haml
+++ b/app/views/issues/update.js.haml
@@ -2,13 +2,3 @@
- if @issue.valid?
:plain
$("##{dom_id(@issue)}").fadeOut();
-- else
- - if @issue.valid?
- :plain
- updatePage();
- switchFromEditIssue();
- - else
- :plain
- $("#edit_issue_dialog").empty();
- $("#edit_issue_dialog").append("#{escape_javascript(render('form'))}");
- $('select#issue_assignee_id').chosen();
diff --git a/app/views/kaminari/admin/_gap.html.haml b/app/views/kaminari/admin/_gap.html.haml
index f82f185ac35..3ffd12f8587 100644
--- a/app/views/kaminari/admin/_gap.html.haml
+++ b/app/views/kaminari/admin/_gap.html.haml
@@ -4,5 +4,6 @@
-# num_pages: total number of pages
-# per_page: number of items to fetch per page
-# remote: data-remote
-%span.page.gap
- = raw(t 'views.pagination.truncate')
+%li{class: "page"}
+ %span.page.gap
+ = raw(t 'views.pagination.truncate')
diff --git a/app/views/labels/_label.html.haml b/app/views/labels/_label.html.haml
index 8a465a9e02c..6e223e8e61d 100644
--- a/app/views/labels/_label.html.haml
+++ b/app/views/labels/_label.html.haml
@@ -1,4 +1,4 @@
-%li.wll
+%li
%strong
%i.icon-tag
= label.name
diff --git a/app/views/labels/index.html.haml b/app/views/labels/index.html.haml
index 4e41d375d6a..6eb2c00e56d 100644
--- a/app/views/labels/index.html.haml
+++ b/app/views/labels/index.html.haml
@@ -4,7 +4,7 @@
Labels
%br
%div.ui-box
- %ul.unstyled.labels-table
+ %ul.well-list.labels-table
- @labels.each do |label|
= render 'label', label: label
diff --git a/app/views/layouts/_init_auto_complete.html.haml b/app/views/layouts/_init_auto_complete.html.haml
index 7b2a291d05c..800dfbe8859 100644
--- a/app/views/layouts/_init_auto_complete.html.haml
+++ b/app/views/layouts/_init_auto_complete.html.haml
@@ -1,6 +1,6 @@
:javascript
$(function() {
- GitLab.GfmAutoComplete.Members.url = "#{ "/api/v2/projects/#{@project.path}/members" if @project }";
+ GitLab.GfmAutoComplete.Members.url = "#{ "/api/v2/projects/#{@project.id}/members" if @project }";
GitLab.GfmAutoComplete.Members.params.private_token = "#{current_user.private_token}";
GitLab.GfmAutoComplete.Emoji.data = #{raw emoji_autocomplete_source};
diff --git a/app/views/layouts/notify.html.haml b/app/views/layouts/notify.html.haml
index 35bf5577e1c..c418e1dbc68 100644
--- a/app/views/layouts/notify.html.haml
+++ b/app/views/layouts/notify.html.haml
@@ -3,14 +3,7 @@
%meta{content: "text/html; charset=utf-8", "http-equiv" => "Content-Type"}
%title
GitLab
- :css
- .header h1 {color: #BBBBBB !important; font: bold 22px Helvetica, Arial, sans-serif; margin: 0; padding: 0; line-height: 32px;}
- .header p {color: #c6c6c6; font: normal 12px Helvetica, Arial, sans-serif; margin: 0; padding: 0; line-height: 18px;}
- .content h2 {color:#646464 !important; font-weight: bold; margin: 0; padding: 0; line-height: 26px; font-size: 18px; font-family: Helvetica, Arial, sans-serif; }
- .content p {color:#767676; font-weight: normal; margin: 0; padding: 0; line-height: 20px; font-size: 12px;font-family: Helvetica, Arial, sans-serif;}
- .content a {color: #0eb6ce; text-decoration: none;}
- .footer p {font-size: 11px; color:#7d7a7a; margin: 0; padding: 0; font-family: Helvetica, Arial, sans-serif;}
- .footer a {color: #0eb6ce; text-decoration: none;}
+
%body{bgcolor: "#EAEAEA", style: "margin: 0; padding: 0; background: #EAEAEA"}
%table{align: "center", border: "0", cellpadding: "0", cellspacing: "0", style: "padding: 35px 0; background: #EAEAEA;", width: "100%"}
%tr
@@ -19,11 +12,11 @@
%tr
%td{style: "font-size: 0px;", width: "20"}
\ 
- %td{align: "left", style: "padding: 18px 0 10px;", width: "580"}
- %h1{style: "color: #BBBBBB; font: normal 22px Helvetica, Arial, sans-serif; margin: 0; padding: 0; line-height: 32px;"}
+ %td{align: "left", style: "padding: 10px 0", width: "580"}
+ %h1{style: "font-size: 24px; color: #BBBBBB; font: normal 22px Helvetica, Arial, sans-serif; margin: 0; padding: 0; line-height: 32px;"}
GITLAB
- if @project
- | #{@project.name}
+ &rarr; #{@project.name_with_namespace}
%table{align: "center", bgcolor: "#fff", border: "0", cellpadding: "0", cellspacing: "0", style: "font-family: Helvetica, Arial, sans-serif; background: #fff;", width: "600"}
%tr= yield
%tr
@@ -35,5 +28,5 @@
%p{style: "font-size: 11px; color:#7d7a7a; margin: 0; padding: 0; font-family: Helvetica, Arial, sans-serif;"}
You're receiving this notification because you are a member of the
- if @project
- #{@project.name}
+ #{@project.name_with_namespace}
project team.
diff --git a/app/views/layouts/project_resource.html.haml b/app/views/layouts/project_resource.html.haml
index ab8e88c07cd..709807456c8 100644
--- a/app/views/layouts/project_resource.html.haml
+++ b/app/views/layouts/project_resource.html.haml
@@ -1,9 +1,9 @@
!!! 5
%html{ lang: "en"}
- = render "layouts/head", title: @project.name
+ = render "layouts/head", title: @project.name_with_namespace
%body{class: "#{app_theme} project"}
= render "layouts/flash"
- = render "layouts/head_panel", title: @project.name
+ = render "layouts/head_panel", title: project_title(@project)
- if can?(current_user, :download_code, @project)
= render 'shared/no_ssh'
.container
diff --git a/app/views/merge_requests/_form.html.haml b/app/views/merge_requests/_form.html.haml
index 302e75cfb00..9606e2e53b3 100644
--- a/app/views/merge_requests/_form.html.haml
+++ b/app/views/merge_requests/_form.html.haml
@@ -32,7 +32,7 @@
.top_box_content
= f.label :title do
%strong= "Title *"
- .input= f.text_field :title, class: "input-xxlarge pad js-gfm-input", maxlength: 255, rows: 5
+ .input= f.text_field :title, class: "input-xxlarge pad js-gfm-input", maxlength: 255, rows: 5, required: true
.merge_requests_middle_box
.merge_requests_assignee
= f.label :assignee_id do
diff --git a/app/views/merge_requests/_merge_request.html.haml b/app/views/merge_requests/_merge_request.html.haml
index 4f68c5f2620..7369f3dd061 100644
--- a/app/views/merge_requests/_merge_request.html.haml
+++ b/app/views/merge_requests/_merge_request.html.haml
@@ -1,4 +1,4 @@
-%li.wll{ class: mr_css_classes(merge_request) }
+%li{ class: mr_css_classes(merge_request) }
.right
.left
- if merge_request.merged?
diff --git a/app/views/merge_requests/_show.html.haml b/app/views/merge_requests/_show.html.haml
index f1d0c8aaafb..20ba991e79a 100644
--- a/app/views/merge_requests/_show.html.haml
+++ b/app/views/merge_requests/_show.html.haml
@@ -2,6 +2,8 @@
= render "merge_requests/show/how_to_merge"
= render "merge_requests/show/mr_box"
= render "merge_requests/show/mr_accept"
+- if @project.gitlab_ci?
+ = render "merge_requests/show/mr_ci"
= render "merge_requests/show/commits"
- if @commits.present?
@@ -28,6 +30,8 @@
MergeRequest.init({
url_to_automerge_check: "#{automerge_check_project_merge_request_path(@project, @merge_request)}",
check_enable: #{@merge_request.state == MergeRequest::UNCHECKED ? "true" : "false"},
+ url_to_ci_check: "#{ci_status_project_merge_request_path(@project, @merge_request)}",
+ ci_enable: #{@project.gitlab_ci? ? "true" : "false"},
current_state: "#{@merge_request.human_state}",
action: "#{controller.action_name}"
});
diff --git a/app/views/merge_requests/index.html.haml b/app/views/merge_requests/index.html.haml
index 7bcb7a81e1a..5b234bfbe02 100644
--- a/app/views/merge_requests/index.html.haml
+++ b/app/views/merge_requests/index.html.haml
@@ -30,7 +30,7 @@
= hidden_field_tag :f, params[:f]
.clearfix
- %ul.unstyled
+ %ul.well-list
= render @merge_requests
- if @merge_requests.blank?
%li
diff --git a/app/views/merge_requests/show/_commits.html.haml b/app/views/merge_requests/show/_commits.html.haml
index d25e707c64e..796922776d9 100644
--- a/app/views/merge_requests/show/_commits.html.haml
+++ b/app/views/merge_requests/show/_commits.html.haml
@@ -5,19 +5,19 @@
Commits (#{@commits.count})
.merge-request-commits
- if @commits.count > 8
- %ul.first_mr_commits.unstyled
+ %ul.first_mr_commits.well-list
- @commits.first(8).each do |commit|
= render "commits/commit", commit: commit
%li.bottom
8 of #{@commits.count} commits displayed.
%strong
%a.mr_show_all_commits Click here to show all
- %ul.all_mr_commits.hide.unstyled
+ %ul.all_mr_commits.hide.well-list
- @commits.each do |commit|
= render "commits/commit", commit: commit
- else
- %ul.unstyled
+ %ul.well-list
- @commits.each do |commit|
= render "commits/commit", commit: commit
diff --git a/app/views/merge_requests/show/_mr_box.html.haml b/app/views/merge_requests/show/_mr_box.html.haml
index b4b4be2980a..cd33732d191 100644
--- a/app/views/merge_requests/show/_mr_box.html.haml
+++ b/app/views/merge_requests/show/_mr_box.html.haml
@@ -1,25 +1,20 @@
.main_box
.top_box_content
- %h4
- - if @merge_request.closed
- .alert-message.error.status_info Closed
- - else
- .alert-message.success.status_info Open
+ %h4.box-title
+ - if @merge_request.merged
+ .error.status_info
+ %i.icon-ok
+ Merged
+ - elsif @merge_request.closed
+ .error.status_info Closed
= gfm escape_once(@merge_request.title)
- - if @project.gitlab_ci?
- .right
- = image_tag ci_status_path, class: 'status-badge'
.middle_box_content
%div
- %cite.cgray Created at #{@merge_request.created_at.stamp("Aug 21, 2011")} by
- = image_tag gravatar_icon(@merge_request.author_email), width: 16, class: "lil_av"
- %strong.author= link_to_merge_request_author(@merge_request)
-
- - if @merge_request.assignee
- %cite.cgray , currently assigned to
- = image_tag gravatar_icon(@merge_request.assignee_email), width: 16, class: "lil_av"
- %strong.author= link_to_merge_request_assignee(@merge_request)
+ %cite.cgray
+ Created at #{@merge_request.created_at.stamp("Aug 21, 2011")} by #{link_to_member(@project, @merge_request.author)}
+ - if @merge_request.assignee
+ \, currently assigned to #{link_to_member(@project, @merge_request.assignee)}
- if @merge_request.milestone
- milestone = @merge_request.milestone
%cite.cgray and attached to milestone
@@ -30,10 +25,10 @@
.bottom_box_content
- if @merge_request.merged?
%span
- Merged by #{@merge_request.merge_event.author_name}
+ Merged by #{link_to_member(@project, @merge_request.merge_event.author)}
%small #{time_ago_in_words(@merge_request.merge_event.created_at)} ago.
- elsif @merge_request.closed_event
%span
- Closed by #{@merge_request.closed_event.author_name}
+ Closed by #{link_to_member(@project, @merge_request.closed_event.author)}
%small #{time_ago_in_words(@merge_request.closed_event.created_at)} ago.
diff --git a/app/views/merge_requests/show/_mr_ci.html.haml b/app/views/merge_requests/show/_mr_ci.html.haml
new file mode 100644
index 00000000000..d46b606ef7f
--- /dev/null
+++ b/app/views/merge_requests/show/_mr_ci.html.haml
@@ -0,0 +1,35 @@
+- if @merge_request.open? && @commits.any?
+ .ci_widget.ci-success{style: "display:none"}
+ .alert.alert-success
+ %i.icon-ok
+ %strong CI build passed
+ for #{@merge_request.last_commit_short_sha}.
+ = link_to "Build page", ci_build_details_path(@merge_request)
+
+
+ .ci_widget.ci-failed{style: "display:none"}
+ .alert.alert-error
+ %i.icon-remove
+ %strong CI build failed
+ for #{@merge_request.last_commit_short_sha}.
+ = link_to "Build page", ci_build_details_path(@merge_request)
+
+ - [:running, :pending].each do |status|
+ .ci_widget{class: "ci-#{status}", style: "display:none"}
+ .alert
+ %i.icon-time
+ %strong CI build #{status}
+ for #{@merge_request.last_commit_short_sha}.
+ = link_to "Build page", ci_build_details_path(@merge_request)
+
+ .ci_widget
+ .alert-message
+ %strong
+ %i.icon-refresh
+ Checking for CI status for #{@merge_request.last_commit_short_sha}
+
+ .ci_widget.ci-error{style: "display:none"}
+ .alert.alert-error
+ %i.icon-remove
+ %strong Cannot connect to CI server. Please check your setting
+
diff --git a/app/views/merge_requests/show/_mr_title.html.haml b/app/views/merge_requests/show/_mr_title.html.haml
index a5275650d86..c2ffe8e3770 100644
--- a/app/views/merge_requests/show/_mr_title.html.haml
+++ b/app/views/merge_requests/show/_mr_title.html.haml
@@ -6,11 +6,6 @@
%span.label_branch= @merge_request.target_branch
%span.right
- - if @merge_request.merged?
- %span.btn.small.disabled.grouped
- %strong
- %i.icon-ok
- = "MERGED"
- if can?(current_user, :modify_merge_request, @merge_request)
- if @merge_request.open?
.left.btn-group
diff --git a/app/views/milestones/_milestone.html.haml b/app/views/milestones/_milestone.html.haml
index 7c4c0e67d7c..3864792f7e8 100644
--- a/app/views/milestones/_milestone.html.haml
+++ b/app/views/milestones/_milestone.html.haml
@@ -1,22 +1,27 @@
-%li{class: "milestone", id: dom_id(milestone) }
+%li{class: "milestone milestone-#{milestone.closed ? 'closed' : 'open'}", id: dom_id(milestone) }
.right
- - if can? current_user, :admin_milestone, milestone.project
+ - if can?(current_user, :admin_milestone, milestone.project) and milestone.open?
= link_to edit_project_milestone_path(milestone.project, milestone), class: "btn small edit-milestone-link grouped" do
%i.icon-edit
Edit
%h4
= link_to_gfm truncate(milestone.title, length: 100), project_milestone_path(milestone.project, milestone)
+ - if milestone.expired? and not milestone.closed
+ %span.cred (Expired)
%small
= milestone.expires_at
- .row
- .span4
- .progress.progress-info
- .bar{style: "width: #{milestone.percent_complete}%;"}
- .span6
- = link_to project_issues_path(milestone.project, milestone_id: milestone.id) do
- = pluralize milestone.issues.count, 'Issue'
- &nbsp;
- = link_to project_merge_requests_path(milestone.project, milestone_id: milestone.id) do
- = pluralize milestone.merge_requests.count, 'Merge Request'
- &nbsp;
- %span.light #{milestone.percent_complete}% complete
+ - if milestone.is_empty?
+ %span.muted Empty
+ - else
+ .row
+ .span4
+ .progress.progress-info
+ .bar{style: "width: #{milestone.percent_complete}%;"}
+ .span6
+ = link_to project_issues_path(milestone.project, milestone_id: milestone.id) do
+ = pluralize milestone.issues.count, 'Issue'
+ &nbsp;
+ = link_to project_merge_requests_path(milestone.project, milestone_id: milestone.id) do
+ = pluralize milestone.merge_requests.count, 'Merge Request'
+ &nbsp;
+ %span.light #{milestone.percent_complete}% complete
diff --git a/app/views/milestones/index.html.haml b/app/views/milestones/index.html.haml
index c5333b08fdc..3089595fe0b 100644
--- a/app/views/milestones/index.html.haml
+++ b/app/views/milestones/index.html.haml
@@ -11,15 +11,18 @@
%li{class: ("active" if (params[:f] == "active" || !params[:f]))}
= link_to project_milestones_path(@project, f: "active") do
Active
+ %li{class: ("active" if params[:f] == "closed")}
+ = link_to project_milestones_path(@project, f: "closed") do
+ Closed
%li{class: ("active" if params[:f] == "all")}
= link_to project_milestones_path(@project, f: "all") do
All
- %ul.unstyled
+ %ul.well-list
= render @milestones
- if @milestones.present?
- %li.bottom= paginate @milestones, remote: true, theme: "gitlab"
+ %li.bottom= paginate @milestones, theme: "gitlab"
- else
%li
%h3.nothing_here_message Nothing to show here
diff --git a/app/views/milestones/show.html.haml b/app/views/milestones/show.html.haml
index b8bc788c953..c4975c72ef2 100644
--- a/app/views/milestones/show.html.haml
+++ b/app/views/milestones/show.html.haml
@@ -1,31 +1,41 @@
-%h3.page_title
- Milestone ##{@milestone.id}
- %small
- = @milestone.expires_at
+.row
+ .span6
+ %h3.page_title
+ Milestone ##{@milestone.id}
+ %small
+ = @milestone.expires_at
+ .back_link
+ = link_to project_milestones_path(@project) do
+ &larr; To milestones list
+ .span6
+ .right
+ - unless @milestone.closed
+ = link_to new_project_issue_path(@project, issue: { milestone_id: @milestone.id }), class: "btn small grouped", title: "New Issue" do
+ %i.icon-plus
+ New Issue
+ = link_to 'Browse Issues', project_issues_path(@milestone.project, milestone_id: @milestone.id), class: "btn edit-milestone-link small grouped"
+ - if can?(current_user, :admin_milestone, @project)
+ = link_to edit_project_milestone_path(@project, @milestone), class: "btn small grouped" do
+ %i.icon-edit
+ Edit
- %span.right
- = link_to new_project_issue_path(@project, issue: { milestone_id: @milestone.id }), class: "btn small grouped", title: "New Issue" do
- %i.icon-plus
- New Issue
- = link_to 'Browse Issues', project_issues_path(@milestone.project, milestone_id: @milestone.id), class: "btn edit-milestone-link small grouped"
- - if can?(current_user, :admin_milestone, @project)
- = link_to edit_project_milestone_path(@project, @milestone), class: "btn small grouped" do
- %i.icon-edit
- Edit
-.back_link
- = link_to project_milestones_path(@project) do
- &larr; To milestones list
+
+- if @milestone.can_be_closed?
+ %hr
+ %p
+ %span All issues for this milestone are closed. You may close milestone now.
+ = link_to 'Close Milestone', project_milestone_path(@project, @milestone, milestone: {closed: true }), method: :put, class: "btn small danger"
.main_box
.top_box_content
- %h5
+ %h4.box-title
- if @milestone.closed
- .alert-message.error.status_info Closed
- - else
- .alert-message.success.status_info Open
+ .error.status_info Closed
+ - elsif @milestone.expired?
+ .error.status_info Expired
+
= gfm escape_once(@milestone.title)
- %small.right= @milestone.expires_at
.middle_box_content
%h5
@@ -34,6 +44,7 @@
#{@milestone.closed_items_count} closed
&ndash;
#{@milestone.open_items_count} open
+ %span.right= @milestone.expires_at
.progress.progress-info
.bar{style: "width: #{@milestone.percent_complete}%;"}
@@ -43,14 +54,16 @@
= preserve do
= markdown @milestone.description
+
.row
.span6
%table.milestone-issue-filter
%thead
- %th
- %ul.nav.nav-pills
- %li.active= link_to('Open Issues', '#')
- %li=link_to('All Issues', '#')
+ %tr
+ %th
+ %ul.nav.nav-pills
+ %li.active= link_to('Open Issues', '#')
+ %li=link_to('All Issues', '#')
- @issues.each do |issue|
%tr{data: {closed: issue.closed}}
%td
@@ -62,10 +75,11 @@
.span6
%table.milestone-merge-requests-filter
%thead
- %th
- %ul.nav.nav-pills
- %li.active= link_to('Open Merge Requests', '#')
- %li=link_to('All Merge Requests', '#')
+ %tr
+ %th
+ %ul.nav.nav-pills
+ %li.active= link_to('Open Merge Requests', '#')
+ %li=link_to('All Merge Requests', '#')
- @merge_requests.each do |merge_request|
%tr{data: {closed: merge_request.closed}}
%td
diff --git a/app/views/notes/_common_form.html.haml b/app/views/notes/_common_form.html.haml
index 0725082d504..d76be75bc27 100644
--- a/app/views/notes/_common_form.html.haml
+++ b/app/views/notes/_common_form.html.haml
@@ -7,6 +7,7 @@
%div= msg
= f.hidden_field :noteable_id
+ = f.hidden_field :commit_id
= f.hidden_field :noteable_type
= f.text_area :note, size: 255, class: 'note-text js-gfm-input'
#preview-note.preview_note.hide
diff --git a/app/views/notes/_per_line_form.html.haml b/app/views/notes/_per_line_form.html.haml
index c8d79850162..ff80ad4e0d5 100644
--- a/app/views/notes/_per_line_form.html.haml
+++ b/app/views/notes/_per_line_form.html.haml
@@ -11,6 +11,7 @@
%div= msg
= f.hidden_field :noteable_id
+ = f.hidden_field :commit_id
= f.hidden_field :noteable_type
= f.hidden_field :line_code
= f.text_area :note, size: 255, class: 'line-note-text js-gfm-input'
diff --git a/app/views/notify/issue_status_changed_email.html.haml b/app/views/notify/issue_status_changed_email.html.haml
index 59130f79d6c..c433e80c9e5 100644
--- a/app/views/notify/issue_status_changed_email.html.haml
+++ b/app/views/notify/issue_status_changed_email.html.haml
@@ -9,7 +9,7 @@
%tr
%td{style: "font-size: 1px; line-height: 1px;", width: "21"}
%td{align: "left", style: "padding: 20px 0 0;"}
- %h2{style: "color:#646464 !important; font-weight: bold; margin: 0; padding: 0; line-height: 26px; font-size: 18px; font-family: Helvetica, Arial, sans-serif; "}
+ %p{style: "color:#646464 !important; line-height: 26px; font-size: 16px; font-family: Helvetica, Arial, sans-serif; "}
= "Issue ##{@issue.id}"
= link_to_gfm truncate(@issue.title, length: 45), project_issue_url(@issue.project, @issue), title: @issue.title
%br
diff --git a/app/views/notify/new_issue_email.html.haml b/app/views/notify/new_issue_email.html.haml
index 654d6cd12be..fba4b865487 100644
--- a/app/views/notify/new_issue_email.html.haml
+++ b/app/views/notify/new_issue_email.html.haml
@@ -9,7 +9,7 @@
%tr
%td{style: "font-size: 1px; line-height: 1px;", width: "21"}
%td{align: "left", style: "padding: 20px 0 0;"}
- %h2{style: "color:#646464 !important; font-weight: bold; margin: 0; padding: 0; line-height: 26px; font-size: 18px; font-family: Helvetica, Arial, sans-serif; "}
+ %p{style: "color:#646464 !important; line-height: 26px; font-size: 16px; font-family: Helvetica, Arial, sans-serif; "}
= "Issue ##{@issue.id}"
= link_to_gfm truncate(@issue.title, length: 45), project_issue_url(@issue.project, @issue), title: @issue.title
%br
diff --git a/app/views/notify/new_merge_request_email.html.haml b/app/views/notify/new_merge_request_email.html.haml
index 151aac451fb..9819767011e 100644
--- a/app/views/notify/new_merge_request_email.html.haml
+++ b/app/views/notify/new_merge_request_email.html.haml
@@ -5,7 +5,8 @@
%td{align: "left", style: "padding: 20px 0 0;"}
%h2{style: "color:#646464; font-weight: bold; margin: 0; padding: 0; line-height: 26px; font-size: 18px; font-family: Helvetica, Arial, sans-serif; "}
= "New Merge Request !#{@merge_request.id}"
- = link_to_gfm truncate(@merge_request.title, length: 16), project_merge_request_url(@merge_request.project, @merge_request)
+ %p{style: "color:#646464 !important; line-height: 26px; font-size: 16px; font-family: Helvetica, Arial, sans-serif; "}
+ = link_to_gfm truncate(@merge_request.title, length: 40), project_merge_request_url(@merge_request.project, @merge_request)
%td{style: "font-size: 1px; line-height: 1px;", width: "21"}
%tr
%td{style: "font-size: 1px; line-height: 1px;", width: "21"}
diff --git a/app/views/notify/project_access_granted_email.html.haml b/app/views/notify/project_access_granted_email.html.haml
index 72b3f0658fc..11117bf0b33 100644
--- a/app/views/notify/project_access_granted_email.html.haml
+++ b/app/views/notify/project_access_granted_email.html.haml
@@ -1,14 +1,15 @@
%td.content{align: "left", style: "font-family: Helvetica, Arial, sans-serif; padding: 20px 0 0;", valign: "top", width: "600"}
%table{border: "0", cellpadding: "0", cellspacing: "0", style: "color: #717171; font: normal 11px Helvetica, Arial, sans-serif; margin: 0; padding: 0;", width: "600"}
%tr
- %td{style: "font-size: 1px; line-height: 1px;", width: "21"}
- %td{align: "left", style: "padding: 20px 0 0;"}
- %h2{style: "color:#646464; font-weight: bold; margin: 0; padding: 0; line-height: 26px; font-size: 18px; font-family: Helvetica, Arial, sans-serif; "}
+ %td{width: "21"}
+ %td
+ %h2{style: "color:#646464;" }
= "You have been granted #{@users_project.project_access_human} access to project"
%td{style: "font-size: 1px; line-height: 1px;", width: "21"}
%tr
- %td{style: "font-size: 1px; line-height: 1px;", width: "21"}
- %td{align: "left", style: "padding: 20px 0 0;"}
- %h2{style: "color:#646464 !important; font-weight: bold; margin: 0; padding: 0; line-height: 26px; font-size: 18px; font-family: Helvetica, Arial, sans-serif; "}
- = link_to_gfm truncate(@project.name, length: 45), project_url(@project), title: @project.name
+ %td{width: "21"}
+ %td
+ %h3
+ = link_to project_url(@project) do
+ = @project.name_with_namespace
%br
diff --git a/app/views/notify/project_was_moved_email.html.haml b/app/views/notify/project_was_moved_email.html.haml
new file mode 100644
index 00000000000..222bd0fecea
--- /dev/null
+++ b/app/views/notify/project_was_moved_email.html.haml
@@ -0,0 +1,25 @@
+%td.content{align: "left", style: "font-family: Helvetica, Arial, sans-serif; padding: 20px 0 0;", valign: "top", width: "600"}
+ %table{border: "0", cellpadding: "0", cellspacing: "0", style: "color: #555; font: normal 11px Helvetica, Arial, sans-serif; margin: 0; padding: 0;", width: "600"}
+ %tr
+ %td{width: "21"}
+ %td
+ %h2
+ = "Project was moved to another location"
+ %td{width: "21"}
+ %tr
+ %td{width: "21"}
+ %td
+ %p
+ The project is now located under
+ = link_to project_url(@project) do
+ = @project.name_with_namespace
+ %p
+ To update the remote url in your local repository run:
+ %br
+ %table{border: "0", cellpadding: "0", cellspacing: "0", width: "558"}
+ %tr
+ %td{valign: "top"}
+ %p{ style: "background:#f5f5f5; padding:10px; border:1px solid #ddd" }
+ git remote set-url origin #{@project.ssh_url_to_repo}
+ %br
+ %td{ width: "21"}
diff --git a/app/views/notify/reassigned_issue_email.html.haml b/app/views/notify/reassigned_issue_email.html.haml
index c7896af3a54..31a5d23242c 100644
--- a/app/views/notify/reassigned_issue_email.html.haml
+++ b/app/views/notify/reassigned_issue_email.html.haml
@@ -5,7 +5,7 @@
%td{align: "left", style: "padding: 20px 0 0;"}
%h2{style: "color:#646464; font-weight: bold; margin: 0; padding: 0; line-height: 26px; font-size: 18px; font-family: Helvetica, Arial, sans-serif; "}
= "Reassigned Issue ##{@issue.id}"
- = link_to_gfm truncate(@issue.title, length: 16), project_issue_url(@issue.project, @issue)
+ = link_to_gfm truncate(@issue.title, length: 30), project_issue_url(@issue.project, @issue)
%td{style: "font-size: 1px; line-height: 1px;", width: "21"}
%tr
%td{style: "font-size: 1px; line-height: 1px;", width: "21"}
diff --git a/app/views/notify/reassigned_merge_request_email.html.haml b/app/views/notify/reassigned_merge_request_email.html.haml
index e49b783635c..8f7308b3dba 100644
--- a/app/views/notify/reassigned_merge_request_email.html.haml
+++ b/app/views/notify/reassigned_merge_request_email.html.haml
@@ -5,7 +5,7 @@
%td{align: "left", style: "padding: 20px 0 0;"}
%h2{style: "color:#646464; font-weight: bold; margin: 0; padding: 0; line-height: 26px; font-size: 18px; font-family: Helvetica, Arial, sans-serif; "}
= "Reassigned Merge Request !#{@merge_request.id}"
- = link_to_gfm truncate(@merge_request.title, length: 16), project_merge_request_url(@merge_request.project, @merge_request)
+ = link_to_gfm truncate(@merge_request.title, length: 30), project_merge_request_url(@merge_request.project, @merge_request)
%td{style: "font-size: 1px; line-height: 1px;", width: "21"}
%tr
%td{style: "font-size: 1px; line-height: 1px;", width: "21"}
diff --git a/app/views/profiles/account.html.haml b/app/views/profiles/account.html.haml
index 1c51f48f401..3c290948d6c 100644
--- a/app/views/profiles/account.html.haml
+++ b/app/views/profiles/account.html.haml
@@ -1,4 +1,4 @@
-- if Gitlab.config.omniauth_enabled?
+- if Gitlab.config.omniauth.enabled
%fieldset
%legend Social Accounts
.oauth_select_holder
@@ -71,6 +71,9 @@
%span.update-failed.cred.hide
%i.icon-ok
Failed
+ %ul.cred
+ %li It will change web url for personal projects.
+ %li It will change the git path to repositories for personal projects.
.input
= f.submit 'Save username', class: "btn save-btn"
diff --git a/app/views/profiles/show.html.haml b/app/views/profiles/show.html.haml
index ac36fa3aa55..934c1fdf7c4 100644
--- a/app/views/profiles/show.html.haml
+++ b/app/views/profiles/show.html.haml
@@ -33,11 +33,11 @@
%ul
%li
%p You can change your password on Account page
- -unless Gitlab.config.disable_gravatar?
+ - if Gitlab.config.gravatar.enabled
%li
%p You can change your avatar at #{link_to "gravatar.com", "http://gravatar.com"}
- - if Gitlab.config.omniauth_enabled? && @user.provider?
+ - if Gitlab.config.omniauth.enabled && @user.provider?
%li
%p
You can login through #{@user.provider.titleize}!
diff --git a/app/views/projects/_form.html.haml b/app/views/projects/_form.html.haml
index 448293ca080..7044d1f20be 100644
--- a/app/views/projects/_form.html.haml
+++ b/app/views/projects/_form.html.haml
@@ -17,19 +17,6 @@
.controls
= text_field_tag :ppath, @project.path_to_repo, class: "xxlarge", readonly: true
- .control-group
- = f.label :namespace_id do
- %span Namespace
- .controls
- - if can? current_user, :change_namespace, @project
- = f.select :namespace_id, namespaces_options(@project.namespace_id), {prompt: 'Choose a project namespace'}, {class: 'chosen'}
- &nbsp;
- %span.cred Be careful. Changing project namespace can have unintended side effects
- - else
- %a.btn.disabled= @project.namespace.try(:human_name) || "/"
- &nbsp;
- %span.cred Only owner can change project namespace.
-
- unless @project.heads.empty?
.clearfix
@@ -63,6 +50,22 @@
= f.check_box :wiki_enabled
%span.descr Pages for project documentation
+
+ - if can? current_user, :change_namespace, @project
+ %fieldset.features
+ %legend Transfer:
+ .control-group
+ = f.label :namespace_id do
+ %span Namespace
+ .controls
+ = f.select :namespace_id, namespaces_options(@project.namespace_id || Namespace::global_id), {prompt: 'Choose a project namespace'}, {class: 'chosen'}
+ %br
+ %ul.prepend-top-10.cred
+ %li Be careful. Changing project namespace can have unintended side effects
+ %li You can transfer project only to namespaces you can manage
+ %li You will need to update your local repositories to point to the new location.
+
+
%br
.actions
diff --git a/app/views/projects/create.js.haml b/app/views/projects/create.js.haml
index ce73fe0cf01..d388988676d 100644
--- a/app/views/projects/create.js.haml
+++ b/app/views/projects/create.js.haml
@@ -9,3 +9,4 @@
$('.project_new_holder').show();
$("#new_project").replaceWith("#{escape_javascript(render('new_form'))}");
$('.save-project-loader').hide();
+ new Projects();
diff --git a/app/views/projects/files.html.haml b/app/views/projects/files.html.haml
index 9f7efcdc515..d108308318e 100644
--- a/app/views/projects/files.html.haml
+++ b/app/views/projects/files.html.haml
@@ -17,7 +17,6 @@
= time_ago_in_words(note.created_at)
ago
- else
- .alert-message.block-message
- %span All files attached to project wall, issues etc will be displayed here
+ %p.slead All files attached to project wall, issues etc will be displayed here
diff --git a/app/views/projects/graph.html.haml b/app/views/projects/graph.html.haml
index 1ba280bb06c..4e0b0e36c34 100644
--- a/app/views/projects/graph.html.haml
+++ b/app/views/projects/graph.html.haml
@@ -4,7 +4,7 @@
%h4
%small You can move around the graph by using the arrow keys.
#holder.graph
- .loading
+ .loading.loading-gray
:javascript
var branch_graph;
diff --git a/app/views/projects/update_failed.js.haml b/app/views/projects/update_failed.js.haml
new file mode 100644
index 00000000000..a3ac5f4088f
--- /dev/null
+++ b/app/views/projects/update_failed.js.haml
@@ -0,0 +1,2 @@
+:plain
+ $(".save-project-loader").replaceWith(errorMessage('#{escape_javascript(@error.message)}'));
diff --git a/app/views/services/index.html.haml b/app/views/services/index.html.haml
index ae3dbef97ad..2c94f965eec 100644
--- a/app/views/services/index.html.haml
+++ b/app/views/services/index.html.haml
@@ -2,24 +2,28 @@
%h3.page_title Services
%br
-%ul.unstyled.ui-box
- %li.wll
- %h4
+%ul.ui-box.well-list
+ %li
+ %h4.cgreen
= link_to edit_project_service_path(@project, :gitlab_ci) do
GitLab CI
%small Continuous integration server from GitLab
.right
- if @gitlab_ci_service.try(:active)
- %small.cgreen Enabled
+ %small.cgreen
+ %i.icon-ok
+ Enabled
- else
- %small.cgray Disabled
- %li.wll
+ %small.cgray
+ %i.icon-off
+ Disabled
+ %li.disabled
%h4
Jenkins CI
%small An extendable open source continuous integration server
.right
%small Not implemented yet
- %li.wll
+ %li.disabled
%h4
Campfire
%small Web-based group chat tool
diff --git a/app/views/shared/_clone_panel.html.haml b/app/views/shared/_clone_panel.html.haml
index f632e1221f9..e283d9b3085 100644
--- a/app/views/shared/_clone_panel.html.haml
+++ b/app/views/shared/_clone_panel.html.haml
@@ -1,4 +1,4 @@
.input-prepend.project_clone_holder
%button{class: "btn active", :"data-clone" => @project.ssh_url_to_repo} SSH
- %button{class: "btn", :"data-clone" => @project.http_url_to_repo}= Gitlab.config.web_protocol.upcase
+ %button{class: "btn", :"data-clone" => @project.http_url_to_repo}= Gitlab.config.gitlab.protocol.upcase
= text_field_tag :project_clone, @project.url_to_repo, class: "one_click_select input-xxlarge"
diff --git a/app/views/snippets/_form.html.haml b/app/views/snippets/_form.html.haml
index 981c7cf0c12..baef737b565 100644
--- a/app/views/snippets/_form.html.haml
+++ b/app/views/snippets/_form.html.haml
@@ -1,28 +1,41 @@
%h3.page_title
= @snippet.new_record? ? "New Snippet" : "Edit Snippet ##{@snippet.id}"
%hr
-= form_for [@project, @snippet] do |f|
- -if @snippet.errors.any?
- .alert-message.block-message.error
- %ul
- - @snippet.errors.full_messages.each do |msg|
- %li= msg
+.snippet-form-holder
+ = form_for [@project, @snippet] do |f|
+ -if @snippet.errors.any?
+ .alert-message.block-message.error
+ %ul
+ - @snippet.errors.full_messages.each do |msg|
+ %li= msg
- .clearfix
- = f.label :title
- .input= f.text_field :title, placeholder: "Example Snippet"
- .clearfix
- = f.label :file_name
- .input= f.text_field :file_name, placeholder: "example.rb"
- .clearfix
- = f.label "Lifetime"
- .input= f.select :expires_at, lifetime_select_options, {}, {class: 'chosen span2'}
- .clearfix
- = f.label :content, "Code"
- .input= f.text_area :content, class: "span8"
+ .clearfix
+ = f.label :title
+ .input= f.text_field :title, placeholder: "Example Snippet", class: 'input-xlarge', required: true
+ .clearfix
+ = f.label "Lifetime"
+ .input= f.select :expires_at, lifetime_select_options, {}, {class: 'chosen span2'}
+ .clearfix
+ .file-editor
+ = f.label :file_name, "File"
+ .input
+ .file_holder.snippet
+ .file_title
+ = f.text_field :file_name, placeholder: "example.rb", class: 'snippet-file-name', required: true
+ .file_content.code
+ %pre#editor= @snippet.content
+ = f.hidden_field :content, class: 'snippet-file-content'
+
+ .form-actions
+ = f.submit 'Save', class: "save-btn btn"
+ = link_to "Cancel", project_snippets_path(@project), class: " btn"
+ - unless @snippet.new_record?
+ .right= link_to 'Destroy', [@project, @snippet], confirm: 'Are you sure?', method: :delete, class: "btn right danger delete-snippet", id: "destroy_snippet_#{@snippet.id}"
+
+
+:javascript
+ var editor = ace.edit("editor");
+ $(".snippet-form-holder form").submit(function(){
+ $(".snippet-file-content").val(editor.getValue());
+ });
- .form-actions
- = f.submit 'Save', class: "primary btn"
- = link_to "Cancel", project_snippets_path(@project), class: " btn"
- - unless @snippet.new_record?
- .right= link_to 'Destroy', [@project, @snippet], confirm: 'Are you sure?', method: :delete, class: "btn right danger delete-snippet", id: "destroy_snippet_#{@snippet.id}"
diff --git a/app/views/snippets/_snippet.html.haml b/app/views/snippets/_snippet.html.haml
index a2d3a65e6cb..a576500c15d 100644
--- a/app/views/snippets/_snippet.html.haml
+++ b/app/views/snippets/_snippet.html.haml
@@ -1,12 +1,13 @@
%tr
%td
+ = image_tag gravatar_icon(snippet.author_email), class: "avatar s24"
%a{href: project_snippet_path(snippet.project, snippet)}
%strong= truncate(snippet.title, length: 60)
%td
= snippet.file_name
%td
%span.cgray
- - if snippet.expires_at
+ - if snippet.expires_at
= snippet.expires_at.to_date.to_s(:short)
- else
Never
diff --git a/app/views/snippets/index.html.haml b/app/views/snippets/index.html.haml
index 515daec6207..7b8f94de7dd 100644
--- a/app/views/snippets/index.html.haml
+++ b/app/views/snippets/index.html.haml
@@ -1,21 +1,21 @@
= render "projects/project_head"
-- if can? current_user, :write_snippet, @project
- .alert-message.block-message
+%h3.page_title
+ Snippets
+ %small share code pastes with others out of git repository
+
+ - if can? current_user, :write_snippet, @project
= link_to new_project_snippet_path(@project), class: "btn small add_new right", title: "New Snippet" do
Add new snippet
- Share code pastes with others if it can't be in a git repository
- %br
- To add new snippet - click on button.
-
+%br
%table
%thead
%tr
%th Title
%th File Name
%th Expires At
- = render @snippets.fresh
- - if @snippets.fresh.empty?
+ = render @snippets
+ - if @snippets.empty?
%tr
%td{colspan: 3}
%h3.nothing_here_message Nothing here.
diff --git a/app/views/snippets/show.html.haml b/app/views/snippets/show.html.haml
index f3e01928077..ad399533a3d 100644
--- a/app/views/snippets/show.html.haml
+++ b/app/views/snippets/show.html.haml
@@ -1,6 +1,6 @@
= render "projects/project_head"
-%h3
+%h3.page_title
= @snippet.title
%small= @snippet.file_name
- if can?(current_user, :admin_snippet, @project) || @snippet.author == current_user
diff --git a/app/views/team_members/_show.html.haml b/app/views/team_members/_show.html.haml
index 8938c7d8a6d..8082f47fca8 100644
--- a/app/views/team_members/_show.html.haml
+++ b/app/views/team_members/_show.html.haml
@@ -1,6 +1,6 @@
- user = member.user
- allow_admin = can? current_user, :admin_project, @project
-%li.wll{id: dom_id(member), class: "team_member_row user_#{user.id}"}
+%li{id: dom_id(member), class: "team_member_row user_#{user.id}"}
.row
.span6
= link_to project_team_member_path(@project, member), title: user.name, class: "dark" do
diff --git a/app/views/team_members/_team.html.haml b/app/views/team_members/_team.html.haml
index 65f17864814..462e75af183 100644
--- a/app/views/team_members/_team.html.haml
+++ b/app/views/team_members/_team.html.haml
@@ -1,10 +1,10 @@
- grouper_project_members(@project).each do |access, members|
- %fieldset
- %legend
+ .ui-box
+ %h5
= Project.access_options.key(access).pluralize
%small= members.size
- %ul.unstyled
- - members.each do |up|
+ %ul.well-list
+ - members.sort_by(&:user_name).each do |up|
= render(partial: 'team_members/show', locals: {member: up})
diff --git a/app/views/team_members/show.html.haml b/app/views/team_members/show.html.haml
index 9d03cd2cb1f..af9a6e6b92d 100644
--- a/app/views/team_members/show.html.haml
+++ b/app/views/team_members/show.html.haml
@@ -6,7 +6,7 @@
= link_to 'Remove from team', project_team_member_path(project_id: @project, id: @team_member.id), confirm: 'Are you sure?', method: :delete, class: "right btn danger"
.profile_avatar_holder
= image_tag gravatar_icon(user.email, 60), class: "borders"
- %h3
+ %h3.page_title
= user.name
%small
= user.email
diff --git a/app/views/tree/_tree.html.haml b/app/views/tree/_tree.html.haml
index 02ae3d90c40..a632bb3b0d7 100644
--- a/app/views/tree/_tree.html.haml
+++ b/app/views/tree/_tree.html.haml
@@ -16,10 +16,11 @@
- else
%table#tree-slider{class: "table_#{@hex_path} tree-table" }
%thead
- %th Name
- %th Last Update
- %th Last Commit
- %th= link_to "history", project_commits_path(@project, @id), class: "btn very_small right"
+ %tr
+ %th Name
+ %th Last Update
+ %th Last Commit
+ %th= link_to "history", project_commits_path(@project, @id), class: "btn very_small right"
- if tree.up_dir?
%tr.tree-item
diff --git a/app/workers/post_receive.rb b/app/workers/post_receive.rb
index 4f4f69c4ece..1414ed490c9 100644
--- a/app/workers/post_receive.rb
+++ b/app/workers/post_receive.rb
@@ -1,12 +1,16 @@
class PostReceive
@queue = :post_receive
- def self.perform(reponame, oldrev, newrev, ref, identifier)
- project = Project.find_by_path(reponame)
+ def self.perform(repo_path, oldrev, newrev, ref, identifier)
+ repo_path.gsub!(Gitlab.config.gitolite.repos_path.to_s, "")
+ repo_path.gsub!(/.git$/, "")
+ repo_path.gsub!(/^\//, "")
+
+ project = Project.find_with_namespace(repo_path)
return false if project.nil?
# Ignore push from non-gitlab users
- user = if identifier.eql? Gitlab.config.gitolite_admin_key
+ user = if identifier.eql? Gitlab.config.gitolite.admin_key
email = project.commit(newrev).author.email rescue nil
User.find_by_email(email) if email
elsif /^[A-Z0-9._%a-z\-]+@(?:[A-Z0-9a-z\-]+\.)+[A-Za-z]{2,4}$/.match(identifier)
diff --git a/config/database.yml.example b/config/database.yml.example
deleted file mode 100644
index c5a2b8d605b..00000000000
--- a/config/database.yml.example
+++ /dev/null
@@ -1,39 +0,0 @@
-#
-# PRODUCTION
-#
-production:
- adapter: mysql2
- encoding: utf8
- reconnect: false
- database: gitlabhq_production
- pool: 5
- username: root
- password: "secure password"
- # host: localhost
- # socket: /tmp/mysql.sock
-
-#
-# Development specific
-#
-development:
- adapter: mysql2
- encoding: utf8
- reconnect: false
- database: gitlabhq_development
- pool: 5
- username: root
- password: "secure password"
- # socket: /tmp/mysql.sock
-
-# Warning: The database defined as "test" will be erased and
-# re-generated from your development database when you run "rake".
-# Do not set this db to the same as development or production.
-test: &test
- adapter: mysql2
- encoding: utf8
- reconnect: false
- database: gitlabhq_test
- pool: 5
- username: root
- password: "secure password"
- # socket: /tmp/mysql.sock
diff --git a/config/database.yml.postgresql b/config/database.yml.postgresql
index 17b38f3d385..0e873d2b8fb 100644
--- a/config/database.yml.postgresql
+++ b/config/database.yml.postgresql
@@ -9,6 +9,7 @@ production:
username: postgres
password:
# host: localhost
+ # port: 5432
# socket: /tmp/postgresql.sock
#
diff --git a/config/gitlab.yml.example b/config/gitlab.yml.example
index 7fcfc5b7cf3..067dbd9b72b 100644
--- a/config/gitlab.yml.example
+++ b/config/gitlab.yml.example
@@ -1,57 +1,65 @@
-# # # # # # # # # # # # # # # # # #
+# # # # # # # # # # # # # # # # # #
# Gitlab application config file #
# # # # # # # # # # # # # # # # # #
#
-# 1. Common settings
+# 1. GitLab app settings
# ==========================
-# Web application specific settings
-web:
+## GitLab settings
+gitlab:
+ ## Web server settings
host: localhost
port: 80
https: false
-# Email used for notification
-# about new issues, comments
-email:
- from: notify@localhost
+ ## Email settings
+ # Email address used in the "From" field in mails sent by GitLab
+ email_from: gitlab@localhost
-# Application specific settings
-# Like default project limit for user etc
-app:
+ ## Project settings
default_projects_limit: 10
- # backup_path: "/vol/backups" # default: Rails.root + backups/
- # backup_keep_time: 604800 # default: 0 (forever) (in seconds)
- # disable_gravatar: true # default: false - Disable user avatars from Gravatar.com
- # gravatar_url: "http://" # default: http://www.gravatar.com/avatar/%{hash}?s=%{size}&d=mm
- # gravatar_ssl_url: "https://" # default: https://secure.gravatar.com/avatar/%{hash}?s=%{size}&d=mm
+
+## Gravatar
+gravatar:
+ enabled: true # Use user avatar images from Gravatar.com (default: true)
+ # plain_url: "http://..." # default: http://www.gravatar.com/avatar/%{hash}?s=%{size}&d=mm
+ # ssl_url: "https://..." # default: https://secure.gravatar.com/avatar/%{hash}?s=%{size}&d=mm
+
#
# 2. Auth settings
# ==========================
-ldap:
+
+## LDAP settings
+ldap:
enabled: false
host: '_your_ldap_server'
base: '_the_base_where_you_search_for_users'
port: 636
uid: 'sAMAccountName'
- method: 'ssl' # plain
+ method: 'ssl' # "ssl" or "plain"
bind_dn: '_the_full_dn_of_the_user_you_will_bind_with'
password: '_the_password_of_the_bind_user'
+## Omniauth settings
omniauth:
# Enable ability for users
- # to login via twitter, google ..
+ # Allow logging in via Twitter, Google, etc. using Omniauth providers
enabled: false
- # IMPORTANT!
- # It allows user to login without having user account
+ # CAUTION!
+ # This allows users to login without having a user account first (default: false)
+ # User accounts will be created automatically when authentication was successful.
allow_single_sign_on: false
+ # Locks down those users until they have been cleared by the admin (default: true)
block_auto_created_users: true
- # Auth providers
+ ## Auth providers
+ # Uncomment the lines and fill in the data of the auth provider you want to use
+ # If your favorite auth provider is not listed you can user others:
+ # see https://github.com/gitlabhq/gitlabhq/wiki/Using-Custom-Omniauth-Providers
providers:
# - { name: 'google_oauth2', app_id: 'YOUR APP ID',
# app_secret: 'YOUR APP SECRET',
@@ -62,29 +70,36 @@ omniauth:
# app_secret: 'YOUR APP SECRET' }
+
#
-# 3. Advanced settings:
+# 3. Advanced settings
# ==========================
-# Git Hosting configuration
-git_host:
+## Backup settings
+backup:
+ path: "tmp/backups" # Relative paths are relative to Rails.root (default: tmp/backups/)
+ # keep_time: 604800 # default: 0 (forever) (in seconds)
+
+## Gitolite settings
+gitolite:
admin_uri: git@localhost:gitolite-admin
- base_path: /home/git/repositories/
+ repos_path: /home/git/repositories/
hooks_path: /home/git/.gitolite/hooks/
- gitolite_admin_key: gitlab
- git_user: git
+ admin_key: gitlab
upload_pack: true
receive_pack: true
- # host: localhost
+ ssh_user: git
+ ssh_host: localhost
+ # ssh_port: 22
# config_file: gitolite.conf
- # port: 22
-# Git settings
-# Use default values unless you understand it
+## Git settings
+# CAUTION!
+# Use the default values unless you really know what you are doing
git:
- path: /usr/bin/git
+ bin_path: /usr/bin/git
# Max size of git object like commit, in bytes
# This value can be increased if you have a very large commits
- git_max_size: 5242880 # 5.megabytes
+ max_size: 5242880 # 5.megabytes
# Git timeout to read commit, in seconds
- git_timeout: 10
+ timeout: 10
diff --git a/config/initializers/1_settings.rb b/config/initializers/1_settings.rb
index e684f37857d..4fe3ced4d8d 100644
--- a/config/initializers/1_settings.rb
+++ b/config/initializers/1_settings.rb
@@ -2,23 +2,43 @@ class Settings < Settingslogic
source "#{Rails.root}/config/gitlab.yml"
class << self
+ # FIXME: Deprecated: remove for 4.1
def web_protocol
+ ActiveSupport::Deprecation.warn("Settings.web_protocol is deprecated and will be removed from GitLab 4.1", caller)
+ gitlab.protocol
+ rescue Settingslogic::MissingSetting
self.web['protocol'] ||= web.https ? "https" : "http"
end
+ # FIXME: Deprecated: remove for 4.1
def web_host
+ ActiveSupport::Deprecation.warn("Settings.web_host is deprecated and will be removed from GitLab 4.1", caller)
+ gitlab.host
+ rescue Settingslogic::MissingSetting
self.web['host'] ||= 'localhost'
end
+ # FIXME: Deprecated: remove for 4.1
def email_from
+ ActiveSupport::Deprecation.warn("Settings.email_from is deprecated and will be removed from GitLab 4.1", caller)
+ gitlab.email_from
+ rescue Settingslogic::MissingSetting
self.email['from'] ||= ("notify@" + web_host)
end
+ # FIXME: Deprecated: remove for 4.1
def url
+ ActiveSupport::Deprecation.warn("Settings.url is deprecated and will be removed from GitLab 4.1", caller)
+ gitlab.url
+ rescue Settingslogic::MissingSetting
self['url'] ||= build_url
end
+ # FIXME: Deprecated: remove for 4.1
def web_port
+ ActiveSupport::Deprecation.warn("Settings.web_port is deprecated and will be removed from GitLab 4.1", caller)
+ gitlab.port.to_i
+ rescue Settingslogic::MissingSetting
if web.https
web['port'] = 443
else
@@ -26,11 +46,17 @@ class Settings < Settingslogic
end.to_i
end
+ # FIXME: Deprecated: remove for 4.1
def web_custom_port?
+ ActiveSupport::Deprecation.warn("Settings.web_custom_port? is deprecated and will be removed from GitLab 4.1", caller)
+ gitlab_on_non_standard_port?
+ rescue Settingslogic::MissingSetting
![443, 80].include?(web_port)
end
+ # FIXME: Deprecated: remove for 4.1
def build_url
+ ActiveSupport::Deprecation.warn("Settings.build_url is deprecated and will be removed from GitLab 4.1", caller)
if web_custom_port?
custom_port = ":#{web_port}"
else
@@ -44,19 +70,35 @@ class Settings < Settingslogic
].join('')
end
+ # FIXME: Deprecated: remove for 4.1
def ssh_port
+ ActiveSupport::Deprecation.warn("Settings.ssh_port is deprecated and will be removed from GitLab 4.1", caller)
+ gitolite.ssh_port
+ rescue Settingslogic::MissingSetting
git_host['port'] || 22
end
+ # FIXME: Deprecated: remove for 4.1
def ssh_user
+ ActiveSupport::Deprecation.warn("Settings.ssh_user is deprecated and will be removed from GitLab 4.1", caller)
+ gitolite.ssh_user
+ rescue Settingslogic::MissingSetting
git_host['git_user'] || 'git'
end
+ # FIXME: Deprecated: remove for 4.1
def ssh_host
+ ActiveSupport::Deprecation.warn("Settings.ssh_host is deprecated and will be removed from GitLab 4.1", caller)
+ gitolite.ssh_host
+ rescue Settingslogic::MissingSetting
git_host['host'] || web_host || 'localhost'
end
+ # FIXME: Deprecated: remove for 4.1
def ssh_path
+ ActiveSupport::Deprecation.warn("Settings.ssh_path is deprecated and will be removed from GitLab 4.1", caller)
+ gitolite.ssh_path_prefix
+ rescue Settingslogic::MissingSetting
if ssh_port != 22
"ssh://#{ssh_user}@#{ssh_host}:#{ssh_port}/"
else
@@ -64,15 +106,27 @@ class Settings < Settingslogic
end
end
+ # FIXME: Deprecated: remove for 4.1
def git_base_path
+ ActiveSupport::Deprecation.warn("Settings.git_base_path is deprecated and will be removed from GitLab 4.1", caller)
+ gitolite.repos_path
+ rescue Settingslogic::MissingSetting
git_host['base_path'] || '/home/git/repositories/'
end
+ # FIXME: Deprecated: remove for 4.1
def git_hooks_path
+ ActiveSupport::Deprecation.warn("Settings.git_hooks_path is deprecated and will be removed from GitLab 4.1", caller)
+ gitolite.hooks_path
+ rescue Settingslogic::MissingSetting
git_host['hooks_path'] || '/home/git/share/gitolite/hooks/'
end
+ # FIXME: Deprecated: remove for 4.1
def git_upload_pack
+ ActiveSupport::Deprecation.warn("Settings.git_upload_pack is deprecated and will be removed from GitLab 4.1", caller)
+ gitolite.upload_pack
+ rescue Settingslogic::MissingSetting
if git_host['upload_pack'] != false
true
else
@@ -80,7 +134,11 @@ class Settings < Settingslogic
end
end
+ # FIXME: Deprecated: remove for 4.1
def git_receive_pack
+ ActiveSupport::Deprecation.warn("Settings.git_receive_pack is deprecated and will be removed from GitLab 4.1", caller)
+ gitolite.receive_pack
+ rescue Settingslogic::MissingSetting
if git_host['receive_pack'] != false
true
else
@@ -88,71 +146,207 @@ class Settings < Settingslogic
end
end
+ # FIXME: Deprecated: remove for 4.1
def git_bin_path
+ ActiveSupport::Deprecation.warn("Settings.git_bin_path is deprecated and will be removed from GitLab 4.1", caller)
+ git.bin_path
+ rescue Settingslogic::MissingSetting
git['path'] || '/usr/bin/git'
end
+ # FIXME: Deprecated: remove for 4.1
def git_max_size
+ ActiveSupport::Deprecation.warn("Settings.git_max_size is deprecated and will be removed from GitLab 4.1", caller)
+ git.max_size
+ rescue Settingslogic::MissingSetting
git['git_max_size'] || 5242880 # 5.megabytes
end
+ # FIXME: Deprecated: remove for 4.1
def git_timeout
+ ActiveSupport::Deprecation.warn("Settings.git_timeout is deprecated and will be removed from GitLab 4.1", caller)
+ git.timeout
+ rescue Settingslogic::MissingSetting
git['git_timeout'] || 10
end
+ # FIXME: Deprecated: remove for 4.1
def gitolite_admin_uri
+ ActiveSupport::Deprecation.warn("Settings.gitolite_admin_uri is deprecated and will be removed from GitLab 4.1", caller)
+ gitolite.admin_uri
+ rescue Settingslogic::MissingSetting
git_host['admin_uri'] || 'git@localhost:gitolite-admin'
end
+ # FIXME: Deprecated: remove for 4.1
def gitolite_config_file
+ ActiveSupport::Deprecation.warn("Settings.gitolite_config_file is deprecated and will be removed from GitLab 4.1", caller)
+ gitolite.config_file
+ rescue Settingslogic::MissingSetting
git_host['config_file'] || 'gitolite.conf'
end
+ # FIXME: Deprecated: remove for 4.1
def gitolite_admin_key
+ ActiveSupport::Deprecation.warn("Settings.gitolite_admin_key is deprecated and will be removed from GitLab 4.1", caller)
+ gitolite.admin_key
+ rescue Settingslogic::MissingSetting
git_host['gitolite_admin_key'] || 'gitlab'
end
+ # FIXME: Deprecated: remove for 4.1
def default_projects_limit
+ ActiveSupport::Deprecation.warn("Settings.default_projects_limit is deprecated and will be removed from GitLab 4.1", caller)
+ gitlab.default_projects_limit
+ rescue Settingslogic::MissingSetting
app['default_projects_limit'] || 10
end
+ # FIXME: Deprecated: remove for 4.1
def backup_path
- t = app['backup_path'] || "backups/"
- t = /^\//.match(t) ? t : Rails.root .join(t)
- t
+ ActiveSupport::Deprecation.warn("Settings.backup_path is deprecated and will be removed from GitLab 4.1", caller)
+ backup.path
+ rescue Settingslogic::MissingSetting
+ File.expand_path(app['backup_path'] || "backups/", Rails.root)
end
+ # FIXME: Deprecated: remove for 4.1
def backup_keep_time
+ ActiveSupport::Deprecation.warn("Settings.backup_keep_time is deprecated and will be removed from GitLab 4.1", caller)
+ backup.keep_time
+ rescue Settingslogic::MissingSetting
app['backup_keep_time'] || 0
end
+ # FIXME: Deprecated: remove for 4.1
def ldap_enabled?
- ldap && ldap['enabled']
+ ActiveSupport::Deprecation.warn("Settings.ldap_enabled? is deprecated and will be removed from GitLab 4.1", caller)
+ ldap.enabled
rescue Settingslogic::MissingSetting
false
end
+ # FIXME: Deprecated: remove for 4.1
def omniauth_enabled?
- omniauth && omniauth['enabled']
+ ActiveSupport::Deprecation.warn("Settings.omniauth_enabled? is deprecated and will be removed from GitLab 4.1", caller)
+ omniauth.enabled
rescue Settingslogic::MissingSetting
false
end
+ # FIXME: Deprecated: remove for 4.1
def omniauth_providers
- (omniauth_enabled? && omniauth['providers']) || []
+ ActiveSupport::Deprecation.warn("Settings.omniauth_providers is deprecated and will be removed from GitLab 4.1", caller)
+ omniauth.providers
+ rescue Settingslogic::MissingSetting
+ []
end
+ # FIXME: Deprecated: remove for 4.1
def disable_gravatar?
+ ActiveSupport::Deprecation.warn("Settings.disable_gravatar? is deprecated and will be removed from GitLab 4.1", caller)
+ !gravatar.enabled
+ rescue Settingslogic::MissingSetting
app['disable_gravatar'] || false
end
+ # FIXME: Deprecated: remove for 4.1
def gravatar_url
+ ActiveSupport::Deprecation.warn("Settings.gravatar_url is deprecated and will be removed from GitLab 4.1", caller)
+ gravatar.plain_url
+ rescue Settingslogic::MissingSetting
app['gravatar_url'] || 'http://www.gravatar.com/avatar/%{hash}?s=%{size}&d=mm'
end
+ # FIXME: Deprecated: remove for 4.1
def gravatar_ssl_url
+ ActiveSupport::Deprecation.warn("Settings.gravatar_ssl_url is deprecated and will be removed from GitLab 4.1", caller)
+ gravatar.ssl_url
+ rescue Settingslogic::MissingSetting
app['gravatar_ssl_url'] || 'https://secure.gravatar.com/avatar/%{hash}?s=%{size}&d=mm'
end
+
+
+ def gitlab_on_non_standard_port?
+ ![443, 80].include?(gitlab.port.to_i)
+ end
+
+ private
+
+ def build_gitolite_ssh_path_prefix
+ if gitolite.ssh_port != 22
+ "ssh://#{gitolite.ssh_user}@#{gitolite.ssh_host}:#{gitolite.ssh_port}/"
+ else
+ "#{gitolite.ssh_user}@#{gitolite.ssh_host}:"
+ end
+ end
+
+ def build_gitlab_url
+ if gitlab_on_non_standard_port?
+ custom_port = ":#{gitlab.port}"
+ else
+ custom_port = nil
+ end
+ [ gitlab.protocol,
+ "://",
+ gitlab.host,
+ custom_port
+ ].join('')
+ end
end
end
+
+
+# Default settings
+
+# FIXME: Deprecated: remove for 4.1
+# all Settings.web ...
+# all Settings.app ...
+# all Settings.email ...
+# all Settings.git_host ...
+Settings['pre_40_config'] ||= Settings['web'].present?
+
+Settings['ldap'] ||= Settingslogic.new({})
+Settings.ldap['enabled'] ||= false
+
+Settings['omniauth'] ||= Settingslogic.new({})
+Settings.omniauth['enabled'] ||= false
+Settings.omniauth['providers'] ||= []
+
+Settings['gitlab'] ||= Settingslogic.new({})
+Settings.gitlab['default_projects_limit'] ||= Settings.pre_40_config ? Settings.default_projects_limit : 10
+Settings.gitlab['host'] ||= Settings.pre_40_config ? Settings.web_host : 'localhost'
+Settings.gitlab['https'] ||= Settings.pre_40_config ? Settings.web.https : false
+Settings.gitlab['port'] ||= Settings.gitlab.https ? 443 : 80
+Settings.gitlab['protocol'] ||= Settings.gitlab.https ? "https" : "http"
+Settings.gitlab['email_from'] ||= Settings.pre_40_config ? Settings.email_from : "gitlab@#{Settings.gitlab.host}"
+Settings.gitlab['url'] ||= Settings.pre_40_config ? Settings.url : Settings.send(:build_gitlab_url)
+
+Settings['gravatar'] ||= Settingslogic.new({})
+Settings.gravatar['enabled'] ||= Settings.pre_40_config ? !Settings.disable_gravatar? : true
+Settings.gravatar['plain_url'] ||= Settings.pre_40_config ? Settings.gravatar_url : 'http://www.gravatar.com/avatar/%{hash}?s=%{size}&d=mm'
+Settings.gravatar['ssl_url'] ||= Settings.pre_40_config ? Settings.gravatar_ssl_url : 'https://secure.gravatar.com/avatar/%{hash}?s=%{size}&d=mm'
+
+Settings['gitolite'] ||= Settingslogic.new({})
+Settings.gitolite['admin_key'] ||= Settings.pre_40_config ? Settings.gitolite_admin_key : 'gitlab'
+Settings.gitolite['admin_uri'] ||= Settings.pre_40_config ? Settings.gitolite_admin_uri : 'git@localhost:gitolite-admin'
+Settings.gitolite['config_file'] ||= Settings.pre_40_config ? Settings.gitolite_config_file : 'gitolite.conf'
+Settings.gitolite['hooks_path'] ||= Settings.pre_40_config ? Settings.git_hooks_path : '/home/git/share/gitolite/hooks/'
+Settings.gitolite['receive_pack'] ||= Settings.pre_40_config ? Settings.git_receive_pack : (Settings.gitolite['receive_pack'] != false)
+Settings.gitolite['repos_path'] ||= Settings.pre_40_config ? Settings.git_base_path : '/home/git/repositories/'
+Settings.gitolite['upload_pack'] ||= Settings.pre_40_config ? Settings.git_upload_pack : (Settings.gitolite['upload_pack'] != false)
+Settings.gitolite['ssh_host'] ||= Settings.pre_40_config ? Settings.ssh_host : (Settings.gitlab.host || 'localhost')
+Settings.gitolite['ssh_port'] ||= Settings.pre_40_config ? Settings.ssh_port : 22
+Settings.gitolite['ssh_user'] ||= Settings.pre_40_config ? Settings.ssh_user : 'git'
+Settings.gitolite['ssh_path_prefix'] ||= Settings.pre_40_config ? Settings.ssh_path : Settings.send(:build_gitolite_ssh_path_prefix)
+
+Settings['backup'] ||= Settingslogic.new({})
+Settings.backup['keep_time'] ||= Settings.pre_40_config ? Settings.backup_keep_time : 0
+Settings.backup['path'] = Settings.pre_40_config ? Settings.backup_path : File.expand_path(Settings.backup['path'] || "tmp/backups/", Rails.root)
+
+Settings['git'] ||= Settingslogic.new({})
+Settings.git['max_size'] ||= Settings.pre_40_config ? Settings.git_max_size : 5242880 # 5.megabytes
+Settings.git['bin_path'] ||= Settings.pre_40_config ? Settings.git_bin_path : '/usr/bin/git'
+Settings.git['timeout'] ||= Settings.pre_40_config ? Settings.git_timeout : 10
+Settings.git['path'] ||= Settings.git.bin_path # FIXME: Deprecated: remove for 4.1
diff --git a/config/initializers/3_grit_ext.rb b/config/initializers/3_grit_ext.rb
index d114ea6cc8b..097c301a06a 100644
--- a/config/initializers/3_grit_ext.rb
+++ b/config/initializers/3_grit_ext.rb
@@ -1,8 +1,8 @@
require 'grit'
require 'pygments'
-Grit::Git.git_timeout = Gitlab.config.git_timeout
-Grit::Git.git_max_size = Gitlab.config.git_max_size
+Grit::Git.git_timeout = Gitlab.config.git.timeout
+Grit::Git.git_max_size = Gitlab.config.git.max_size
Grit::Blob.class_eval do
include Linguist::BlobHelper
diff --git a/config/initializers/devise.rb b/config/initializers/devise.rb
index 8f3cef5a2ac..ed3ab71862a 100644
--- a/config/initializers/devise.rb
+++ b/config/initializers/devise.rb
@@ -4,7 +4,7 @@ Devise.setup do |config|
# ==> Mailer Configuration
# Configure the e-mail address which will be shown in Devise::Mailer,
# note that it will be overwritten if you use your own mailer class with default "from" parameter.
- config.mailer_sender = Gitlab.config.email_from
+ config.mailer_sender = Gitlab.config.gitlab.email_from
# Configure the class responsible to send e-mails.
# config.mailer = "Devise::Mailer"
@@ -205,20 +205,18 @@ Devise.setup do |config|
# manager.default_strategies(:scope => :user).unshift :some_external_strategy
# end
- gl = Gitlab.config
-
- if gl.ldap_enabled?
+ if Gitlab.config.ldap.enabled
config.omniauth :ldap,
- :host => gl.ldap['host'],
- :base => gl.ldap['base'],
- :uid => gl.ldap['uid'],
- :port => gl.ldap['port'],
- :method => gl.ldap['method'],
- :bind_dn => gl.ldap['bind_dn'],
- :password => gl.ldap['password']
+ :host => Gitlab.config.ldap['host'],
+ :base => Gitlab.config.ldap['base'],
+ :uid => Gitlab.config.ldap['uid'],
+ :port => Gitlab.config.ldap['port'],
+ :method => Gitlab.config.ldap['method'],
+ :bind_dn => Gitlab.config.ldap['bind_dn'],
+ :password => Gitlab.config.ldap['password']
end
- gl.omniauth_providers.each do |gl_provider|
- config.omniauth gl_provider['name'].to_sym, gl_provider['app_id'], gl_provider['app_secret']
+ Gitlab.config.omniauth.providers.each do |provider|
+ config.omniauth provider['name'].to_sym, provider['app_id'], provider['app_secret']
end
end
diff --git a/config/routes.rb b/config/routes.rb
index f1527977c09..e08bfebc020 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -14,10 +14,10 @@ Gitlab::Application.routes.draw do
# Enable Grack support
mount Grack::Bundle.new({
- git_path: Gitlab.config.git_bin_path,
- project_root: Gitlab.config.git_base_path,
- upload_pack: Gitlab.config.git_upload_pack,
- receive_pack: Gitlab.config.git_receive_pack
+ git_path: Gitlab.config.git.bin_path,
+ project_root: Gitlab.config.gitolite.repos_path,
+ upload_pack: Gitlab.config.gitolite.upload_pack,
+ receive_pack: Gitlab.config.gitolite.receive_pack
}), at: '/:path', constraints: { path: /[-\/\w\.-]+\.git/ }
#
@@ -164,11 +164,12 @@ Gitlab::Application.routes.draw do
end
end
- resources :merge_requests, constraints: {id: /\d+/} do
+ resources :merge_requests, constraints: {id: /\d+/}, except: [:destroy] do
member do
get :diffs
get :automerge
get :automerge_check
+ get :ci_status
end
collection do
@@ -199,9 +200,9 @@ Gitlab::Application.routes.draw do
:via => [:get, :post], constraints: {from: /.+/, to: /.+/}
resources :team, controller: 'team_members', only: [:index]
- resources :milestones
+ resources :milestones, except: [:destroy]
resources :labels, only: [:index]
- resources :issues do
+ resources :issues, except: [:destroy] do
collection do
post :sort
post :bulk_update
diff --git a/db/fixtures/development/002_project.rb b/db/fixtures/development/002_project.rb
index 91d42a14201..4db11a878ec 100644
--- a/db/fixtures/development/002_project.rb
+++ b/db/fixtures/development/002_project.rb
@@ -1,5 +1,14 @@
+Group.seed(:id, [
+ { id: 100, name: "Brightbox", path: 'brightbox', owner_id: 1 },
+ { id: 101, name: "KDE", path: 'kde', owner_id: 1 },
+])
+
Project.seed(:id, [
- { id: 1, name: "Underscore.js", path: "underscore", owner_id: 1, namespace_id: 1 },
+ { id: 1, name: "Underscore.js", path: "underscore", owner_id: 1 },
{ id: 2, name: "Diaspora", path: "diaspora", owner_id: 1 },
- { id: 3, name: "Ruby on Rails", path: "rails", owner_id: 1 }
+ { id: 3, namespace_id: 100, name: "Brightbox CLI", path: "brightbox-cli", owner_id: 1 },
+ { id: 4, namespace_id: 100, name: "Puppet", path: "puppet", owner_id: 1 },
+ { id: 5, namespace_id: 101, name: "kdebase", path: "kdebase", owner_id: 1},
+ { id: 6, namespace_id: 101, name: "kdelibs", path: "kdelibs", owner_id: 1},
+ { id: 7, namespace_id: 101, name: "amarok", path: "amarok", owner_id: 1},
])
diff --git a/db/fixtures/development/009_source_code.rb b/db/fixtures/development/009_source_code.rb
index 849d1aab8ae..6b9b6584a58 100644
--- a/db/fixtures/development/009_source_code.rb
+++ b/db/fixtures/development/009_source_code.rb
@@ -1,9 +1,10 @@
root = Gitlab.config.git_base_path
projects = [
- { path: 'root/underscore.git', git: 'https://github.com/documentcloud/underscore.git' },
+ { path: 'underscore.git', git: 'https://github.com/documentcloud/underscore.git' },
{ path: 'diaspora.git', git: 'https://github.com/diaspora/diaspora.git' },
- { path: 'rails.git', git: 'https://github.com/rails/rails.git' },
+ { path: 'brightbox/brightbox-cli.git', git: 'https://github.com/brightbox/brightbox-cli.git' },
+ { path: 'brightbox/puppet.git', git: 'https://github.com/brightbox/puppet.git' },
]
projects.each do |project|
@@ -14,7 +15,7 @@ projects.each do |project|
cmds = [
"cd #{root} && sudo -u git -H git clone --bare #{project[:git]} ./#{project[:path]}",
- "sudo cp ./lib/hooks/post-receive #{project_path}/hooks/post-receive",
+ "sudo ln -s ./lib/hooks/post-receive #{project_path}/hooks/post-receive",
"sudo chown git:git -R #{project_path}",
"sudo chmod 770 -R #{project_path}",
]
diff --git a/db/fixtures/development/010_groups.rb b/db/fixtures/development/010_groups.rb
deleted file mode 100644
index 09371b00751..00000000000
--- a/db/fixtures/development/010_groups.rb
+++ /dev/null
@@ -1,11 +0,0 @@
-Group.seed(:id, [
- { id: 100, name: "Gitlab", path: 'gitlab', owner_id: 1},
- { id: 101, name: "Rails", path: 'rails', owner_id: 1 },
- { id: 102, name: "KDE", path: 'kde', owner_id: 1 }
-])
-
-Project.seed(:id, [
- { id: 10, name: "kdebase", path: "kdebase", owner_id: 1, namespace_id: 102 },
- { id: 11, name: "kdelibs", path: "kdelibs", owner_id: 1, namespace_id: 102 },
- { id: 12, name: "amarok", path: "amarok", owner_id: 1, namespace_id: 102 }
-])
diff --git a/db/migrate/20121218164840_move_noteable_commit_to_own_field.rb b/db/migrate/20121218164840_move_noteable_commit_to_own_field.rb
new file mode 100644
index 00000000000..6f2da4136a3
--- /dev/null
+++ b/db/migrate/20121218164840_move_noteable_commit_to_own_field.rb
@@ -0,0 +1,20 @@
+class MoveNoteableCommitToOwnField < ActiveRecord::Migration
+ def up
+ add_column :notes, :commit_id, :string, null: true
+ add_column :notes, :new_noteable_id, :integer, null: true
+ Note.where(noteable_type: 'Commit').update_all('commit_id = noteable_id')
+
+ if ActiveRecord::Base.connection.adapter_name == 'PostgreSQL'
+ Note.where("noteable_type != 'Commit'").update_all('new_noteable_id = CAST (noteable_id AS INTEGER)')
+ else
+ Note.where("noteable_type != 'Commit'").update_all('new_noteable_id = noteable_id')
+ end
+
+ remove_column :notes, :noteable_id
+ rename_column :notes, :new_noteable_id, :noteable_id
+ end
+
+ def down
+ raise ActiveRecord::IrreversibleMigration
+ end
+end
diff --git a/db/migrate/20121219095402_indices_for_notes.rb b/db/migrate/20121219095402_indices_for_notes.rb
new file mode 100644
index 00000000000..4c5d041ce81
--- /dev/null
+++ b/db/migrate/20121219095402_indices_for_notes.rb
@@ -0,0 +1,6 @@
+class IndicesForNotes < ActiveRecord::Migration
+ def change
+ add_index :notes, :commit_id
+ add_index :notes, [:project_id, :noteable_type]
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index 923d2c5543e..7de5593285a 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -11,7 +11,7 @@
#
# It's strongly recommended to check this file into your version control system.
-ActiveRecord::Schema.define(:version => 20121205201726) do
+ActiveRecord::Schema.define(:version => 20121219095402) do
create_table "events", :force => true do |t|
t.string "target_type"
@@ -124,7 +124,6 @@ ActiveRecord::Schema.define(:version => 20121205201726) do
create_table "notes", :force => true do |t|
t.text "note"
- t.string "noteable_id"
t.string "noteable_type"
t.integer "author_id"
t.datetime "created_at", :null => false
@@ -132,11 +131,14 @@ ActiveRecord::Schema.define(:version => 20121205201726) do
t.integer "project_id"
t.string "attachment"
t.string "line_code"
+ t.string "commit_id"
+ t.integer "noteable_id"
end
+ add_index "notes", ["commit_id"], :name => "index_notes_on_commit_id"
add_index "notes", ["created_at"], :name => "index_notes_on_created_at"
- add_index "notes", ["noteable_id"], :name => "index_notes_on_noteable_id"
add_index "notes", ["noteable_type"], :name => "index_notes_on_noteable_type"
+ add_index "notes", ["project_id", "noteable_type"], :name => "index_notes_on_project_id_and_noteable_type"
add_index "notes", ["project_id"], :name => "index_notes_on_project_id"
create_table "projects", :force => true do |t|
diff --git a/doc/api/issues.md b/doc/api/issues.md
index aaad3305489..b5b5a4eadd4 100644
--- a/doc/api/issues.md
+++ b/doc/api/issues.md
@@ -18,6 +18,7 @@ GET /issues
"assignee": null,
"author": {
"id": 1,
+ "username": "john_smith",
"email": "john@example.com",
"name": "John Smith",
"blocked": false,
@@ -46,6 +47,7 @@ GET /issues
},
"assignee": {
"id": 2,
+ "username": "jack_smith",
"email": "jack@example.com",
"name": "Jack Smith",
"blocked": false,
@@ -53,6 +55,7 @@ GET /issues
},
"author": {
"id": 1,
+ "username": "john_smith",
"email": "john@example.com",
"name": "John Smith",
"blocked": false,
@@ -110,6 +113,7 @@ Parameters:
},
"assignee": {
"id": 2,
+ "username": "jack_smith",
"email": "jack@example.com",
"name": "Jack Smith",
"blocked": false,
@@ -117,6 +121,7 @@ Parameters:
},
"author": {
"id": 1,
+ "username": "john_smith",
"email": "john@example.com",
"name": "John Smith",
"blocked": false,
@@ -168,17 +173,3 @@ Parameters:
Will return updated issue with status `200 OK` on success, or `404 Not found` on fail.
-## Delete issue
-
-Delete existing project issue.
-
-```
-DELETE /projects/:id/issues/:issue_id
-```
-
-Parameters:
-
-+ `id` (required) - The ID or code name of a project
-+ `issue_id` (required) - The ID of a project's issue
-
-Status code `200` will be returned on success.
diff --git a/doc/api/merge_requests.md b/doc/api/merge_requests.md
index e5b067a61d9..86bd79ff43a 100644
--- a/doc/api/merge_requests.md
+++ b/doc/api/merge_requests.md
@@ -22,6 +22,7 @@ Parameters:
"merged":false,
"author":{
"id":1,
+ "username": "admin",
"email":"admin@local.host",
"name":"Administrator",
"blocked":false,
@@ -29,6 +30,7 @@ Parameters:
},
"assignee":{
"id":1,
+ "username": "admin",
"email":"admin@local.host",
"name":"Administrator",
"blocked":false,
@@ -62,6 +64,7 @@ Parameters:
"merged":false,
"author":{
"id":1,
+ "username": "admin",
"email":"admin@local.host",
"name":"Administrator",
"blocked":false,
@@ -69,6 +72,7 @@ Parameters:
},
"assignee":{
"id":1,
+ "username": "admin",
"email":"admin@local.host",
"name":"Administrator",
"blocked":false,
@@ -105,6 +109,7 @@ Parameters:
"merged":false,
"author":{
"id":1,
+ "username": "admin",
"email":"admin@local.host",
"name":"Administrator",
"blocked":false,
@@ -112,6 +117,7 @@ Parameters:
},
"assignee":{
"id":1,
+ "username": "admin",
"email":"admin@local.host",
"name":"Administrator",
"blocked":false,
@@ -150,6 +156,7 @@ Parameters:
"merged":false,
"author":{
"id":1,
+ "username": "admin",
"email":"admin@local.host",
"name":"Administrator",
"blocked":false,
@@ -157,6 +164,7 @@ Parameters:
},
"assignee":{
"id":1,
+ "username": "admin",
"email":"admin@local.host",
"name":"Administrator",
"blocked":false,
@@ -184,6 +192,7 @@ Will return created note with status `201 Created` on success, or `404 Not found
{
"author":{
"id":1,
+ "username": "admin",
"email":"admin@local.host",
"name":"Administrator",
"blocked":false,
diff --git a/doc/api/notes.md b/doc/api/notes.md
index 7b226dea44c..dddb55edb93 100644
--- a/doc/api/notes.md
+++ b/doc/api/notes.md
@@ -15,6 +15,7 @@ GET /projects/:id/notes
"body": "The solution is rather tricky",
"author": {
"id": 1,
+ "username": "john_smith",
"email": "john@example.com",
"name": "John Smith",
"blocked": false,
diff --git a/doc/api/projects.md b/doc/api/projects.md
index fdedf904a3a..c8cb263e705 100644
--- a/doc/api/projects.md
+++ b/doc/api/projects.md
@@ -17,6 +17,7 @@ GET /projects
"default_branch": "master",
"owner": {
"id": 1,
+ "username": "john_smith",
"email": "john@example.com",
"name": "John Smith",
"blocked": false,
@@ -38,6 +39,7 @@ GET /projects
"default_branch": "api",
"owner": {
"id": 1,
+ "username": "john_smith",
"email": "john@example.com",
"name": "John Smith",
"blocked": false,
@@ -75,6 +77,7 @@ Parameters:
"default_branch": "api",
"owner": {
"id": 1,
+ "username": "john_smith",
"email": "john@example.com",
"name": "John Smith",
"blocked": false,
@@ -123,6 +126,7 @@ GET /projects/:id/members
Parameters:
+ `id` (required) - The ID or code name of a project
++ `query` - Query string
## Get project team member
@@ -141,6 +145,7 @@ Parameters:
{
"id": 1,
+ "username": "john_smith",
"email": "john@example.com",
"name": "John Smith",
"blocked": false,
diff --git a/doc/api/session.md b/doc/api/session.md
index 9fdbeb439a4..c7e57aaca7a 100644
--- a/doc/api/session.md
+++ b/doc/api/session.md
@@ -13,6 +13,7 @@ Parameters:
```json
{
"id": 1,
+ "username": "john_smith",
"email": "john@example.com",
"name": "John Smith",
"private_token": "dd34asd13as",
diff --git a/doc/api/snippets.md b/doc/api/snippets.md
index 288fd5296f6..b9638ea8291 100644
--- a/doc/api/snippets.md
+++ b/doc/api/snippets.md
@@ -30,6 +30,7 @@ Parameters:
"file_name": "add.rb",
"author": {
"id": 1,
+ "username": "john_smith",
"email": "john@example.com",
"name": "John Smith",
"blocked": false,
diff --git a/doc/api/users.md b/doc/api/users.md
index c116144d91e..200c0e06e04 100644
--- a/doc/api/users.md
+++ b/doc/api/users.md
@@ -10,6 +10,7 @@ GET /users
[
{
"id": 1,
+ "username": "john_smith",
"email": "john@example.com",
"name": "John Smith",
"blocked": false,
@@ -23,6 +24,7 @@ GET /users
},
{
"id": 2,
+ "username": "jack_smith",
"email": "jack@example.com",
"name": "Jack Smith",
"blocked": false,
@@ -52,6 +54,7 @@ Parameters:
```json
{
"id": 1,
+ "username": "john_smith",
"email": "john@example.com",
"name": "John Smith",
"blocked": false,
@@ -75,7 +78,8 @@ POST /users
Parameters:
+ `email` (required) - Email
+ `password` (required) - Password
-+ `name` - Name
++ `username` (required) - Username
++ `name` (required) - Name
+ `skype` - Skype ID
+ `linkedin` - Linkedin
+ `twitter` - Twitter account
@@ -95,6 +99,7 @@ GET /user
```json
{
"id": 1,
+ "username": "john_smith",
"email": "john@example.com",
"name": "John Smith",
"blocked": false,
diff --git a/doc/development.md b/doc/development.md
deleted file mode 100644
index b7213adc1e0..00000000000
--- a/doc/development.md
+++ /dev/null
@@ -1,36 +0,0 @@
-## Development tips:
-
-
-### Installation
-
-Install the Gitlab development in a virtual machine with the [Gitlab Vagrant virtual machine](https://github.com/gitlabhq/gitlab-vagrant-vm). Installing it in a virtual machine makes it much easier to set up all the dependencies for integration testing.
-
-
-### Start application in development mode
-
-#### 1. Via foreman
-
- bundle exec foreman start -p 3000
-
-#### 2. Manually
-
- bundle exec rails s
- bundle exec rake environment resque:work QUEUE=* VVERBOSE=1
-
-
-### Test DB setup & seed
-
- bundle exec rake db:setup RAILS_ENV=test
- bundle exec rake db:seed_fu RAILS_ENV=test
-
-
-### Run the Tests
-
- # All in one
- bundle exec rake gitlab:test
-
- # Rspec
- bundle exec rake spec
-
- # Spinach
- bundle exec rake spinach
diff --git a/doc/install/databases.md b/doc/install/databases.md
index 1a6f739ecdc..92011647f11 100644
--- a/doc/install/databases.md
+++ b/doc/install/databases.md
@@ -1,47 +1,63 @@
-# Databases:
+# Setup Database
-GitLab use MySQL as default database but you are free to use PostgreSQL.
+GitLab supports the following databases:
+
+* MySQL (preferred)
+* PostgreSQL
## MySQL
+ # Install the database packages
sudo apt-get install -y mysql-server mysql-client libmysqlclient-dev
+ # Install only the necessary gems
+ sudo -u gitlab -H bundle install --deployment --without development test postgres
+
# Login to MySQL
$ mysql -u root -p
+ # Create a user for GitLab. (change $password to a real password)
+ mysql> CREATE USER 'gitlab'@'localhost' IDENTIFIED BY '$password';
+
# Create the GitLab production database
mysql> CREATE DATABASE IF NOT EXISTS `gitlabhq_production` DEFAULT CHARACTER SET `utf8` COLLATE `utf8_unicode_ci`;
- # Create the MySQL User change $password to a real password
- mysql> CREATE USER 'gitlab'@'localhost' IDENTIFIED BY '$password';
-
- # Grant proper permissions to the MySQL User
+ # Grant the GitLab user necessary permissopns on the table.
mysql> GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, INDEX, ALTER ON `gitlabhq_production`.* TO 'gitlab'@'localhost';
+ # Quit the database session
+ mysql> \q
+
+ # Try connecting to the new database with the new user
+ sudo -u gitlab -H mysql -u gitlab -p -D gitlabhq_production
## PostgreSQL
- sudo apt-get install -y postgresql-9.1 postgresql-server-dev-9.1
+ # Install the database packages
+ sudo apt-get install -y postgresql-9.1 libpq-dev
+
+ # Install only the necessary gems
+ sudo -u gitlab -H bundle install --deployment --without development test mysql
- # Connect to database server
+ # Login to PostgreSQL
sudo -u postgres psql -d template1
- # Add a user called gitlab. Change $password to a real password
+ # Create a user for GitLab. (change $password to a real password)
template1=# CREATE USER gitlab WITH PASSWORD '$password';
# Create the GitLab production database & grant all privileges on database
template1=# CREATE DATABASE gitlabhq_production OWNER gitlab;
- # Quit from PostgreSQL server
+ # Quit the database session
template1=# \q
- # Try connect to new database
- sudo -u gitlab psql -d gitlabhq_production
+ # Try connecting to the new database with the new user
+ sudo -u gitlab -H psql -d gitlabhq_production
-#### Select the database you want to use
+# Configure GitLab
# Mysql
sudo -u gitlab cp config/database.yml.mysql config/database.yml
@@ -49,12 +65,4 @@ GitLab use MySQL as default database but you are free to use PostgreSQL.
# PostgreSQL
sudo -u gitlab cp config/database.yml.postgresql config/database.yml
- # make sure to update username/password in config/database.yml
-
-#### Install gems
-
- # mysql
- sudo -u gitlab -H bundle install --without development test postgres --deployment
-
- # or postgres
- sudo -u gitlab -H bundle install --without development test mysql --deployment
+Make sure to update username/password in config/database.yml.
diff --git a/doc/install/installation.md b/doc/install/installation.md
index 6876a8756b1..159713dcba9 100644
--- a/doc/install/installation.md
+++ b/doc/install/installation.md
@@ -1,283 +1,322 @@
-_This installation guide created for Debian/Ubuntu and properly tested._
+This installation guide was created for Debian/Ubuntu and tested on it.
-_Checkout requirements before setup_
+Please read `doc/install/requirements.md` for hardware and platform requirements.
-### IMPORTANT
+**Important Note:**
+The following steps have been known to work.
+If you deviate from this guide, do it with caution and make sure you don't
+violate any assumptions GitLab makes about its environment.
+For things like AWS installation scripts, init scripts or config files for
+alternative web server have a look at the "Advanced Setup Tips" section.
-Please make sure you have followed all the steps below before posting to the mailing list with installation and configuration questions.
-Only create a GitHub Issue if you want a specific part of this installation guide updated.
-
-Also read the [Read this before you submit an issue](https://github.com/gitlabhq/gitlabhq/wiki/Read-this-before-you-submit-an-issue) wiki page.
+**Important Note:**
+If you find a bug/error in this guide please submit an issue or pull request
+following the contribution guide (see `CONTRIBUTING.md`).
- - -
-# Basic setup
-
-The basic installation will provide you a GitLab setup with options:
-
-1. ruby 1.9.3
-2. mysql as main db
-3. gitolite v3 fork by gitlab
-4. nginx + unicorn
+# Overview
-The installation consists of next steps:
+The GitLab installation consists of setting up th following components:
-1. Packages / dependencies
+1. Packages / Dependencies
2. Ruby
-3. Users
+3. System Users
4. Gitolite
-5. Mysql
-6. GitLab.
-7. Nginx
+5. Database
+6. GitLab
+7. Nginx
-# 1. Packages / dependencies
+# 1. Packages / Dependencies
-*Keep in mind that `sudo` is not installed on Debian by default. You should install it as root:*
+`sudo` is not installed on Debian by default. If you don't have it you'll need
+to install it first.
- apt-get update && apt-get upgrade && apt-get install sudo
+ # run as root
+ apt-get update && apt-get upgrade && apt-get install sudo vim
-Now install the required packages:
+Make sure your system is up-to-date:
sudo apt-get update
sudo apt-get upgrade
- sudo apt-get install -y wget curl gcc checkinstall libxml2-dev libxslt-dev libcurl4-openssl-dev libreadline6-dev libc6-dev libssl-dev libmysql++-dev make build-essential zlib1g-dev libicu-dev redis-server openssh-server git-core python-dev python-pip libyaml-dev postfix libpq-dev
+**Note:**
+Vim is an editor that is used here whenever there are files that need to be
+edited by hand. But, you can use any editor you like instead.
+
+ # Install vim
+ sudo apt-get install -y vim
+
+Install the required packages:
+
+ sudo apt-get install -y build-essential zlib1g-dev libyaml-dev libssl-dev libgdbm-dev libreadline-dev libncurses5-dev libffi-dev wget curl git-core openssh-server redis-server postfix checkinstall libxml2-dev libxslt-dev libcurl4-openssl-dev libicu-dev
+
+Make sure you have the right version of Python installed.
+
+ # Install Python
+ sudo apt-get install python
+
+ # Make sure that Python is 2.5+ (3.x is not supported at the moment)
+ python --version
+
+ # If it's Python 3 you might need to install Python 2 separately
+ sudo apt-get install python2.7
+
+ # Make sure you can access Python via python2
+ python2 --version
+
+ # If you get a "command not found" error create a link to the python binary
+ sudo ln -s /usr/bin/python /usr/bin/python2
- sudo pip install pygments
+# 2. Ruby
-# 2. Install Ruby
+Download and compile it:
- wget http://ftp.ruby-lang.org/pub/ruby/1.9/ruby-1.9.3-p194.tar.gz
- tar xfvz ruby-1.9.3-p194.tar.gz
- cd ruby-1.9.3-p194
+ wget http://ftp.ruby-lang.org/pub/ruby/1.9/ruby-1.9.3-p327.tar.gz
+ tar xfvz ruby-1.9.3-p327.tar.gz
+ cd ruby-1.9.3-p327
./configure
make
sudo make install
-# 3. Users
+Install the Bundler Gem:
-Create user for git:
+ sudo gem install bundler
+
+
+# 3. System Users
+
+Create a user for Git and Gitolite:
sudo adduser \
--system \
--shell /bin/sh \
- --gecos 'git version control' \
+ --gecos 'Git Version Control' \
--group \
--disabled-password \
--home /home/git \
git
-Create user for GitLab:
-
- # ubuntu/debian
- sudo adduser --disabled-login --gecos 'gitlab system' gitlab
+Create a user for GitLab:
-Add your users to groups:
+ sudo adduser --disabled-login --gecos 'GitLab' gitlab
+ # Add it to the git group
sudo usermod -a -G git gitlab
- sudo usermod -a -G gitlab git
-
-Generate key:
- sudo -H -u gitlab ssh-keygen -q -N '' -t rsa -f /home/gitlab/.ssh/id_rsa
+ # Generate the SSH key
+ sudo -u gitlab -H ssh-keygen -q -N '' -t rsa -f /home/gitlab/.ssh/id_rsa
# 4. Gitolite
Clone GitLab's fork of the Gitolite source code:
- sudo -H -u git git clone -b gl-v304 https://github.com/gitlabhq/gitolite.git /home/git/gitolite
+ cd /home/git
+ sudo -u git -H git clone -b gl-v320 https://github.com/gitlabhq/gitolite.git /home/git/gitolite
-Setup:
+Setup Gitolite with GitLab as its admin:
- cd /home/git
- sudo -u git -H mkdir bin
- sudo -u git sh -c 'echo -e "PATH=\$PATH:/home/git/bin\nexport PATH" >> /home/git/.profile'
- sudo -u git sh -c 'gitolite/install -ln /home/git/bin'
+**Important Note:**
+GitLab assumes *full and unshared* control over this Gitolite installation.
+
+ # Add Gitolite scripts to $PATH
+ sudo -u git -H mkdir /home/git/bin
+ sudo -u git -H sh -c 'printf "%b\n%b\n" "PATH=\$PATH:/home/git/bin" "export PATH" >> /home/git/.profile'
+ sudo -u git -H sh -c 'gitolite/install -ln /home/git/bin'
+ # Copy the gitlab user's (public) SSH key ...
sudo cp /home/gitlab/.ssh/id_rsa.pub /home/git/gitlab.pub
sudo chmod 0444 /home/git/gitlab.pub
+ # ... and use it as the admin key for the Gitolite setup
sudo -u git -H sh -c "PATH=/home/git/bin:$PATH; gitolite setup -pk /home/git/gitlab.pub"
-
-Permissions:
+Fix the directory permissions for the repositories:
- sudo chmod -R g+rwX /home/git/repositories/
+ # Make sure the repositories dir is owned by git and it stays that way
+ sudo chmod -R ug+rwXs,o-rwx /home/git/repositories/
sudo chown -R git:git /home/git/repositories/
- # clone admin repo to add localhost to known_hosts
- # & be sure your user has access to gitolite
+## Test if everything works so far
+
+ # Clone the admin repo so SSH adds localhost to known_hosts ...
+ # ... and to be sure your users have access to Gitolite
sudo -u gitlab -H git clone git@localhost:gitolite-admin.git /tmp/gitolite-admin
- # if succeed you can remove it
+ # If it succeeded without errors you can remove the cloned repo
sudo rm -rf /tmp/gitolite-admin
-**IMPORTANT! If you can't clone `gitolite-admin` repository - DO NOT PROCEED WITH INSTALLATION**
+**Important Note:**
+If you can't clone the `gitolite-admin` repository: **DO NOT PROCEED WITH INSTALLATION**!
Check the [Trouble Shooting Guide](https://github.com/gitlabhq/gitlab-public-wiki/wiki/Trouble-Shooting-Guide)
-and ensure you have followed all of the above steps carefully.
-
+and make sure you have followed all of the above steps carefully.
-# 5. Mysql database
- sudo apt-get install -y mysql-server mysql-client libmysqlclient-dev
+# 5. Database
- # Login to MySQL
- $ mysql -u root -p
-
- # Create the GitLab production database
- mysql> CREATE DATABASE IF NOT EXISTS `gitlabhq_production` DEFAULT CHARACTER SET `utf8` COLLATE `utf8_unicode_ci`;
-
- # Create the MySQL User change $password to a real password
- mysql> CREATE USER 'gitlab'@'localhost' IDENTIFIED BY '$password';
-
- # Grant proper permissions to the MySQL User
- mysql> GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, INDEX, ALTER ON `gitlabhq_production`.* TO 'gitlab'@'localhost';
+See `doc/install/databases.md`
# 6. GitLab
+ # We'll install GitLab into home directory of the user "gitlab"
cd /home/gitlab
+## Clone the Source
-#### Get source code
+ # Clone the latest stable release
+ sudo -u gitlab -H git clone -b stable https://github.com/gitlabhq/gitlabhq.git gitlab
- # Get gitlab code. Use this for stable setup
- sudo -H -u gitlab git clone -b stable https://github.com/gitlabhq/gitlabhq.git gitlab
+**Note:**
+You can change `stable` to `master` if you want the *bleeding edge* version, but
+do so with caution!
- # Skip this for stable setup.
- # Master branch (recent changes, less stable)
- sudo -H -u gitlab git clone -b master https://github.com/gitlabhq/gitlabhq.git gitlab
+## Configure it
+ cd /home/gitlab/gitlab
+
+ # Copy the example GitLab config
+ sudo -u gitlab -H cp config/gitlab.yml.example config/gitlab.yml
-#### Copy configs
-
- cd gitlab
+ # Make sure to change "localhost" to the fully-qualified domain name of your
+ # host serving GitLab where necessary
+ sudo -u gitlab -H vim config/gitlab.yml
- # Rename config files
- #
- sudo -u gitlab cp config/gitlab.yml.example config/gitlab.yml
+ # Make sure GitLab can write to the log/ and tmp/ directories
+ sudo chown -R gitlab log/
+ sudo chown -R gitlab tmp/
+ sudo chmod -R u+rwX log/
+ sudo chmod -R u+rwX tmp/
- # Copy mysql db config
- #
- # make sure to update username/password in config/database.yml
- #
- sudo -u gitlab cp config/database.yml.mysql config/database.yml
+ # Copy the example Unicorn config
+ sudo -u gitlab -H cp config/unicorn.rb.example config/unicorn.rb
- # Copy unicorn config
- #
- sudo -u gitlab cp config/unicorn.rb.example config/unicorn.rb
+**Important Note:**
+Make sure to edit both files to match your setup.
-#### Install gems
+## Install Gems
cd /home/gitlab/gitlab
sudo gem install charlock_holmes --version '0.6.9'
- sudo gem install bundler
- sudo -u gitlab -H bundle install --without development test postgres --deployment
+ sudo -u gitlab -H bundle install --deployment --without development test
-#### Configure git client
+## Configure Git
-Gitlab needs to be able to commit and push changes to gitolite.
-Git requires a username and email in order to be able to do that.
+GitLab needs to be able to commit and push changes to Gitolite. In order to do
+that Git requires a username and email. (We recommend using the same address
+used for the `email.from` setting in `config/gitlab.yml`)
+ sudo -u gitlab -H git config --global user.name "GitLab"
sudo -u gitlab -H git config --global user.email "gitlab@localhost"
- sudo -u gitlab -H git config --global user.name "Gitlab"
-#### Setup application
+## Setup GitLab Hooks
- sudo -u gitlab bundle exec rake gitlab:app:setup RAILS_ENV=production
+ sudo cp ./lib/hooks/post-receive /home/git/.gitolite/hooks/common/post-receive
+ sudo chown git:git /home/git/.gitolite/hooks/common/post-receive
+## Initialise Database and Activate Advanced Features
-#### Setup GitLab hooks
+ sudo -u gitlab -H bundle exec rake gitlab:app:setup RAILS_ENV=production
- sudo cp ./lib/hooks/post-receive /home/git/.gitolite/hooks/common/post-receive
- sudo chown git:git /home/git/.gitolite/hooks/common/post-receive
-#### Check application status
+## Check Application Status
+
+Check if GitLab and its environment is configured correctly:
-Checking status:
+ sudo -u gitlab -H bundle exec rake gitlab:env:info RAILS_ENV=production
- sudo -u gitlab bundle exec rake gitlab:app:status RAILS_ENV=production
+To make sure you didn't miss anything run a more thorough check with:
+ sudo -u gitlab -H bundle exec rake gitlab:check RAILS_ENV=production
- # OUTPUT EXAMPLE
- Starting diagnostic
- config/database.yml............exists
- config/gitlab.yml............exists
- /home/git/repositories/............exists
- /home/git/repositories/ is writable?............YES
- remote: Counting objects: 603, done.
- remote: Compressing objects: 100% (466/466), done.
- remote: Total 603 (delta 174), reused 0 (delta 0)
- Receiving objects: 100% (603/603), 53.29 KiB, done.
- Resolving deltas: 100% (174/174), done.
- Can clone gitolite-admin?............YES
- UMASK for .gitolite.rc is 0007? ............YES
- /home/git/share/gitolite/hooks/common/post-receive exists? ............YES
+If you are all green: congratulations, you successfully installed GitLab!
+Although this is the case, there are still a few steps to go.
-If you got all YES - congratulations! You can run a GitLab app.
-#### init script
+## Install Init Script
-Create init script in /etc/init.d/gitlab:
+Download the init script (will be /etc/init.d/gitlab):
sudo wget https://raw.github.com/gitlabhq/gitlab-recipes/master/init.d/gitlab -P /etc/init.d/
sudo chmod +x /etc/init.d/gitlab
-GitLab autostart:
+Make GitLab start on boot:
sudo update-rc.d gitlab defaults 21
-#### Now you should start GitLab application:
+
+Start your GitLab instance:
sudo service gitlab start
+ # or
+ sudo /etc/init.d/gitlab restart
# 7. Nginx
- # Install first
+**Note:**
+If you can't or don't want to use Nginx as your web server, have a look at the
+"Advanced Setup Tips" section.
+
+## Installation
sudo apt-get install nginx
- # Add GitLab to nginx sites & change with your host specific settings
+## Site Configuration
+
+Download an example site config:
+
sudo wget https://raw.github.com/gitlabhq/gitlab-recipes/master/nginx/gitlab -P /etc/nginx/sites-available/
sudo ln -s /etc/nginx/sites-available/gitlab /etc/nginx/sites-enabled/gitlab
+Make sure to edit the config file to match your setup:
+
# Change **YOUR_SERVER_IP** and **YOUR_SERVER_FQDN**
# to the IP address and fully-qualified domain name
- # of the host serving GitLab.
+ # of your host serving GitLab
sudo vim /etc/nginx/sites-enabled/gitlab
- # Restart nginx:
+## Restart
+
sudo /etc/init.d/nginx restart
-# Done! Visit YOUR_SERVER for gitlab instance
+# Done!
-You can login via web using admin generated with setup:
+Visit YOUR_SERVER for your first GitLab login.
+The setup has created an admin account for you. You can use it to log in:
admin@local.host
5iveL!fe
+**Important Note:**
+Please go over to your profile page and immediately chage the password, so
+nobody can access your GitLab by using this login information later on.
+
+**Enjoy!**
-- - -
+- - -
-# Advanced setup tips:
-_Checkout databases.md for PostgreSQL_
+# Advanced Setup Tips
-## Customizing Resque's Redis connection
+## Custom Redis Connection
If you'd like Resque to connect to a Redis server on a non-standard port or on
-a different host, you can configure its connection string in the
-**config/resque.yml** file:
+a different host, you can configure its connection string via the
+`config/resque.yml` file.
+
+ # example
+ production: redis.example.tld:6379
+
- production: redis.example.com:6379
+## User-contributed Configurations
-**Ok - we have a working application now. **
-**But keep going - there are some things that should be done **
+You can find things like AWS installation scripts, init scripts or config files
+for alternative web server in our [recipes collection](https://github.com/gitlabhq/gitlab-recipes/).
diff --git a/doc/install/requirements.md b/doc/install/requirements.md
index 75b02d6456f..ec5b013c5d8 100644
--- a/doc/install/requirements.md
+++ b/doc/install/requirements.md
@@ -1,28 +1,56 @@
-## Platform requirements:
+# Hardware
-**The project is designed for the Linux operating system.**
+We recommend you to run GitLab on a server with at least 1GB RAM.
-It may work on FreeBSD and Mac OS, but we don't test our application for these systems and can't guarantee stability and full functionality.
+The necessary hard disk space largely depends on the size of the repos you want
+to use GitLab with. But as a *rule of thumb* you should have at least as much
+free space as your all repos combined take up.
-We officially support (recent versions of) these Linux distributions:
+
+
+# Operating Systems
+
+## Linux
+
+GitLab is developed for the Linux operating system.
+
+GitLab officially supports (recent versions of) these Linux distributions:
- Ubuntu Linux
- Debian/GNU Linux
-It should work on:
+It should also work on (though they are not officially supported):
+- Arch
+- CentOS
- Fedora
-- CentOs
+- Gentoo
- RedHat
-You might have some luck using these, but no guarantees:
+## Other Unix Systems
+
+There is nothing that prevents GitLab from running on other Unix operating
+systems. This means you may get it to work on systems running FreeBSD or OS X.
+**If you want to try, please proceed with caution!**
+
+## Windows
+
+GitLab does **not** run on Windows and we have no plans of supporting it in the
+near future.
+
+
+
+# Rubies
-- FreeBSD will likely work, see https://github.com/gitlabhq/gitlabhq/issues/796
-- MacOS X will likely work, see https://groups.google.com/forum/#!topic/gitlabhq/5IXHbPkjKLA
+GitLab requires Ruby (MRI) 1.9.3 and several Gems with native components.
+While it is generally possible to use other Rubies (like
+[JRuby](http://jruby.org/) or [Rubinius](http://rubini.us/)) it might require
+some work on your part.
-GitLab does **not** run on Windows and we have no plans of making GitLab compatible.
-## Hardware:
+# Installation troubles and reporting success or failure
-We recommend to use server with at least 1GB RAM for gitlab instance.
+If you have troubles installing GitLab following the official installation guide
+or want to share your experience installing GitLab on a not officially supported
+platform, please follow the the contribution guide (see CONTRIBUTING.md).
diff --git a/doc/raketasks/backup_restore.md b/doc/raketasks/backup_restore.md
index 575467b4371..bbfeeb716fa 100644
--- a/doc/raketasks/backup_restore.md
+++ b/doc/raketasks/backup_restore.md
@@ -4,7 +4,7 @@ Creates a backup archive of the database and all repositories. This archive will
The filename will be `[TIMESTAMP]_gitlab_backup.tar`. This timestamp can be used to restore an specific backup.
```
-bundle exec rake gitlab:app:backup_create
+bundle exec rake gitlab:backup:create
```
Example output:
@@ -40,7 +40,7 @@ Deleting old backups... [SKIPPING]
### Restore a previously created backup
```
-bundle exec rake gitlab:app:backup_restore
+bundle exec rake gitlab:backup:restore
```
Options:
diff --git a/doc/raketasks/features.md b/doc/raketasks/features.md
index 2a66b1caca7..7a2a4b668bd 100644
--- a/doc/raketasks/features.md
+++ b/doc/raketasks/features.md
@@ -1,6 +1,6 @@
### Enable usernames and namespaces for user projects
-This command will enable the namespace feature introduced in v4.0. It will move every project in its namespace folder.
+This command will enable the namespaces feature introduced in v4.0. It will move every project in its namespace folder.
Note:
@@ -13,7 +13,7 @@ Old path: `git@example.org:myrepo.git`
New path: `git@example.org:username/myrepo.git` or `git@example.org:groupname/myrepo.git`
```
-bundle exec rake gitlab:activate_namespaces
+bundle exec rake gitlab:enable_namespaces
```
@@ -22,7 +22,7 @@ bundle exec rake gitlab:activate_namespaces
This command will enable the auto merge feature. After this you will be able to **merge a merge request** via GitLab and use the **online editor**.
```
-bundle exec rake gitlab:app:enable_automerge
+bundle exec rake gitlab:enable_automerge
```
Example output:
diff --git a/doc/raketasks/maintenance.md b/doc/raketasks/maintenance.md
index 1247d4b6dd7..bb8e1ed29f7 100644
--- a/doc/raketasks/maintenance.md
+++ b/doc/raketasks/maintenance.md
@@ -54,9 +54,18 @@ Git: /usr/bin/git
```
-### Check GitLab installation status
+### Check GitLab configuration
-[Trouble-Shooting-Guide](https://github.com/gitlabhq/gitlab-public-wiki/wiki/Trouble-Shooting-Guide)
+Runs the following rake tasks:
+
+* gitlab:env:check
+* gitlab:gitolite:check
+* gitlab:resque:check
+* gitlab:app:check
+
+It will check that each component was setup according to the installation guide and suggest fixes for issues found.
+
+You may also have a look at our [Trouble Shooting Guide](https://github.com/gitlabhq/gitlab-public-wiki/wiki/Trouble-Shooting-Guide).
```
bundle exec rake gitlab:check
@@ -65,21 +74,78 @@ bundle exec rake gitlab:check
Example output:
```
-config/database.yml............exists
-config/gitlab.yml............exists
-/home/git/repositories/............exists
-/home/git/repositories/ is writable?............YES
-Can clone gitolite-admin?............YES
-Can git commit?............YES
-UMASK for .gitolite.rc is 0007? ............YES
-/home/git/.gitolite/hooks/common/post-receive exists? ............YES
+Checking Environment ...
+
+gitlab user is in git group? ... yes
+Has no "-e" in ~git/.profile ... yes
+Git configured for gitlab user? ... yes
+Has python2? ... yes
+python2 is supported version? ... yes
+
+Checking Environment ... Finished
+
+Checking Gitolite ...
+
+Using recommended version ... yes
+Repo umask is 0007 in .gitolite.rc? ... yes
+Allow all Git config keys in .gitolite.rc ... yes
+Config directory exists? ... yes
+Config directory owned by git:git? ... yes
+Config directory access is drwxr-x---? ... yes
+Repo base directory exists? ... yes
+Repo base owned by git:git? ... yes
+Repo base access is drwsrws---? ... yes
+Can clone gitolite-admin? ... yes
+Can commit to gitolite-admin? ... yes
+post-receive hook exists? ... yes
+post-receive hook up-to-date? ... yes
+post-receive hooks in repos are links: ...
+GitLab ... ok
+Non-Ascii Files Test ... ok
+Touch Commit Test ... ok
+Without Master Test ... ok
+Git config in repos: ...
+GitLab ... ok
+Non-Ascii Files Test ... ok
+Touch Commit Test ... ok
+Without Master Test ... ok
+
+Checking Gitolite ... Finished
+
+Checking Resque ...
+
+Running? ... yes
+
+Checking Resque ... Finished
+
+Checking GitLab ...
+
+Database config exists? ... yes
+Database is not SQLite ... yes
+All migrations up? ... yes
+GitLab config exists? ... yes
+GitLab config not outdated? ... yes
+Log directory writable? ... yes
+Tmp directory writable? ... yes
+Init script exists? ... yes
+Init script up-to-date? ... yes
+Projects have satellites? ...
+GitLab ... yes
+Non-Ascii Files Test ... yes
+Touch Commit Test ... yes
+Without Master Test ... yes
+
+Checking GitLab ... Finished
+```
-Validating projects repositories:
-* abcd.....post-receive file ok
-* abcdtest.....post-receive file missing
-Finished
+### (Re-)Create satellite repos
+This will create satellite repos for all your projects.
+If necessary, remove the `tmp/repo_satellites` directory and rerun the command below.
+
+```
+bundle exec rake gitlab:satellites:create
```
diff --git a/doc/raketasks/user_management.md b/doc/raketasks/user_management.md
index e4ca5280b78..021ce35931f 100644
--- a/doc/raketasks/user_management.md
+++ b/doc/raketasks/user_management.md
@@ -1,7 +1,7 @@
### Add user to as a developer to all projects
```
-bundle exec rake add_user_to_project_teams[username@domain.tld]
+bundle exec rake gitlab:import:user_to_projects[username@domain.tld]
```
@@ -12,5 +12,5 @@ Notes:
* admin users are added as masters
```
-bundle exec rake add_users_to_project_teams
+bundle exec rake gitlab:import:all_users_to_all_projects
```
diff --git a/features/project/issues/issues.feature b/features/project/issues/issues.feature
index 99529373d4d..d6ef384c9a6 100644
--- a/features/project/issues/issues.feature
+++ b/features/project/issues/issues.feature
@@ -24,11 +24,9 @@ Feature: Project Issues
Given I click link "Release 0.4"
Then I should see issue "Release 0.4"
- @javascript
Scenario: I submit new unassigned issue
Given I click link "New Issue"
And I submit new issue "500 error on profile"
- Given I click link "500 error on profile"
Then I should see issue "500 error on profile"
@javascript
@@ -57,26 +55,19 @@ Feature: Project Issues
Then I should see "Release 0.3" in issues
And I should not see "Release 0.4" in issues
- # TODO: find out solution for poltergeist/phantomjs or remove
- # @javascript
- # Scenario: I clear search
- # Given I click link "All"
- # And I fill in issue search with "Something"
- # And I fill in issue search with ""
- # Then I should see "Release 0.4" in issues
- # And I should see "Release 0.3" in issues
+ # Disable this two cause of random failing
+ # TODO: fix after v4.0 released
+ #@javascript
+ #Scenario: I create Issue with pre-selected milestone
+ #Given project "Shop" has milestone "v2.2"
+ #And project "Shop" has milestone "v3.0"
+ #And I visit project "Shop" issues page
+ #When I select milestone "v3.0"
+ #And I click link "New Issue"
+ #Then I should see selected milestone with title "v3.0"
- @javascript
- Scenario: I create Issue with pre-selected milestone
- Given project "Shop" has milestone "v2.2"
- And project "Shop" has milestone "v3.0"
- And I visit project "Shop" issues page
- When I select milestone "v3.0"
- And I click link "New Issue"
- Then I should see selected milestone with title "v3.0"
-
- @javascript
- Scenario: I create Issue with pre-selected assignee
- When I select first assignee from "Shop" project
- And I click link "New Issue"
- Then I should see first assignee from "Shop" as selected assignee
+ #@javascript
+ #Scenario: I create Issue with pre-selected assignee
+ #When I select first assignee from "Shop" project
+ #And I click link "New Issue"
+ #Then I should see first assignee from "Shop" as selected assignee
diff --git a/features/steps/project/project_browse_commits.rb b/features/steps/project/project_browse_commits.rb
index 6bf164e2c8f..2c03ce14fc1 100644
--- a/features/steps/project/project_browse_commits.rb
+++ b/features/steps/project/project_browse_commits.rb
@@ -32,8 +32,8 @@ class ProjectBrowseCommits < Spinach::FeatureSteps
end
And 'I fill compare fields with refs' do
- fill_in "from", with: "bcf03b5de6c33f3869ef70d68cf06e679d1d7f9a"
- fill_in "to", with: "8716fc78f3c65bbf7bcf7b574febd583bc5d2812"
+ fill_in "from", with: "8716fc78f3c65bbf7bcf7b574febd583bc5d2812"
+ fill_in "to", with: "bcf03b5de6c33f3869ef70d68cf06e679d1d7f9a"
click_button "Compare"
end
diff --git a/features/steps/project/project_issues.rb b/features/steps/project/project_issues.rb
index cc0acb5b481..2103aeb1715 100644
--- a/features/steps/project/project_issues.rb
+++ b/features/steps/project/project_issues.rb
@@ -95,7 +95,7 @@ class ProjectIssues < Spinach::FeatureSteps
end
Then 'I should see selected milestone with title "v3.0"' do
- issues_milestone_selector = "#milestone_id_chzn > a"
+ issues_milestone_selector = "#issue_milestone_id_chzn > a"
page.find(issues_milestone_selector).should have_content("v3.0")
end
@@ -106,7 +106,7 @@ class ProjectIssues < Spinach::FeatureSteps
end
Then 'I should see first assignee from "Shop" as selected assignee' do
- issues_assignee_selector = "#assignee_id_chzn > a"
+ issues_assignee_selector = "#issue_assignee_id_chzn > a"
project = Project.find_by_name "Shop"
assignee_name = project.users.first.name
page.find(issues_assignee_selector).should have_content(assignee_name)
diff --git a/features/support/env.rb b/features/support/env.rb
index a30b357718e..500de0f3e20 100644
--- a/features/support/env.rb
+++ b/features/support/env.rb
@@ -33,11 +33,9 @@ DatabaseCleaner.strategy = :truncation
Spinach.hooks.before_scenario do
# Use tmp dir for FS manipulations
- Gitlab.config.stub(git_base_path: Rails.root.join('tmp', 'test-git-base-path'))
- FileUtils.rm_rf Gitlab.config.git_base_path
- FileUtils.mkdir_p Gitlab.config.git_base_path
-
- DatabaseCleaner.start
+ Gitlab.config.gitolite.stub(repos_path: Rails.root.join('tmp', 'test-git-base-path'))
+ FileUtils.rm_rf Gitlab.config.gitolite.repos_path
+ FileUtils.mkdir_p Gitlab.config.gitolite.repos_path
end
Spinach.hooks.after_scenario do
diff --git a/lib/api/entities.rb b/lib/api/entities.rb
index 9e9d44594a2..070fbad27ed 100644
--- a/lib/api/entities.rb
+++ b/lib/api/entities.rb
@@ -1,12 +1,12 @@
module Gitlab
module Entities
class User < Grape::Entity
- expose :id, :email, :name, :bio, :skype, :linkedin, :twitter,
+ expose :id, :username, :email, :name, :bio, :skype, :linkedin, :twitter,
:dark_scheme, :theme_id, :blocked, :created_at
end
class UserBasic < Grape::Entity
- expose :id, :email, :name, :blocked, :created_at
+ expose :id, :username, :email, :name, :blocked, :created_at
end
class UserLogin < UserBasic
diff --git a/lib/api/helpers.rb b/lib/api/helpers.rb
index e9305b40836..6bd8111c2b2 100644
--- a/lib/api/helpers.rb
+++ b/lib/api/helpers.rb
@@ -5,13 +5,18 @@ module Gitlab
end
def user_project
- if @project ||= current_user.projects.find_by_id(params[:id]) ||
- current_user.projects.find_by_path(params[:id])
+ @project ||= find_project
+ @project || not_found!
+ end
+
+ def find_project
+ project = Project.find_by_id(params[:id]) || Project.find_with_namespace(params[:id])
+
+ if project && can?(current_user, :read_project, project)
+ project
else
- not_found!
+ nil
end
-
- @project
end
def paginate(object)
@@ -32,6 +37,10 @@ module Gitlab
end
end
+ def can?(object, action, subject)
+ abilities.allowed?(object, action, subject)
+ end
+
def attributes_for_keys(keys)
attrs = {}
keys.each do |key|
diff --git a/lib/api/projects.rb b/lib/api/projects.rb
index 384dbcd5473..044a6272766 100644
--- a/lib/api/projects.rb
+++ b/lib/api/projects.rb
@@ -57,10 +57,15 @@ module Gitlab
#
# Parameters:
# id (required) - The ID or code name of a project
+ # query - Query string
# Example Request:
# GET /projects/:id/members
get ":id/members" do
- @members = paginate user_project.users
+ if params[:query].present?
+ @members = paginate user_project.users.where("username LIKE ?", "%#{params[:query]}%")
+ else
+ @members = paginate user_project.users
+ end
present @members, with: Entities::ProjectMember, project: user_project
end
diff --git a/lib/api/users.rb b/lib/api/users.rb
index cad99fd9f7b..140c20f6bd2 100644
--- a/lib/api/users.rb
+++ b/lib/api/users.rb
@@ -101,8 +101,6 @@ module Gitlab
key = current_user.keys.find params[:id]
key.delete
end
-
-
end
end
end
diff --git a/lib/gitlab/auth.rb b/lib/gitlab/auth.rb
index 056fb034daf..8c45c93557e 100644
--- a/lib/gitlab/auth.rb
+++ b/lib/gitlab/auth.rb
@@ -38,7 +38,7 @@ module Gitlab
email: email,
password: password,
password_confirmation: password,
- projects_limit: Gitlab.config.default_projects_limit,
+ projects_limit: Gitlab.config.gitlab.default_projects_limit,
}, as: :admin)
if Gitlab.config.omniauth['block_auto_created_users'] && !ldap
@user.blocked = true
diff --git a/lib/gitlab/backend/gitolite.rb b/lib/gitlab/backend/gitolite.rb
index 7c3861bdd13..3b8a2090f73 100644
--- a/lib/gitlab/backend/gitolite.rb
+++ b/lib/gitlab/backend/gitolite.rb
@@ -38,7 +38,7 @@ module Gitlab
end
def url_to_repo path
- Gitlab.config.ssh_path + "#{path}.git"
+ Gitlab.config.gitolite.ssh_path_prefix + "#{path}.git"
end
def enable_automerge
diff --git a/lib/gitlab/backend/gitolite_config.rb b/lib/gitlab/backend/gitolite_config.rb
index 70ccc4782c6..a2bc4ca8d74 100644
--- a/lib/gitlab/backend/gitolite_config.rb
+++ b/lib/gitlab/backend/gitolite_config.rb
@@ -16,7 +16,7 @@ module Gitlab
def ga_repo
@ga_repo ||= ::Gitolite::GitoliteAdmin.new(
File.join(config_tmp_dir,'gitolite'),
- conf: Gitlab.config.gitolite_config_file
+ conf: Gitlab.config.gitolite.config_file
)
end
@@ -167,7 +167,7 @@ module Gitlab
# Enable access to all repos for gitolite admin.
# We use it for accept merge request feature
def admin_all_repo
- owner_name = Gitlab.config.gitolite_admin_key
+ owner_name = Gitlab.config.gitolite.admin_key
# @ALL repos premission for gitolite owner
repo_name = "@all"
@@ -189,7 +189,7 @@ module Gitlab
def pull tmp_dir
Dir.mkdir tmp_dir
- `git clone #{Gitlab.config.gitolite_admin_uri} #{tmp_dir}/gitolite`
+ `git clone #{Gitlab.config.gitolite.admin_uri} #{tmp_dir}/gitolite`
unless File.exists?(File.join(tmp_dir, 'gitolite', 'conf', 'gitolite.conf'))
raise PullError, "unable to clone gitolite-admin repo"
diff --git a/lib/gitlab/backend/grack_auth.rb b/lib/gitlab/backend/grack_auth.rb
index 9fafc9617d1..7c31117f01d 100644
--- a/lib/gitlab/backend/grack_auth.rb
+++ b/lib/gitlab/backend/grack_auth.rb
@@ -38,12 +38,12 @@ module Grack
end
def validate_get_request
- true
+ can?(user, :download_code, project)
end
def validate_post_request
if @request.path_info.end_with?('git-upload-pack')
- can?(user, :push_code, project)
+ can?(user, :download_code, project)
elsif @request.path_info.end_with?('git-receive-pack')
action = if project.protected_branch?(current_ref)
:push_code_to_protected_branches
diff --git a/lib/gitlab/logger.rb b/lib/gitlab/logger.rb
index 8b4eee5da06..389eef3395f 100644
--- a/lib/gitlab/logger.rb
+++ b/lib/gitlab/logger.rb
@@ -14,6 +14,11 @@ module Gitlab
logs = `tail -n 2000 #{path}`.split("\n")
end
+ def self.read_latest_for filename
+ path = Rails.root.join("log", filename)
+ logs = `tail -n 2000 #{path}`.split("\n")
+ end
+
def self.build
new(Rails.root.join("log", file_name))
end
diff --git a/lib/gitlab/project_mover.rb b/lib/gitlab/project_mover.rb
index eeab22ae6e7..def6e90001b 100644
--- a/lib/gitlab/project_mover.rb
+++ b/lib/gitlab/project_mover.rb
@@ -15,10 +15,10 @@ module Gitlab
def execute
# Create new dir if missing
- new_dir_path = File.join(Gitlab.config.git_base_path, new_dir)
+ new_dir_path = File.join(Gitlab.config.gitolite.repos_path, new_dir)
system("mkdir -m 770 #{new_dir_path}") unless File.exists?(new_dir_path)
- old_path = File.join(Gitlab.config.git_base_path, old_dir, "#{project.path}.git")
+ old_path = File.join(Gitlab.config.gitolite.repos_path, old_dir, "#{project.path}.git")
new_path = File.join(new_dir_path, "#{project.path}.git")
if File.exists? new_path
diff --git a/lib/hooks/post-receive b/lib/hooks/post-receive
index 4a3ce372eb8..ebd9e1a028a 100755
--- a/lib/hooks/post-receive
+++ b/lib/hooks/post-receive
@@ -6,7 +6,6 @@
while read oldrev newrev ref
do
# For every branch or tag that was pushed, create a Resque job in redis.
- pwd=`pwd`
- reponame=`basename "$pwd" | sed s/\.git$//`
- env -i redis-cli rpush "resque:gitlab:queue:post_receive" "{\"class\":\"PostReceive\",\"args\":[\"$reponame\",\"$oldrev\",\"$newrev\",\"$ref\",\"$GL_USER\"]}" > /dev/null 2>&1
+ repo_path=`pwd`
+ env -i redis-cli rpush "resque:gitlab:queue:post_receive" "{\"class\":\"PostReceive\",\"args\":[\"$repo_path\",\"$oldrev\",\"$newrev\",\"$ref\",\"$GL_USER\"]}" > /dev/null 2>&1
done
diff --git a/lib/tasks/bulk_add_permission.rake b/lib/tasks/bulk_add_permission.rake
deleted file mode 100644
index bf08ace8e9c..00000000000
--- a/lib/tasks/bulk_add_permission.rake
+++ /dev/null
@@ -1,20 +0,0 @@
-desc "Add all users to all projects (admin users are added as masters)"
-task :add_users_to_project_teams => :environment do |t, args|
- user_ids = User.where(:admin => false).pluck(:id)
- admin_ids = User.where(:admin => true).pluck(:id)
-
- Project.find_each do |project|
- puts "Importing #{user_ids.size} users into #{project.code}"
- UsersProject.bulk_import(project, user_ids, UsersProject::DEVELOPER)
- puts "Importing #{admin_ids.size} admins into #{project.code}"
- UsersProject.bulk_import(project, admin_ids, UsersProject::MASTER)
- end
-end
-
-desc "Add user to as a developer to all projects"
-task :add_user_to_project_teams, [:email] => :environment do |t, args|
- user = User.find_by_email args.email
- project_ids = Project.pluck(:id)
-
- UsersProject.user_bulk_import(user, project_ids, UsersProject::DEVELOPER)
-end
diff --git a/lib/tasks/gitlab/backup.rake b/lib/tasks/gitlab/backup.rake
index c01fe479dba..b7a64394ad0 100644
--- a/lib/tasks/gitlab/backup.rake
+++ b/lib/tasks/gitlab/backup.rake
@@ -1,14 +1,14 @@
require 'active_record/fixtures'
namespace :gitlab do
- namespace :app do
+ namespace :backup do
# Create backup of GitLab system
desc "GITLAB | Create a backup of the GitLab system"
- task :backup_create => :environment do
- Rake::Task["gitlab:app:db_dump"].invoke
- Rake::Task["gitlab:app:repo_dump"].invoke
+ task :create => :environment do
+ Rake::Task["gitlab:backup:db:create"].invoke
+ Rake::Task["gitlab:backup:repo:create"].invoke
- Dir.chdir(Gitlab.config.backup_path)
+ Dir.chdir(Gitlab.config.backup.path)
# saving additional informations
s = {}
@@ -17,7 +17,7 @@ namespace :gitlab do
s[:gitlab_version] = %x{git rev-parse HEAD}.gsub(/\n/,"")
s[:tar_version] = %x{tar --version | head -1}.gsub(/\n/,"")
- File.open("#{Gitlab.config.backup_path}/backup_information.yml", "w+") do |file|
+ File.open("#{Gitlab.config.backup.path}/backup_information.yml", "w+") do |file|
file << s.to_yaml.gsub(/^---\n/,'')
end
@@ -39,10 +39,10 @@ namespace :gitlab do
# delete backups
print "Deleting old backups... "
- if Gitlab.config.backup_keep_time > 0
+ if Gitlab.config.backup.keep_time > 0
file_list = Dir.glob("*_gitlab_backup.tar").map { |f| f.split(/_/).first.to_i }
file_list.sort.each do |timestamp|
- if Time.at(timestamp) < (Time.now - Gitlab.config.backup_keep_time)
+ if Time.at(timestamp) < (Time.now - Gitlab.config.backup.keep_time)
%x{rm #{timestamp}_gitlab_backup.tar}
end
end
@@ -54,15 +54,15 @@ namespace :gitlab do
# Restore backup of GitLab system
desc "GITLAB | Restore a previously created backup"
- task :backup_restore => :environment do
- Dir.chdir(Gitlab.config.backup_path)
+ task :restore => :environment do
+ Dir.chdir(Gitlab.config.backup.path)
# check for existing backups in the backup dir
file_list = Dir.glob("*_gitlab_backup.tar").each.map { |f| f.split(/_/).first.to_i }
puts "no backups found" if file_list.count == 0
if file_list.count > 1 && ENV["BACKUP"].nil?
puts "Found more than one backup, please specify which one you want to restore:"
- puts "rake gitlab:app:backup_restore BACKUP=timestamp_of_backup"
+ puts "rake gitlab:backup:restore BACKUP=timestamp_of_backup"
exit 1;
end
@@ -93,8 +93,8 @@ namespace :gitlab do
exit 1
end
- Rake::Task["gitlab:app:db_restore"].invoke
- Rake::Task["gitlab:app:repo_restore"].invoke
+ Rake::Task["gitlab:backup:db:restore"].invoke
+ Rake::Task["gitlab:backup:repo:restore"].invoke
# cleanup: remove tmp files
print "Deleting tmp directories..."
@@ -110,82 +110,86 @@ namespace :gitlab do
################################# REPOSITORIES #################################
- task :repo_dump => :environment do
- backup_path_repo = File.join(Gitlab.config.backup_path, "repositories")
- FileUtils.mkdir_p(backup_path_repo) until Dir.exists?(backup_path_repo)
- puts "Dumping repositories:"
- project = Project.all.map { |n| [n.path, n.path_to_repo] }
- project << ["gitolite-admin.git", File.join(File.dirname(project.first.second), "gitolite-admin.git")]
- project.each do |project|
- print "- Dumping repository #{project.first}... "
- if Kernel.system("cd #{project.second} > /dev/null 2>&1 && git bundle create #{backup_path_repo}/#{project.first}.bundle --all > /dev/null 2>&1")
- puts "[DONE]".green
- else
- puts "[FAILED]".red
+ namespace :repo do
+ task :create => :environment do
+ backup_path_repo = File.join(Gitlab.config.backup.path, "repositories")
+ FileUtils.mkdir_p(backup_path_repo) until Dir.exists?(backup_path_repo)
+ puts "Dumping repositories:"
+ project = Project.all.map { |n| [n.path, n.path_to_repo] }
+ project << ["gitolite-admin.git", File.join(File.dirname(project.first.second), "gitolite-admin.git")]
+ project.each do |project|
+ print "- Dumping repository #{project.first}... "
+ if Kernel.system("cd #{project.second} > /dev/null 2>&1 && git bundle create #{backup_path_repo}/#{project.first}.bundle --all > /dev/null 2>&1")
+ puts "[DONE]".green
+ else
+ puts "[FAILED]".red
+ end
end
end
- end
- task :repo_restore => :environment do
- backup_path_repo = File.join(Gitlab.config.backup_path, "repositories")
- puts "Restoring repositories:"
- project = Project.all.map { |n| [n.path, n.path_to_repo] }
- project << ["gitolite-admin.git", File.join(File.dirname(project.first.second), "gitolite-admin.git")]
- project.each do |project|
- print "- Restoring repository #{project.first}... "
- FileUtils.rm_rf(project.second) if File.dirname(project.second) # delete old stuff
- if Kernel.system("cd #{File.dirname(project.second)} > /dev/null 2>&1 && git clone --bare #{backup_path_repo}/#{project.first}.bundle #{project.first}.git > /dev/null 2>&1")
- permission_commands = [
- "sudo chmod -R g+rwX #{Gitlab.config.git_base_path}",
- "sudo chown -R #{Gitlab.config.ssh_user}:#{Gitlab.config.ssh_user} #{Gitlab.config.git_base_path}"
- ]
- permission_commands.each { |command| Kernel.system(command) }
- puts "[DONE]".green
- else
- puts "[FAILED]".red
+ task :restore => :environment do
+ backup_path_repo = File.join(Gitlab.config.backup.path, "repositories")
+ puts "Restoring repositories:"
+ project = Project.all.map { |n| [n.path, n.path_to_repo] }
+ project << ["gitolite-admin.git", File.join(File.dirname(project.first.second), "gitolite-admin.git")]
+ project.each do |project|
+ print "- Restoring repository #{project.first}... "
+ FileUtils.rm_rf(project.second) if File.dirname(project.second) # delete old stuff
+ if Kernel.system("cd #{File.dirname(project.second)} > /dev/null 2>&1 && git clone --bare #{backup_path_repo}/#{project.first}.bundle #{project.first}.git > /dev/null 2>&1")
+ permission_commands = [
+ "sudo chmod -R g+rwX #{Gitlab.config.git_base_path}",
+ "sudo chown -R #{Gitlab.config.ssh_user}:#{Gitlab.config.ssh_user} #{Gitlab.config.git_base_path}"
+ ]
+ permission_commands.each { |command| Kernel.system(command) }
+ puts "[DONE]".green
+ else
+ puts "[FAILED]".red
+ end
end
end
end
###################################### DB ######################################
- task :db_dump => :environment do
- backup_path_db = File.join(Gitlab.config.backup_path, "db")
- FileUtils.mkdir_p(backup_path_db) unless Dir.exists?(backup_path_db)
-
- puts "Dumping database tables:"
- ActiveRecord::Base.connection.tables.each do |tbl|
- print "- Dumping table #{tbl}... "
- count = 1
- File.open(File.join(backup_path_db, tbl + ".yml"), "w+") do |file|
- ActiveRecord::Base.connection.select_all("SELECT * FROM `#{tbl}`").each do |line|
- line.delete_if{|k,v| v.blank?}
- output = {tbl + '_' + count.to_s => line}
- file << output.to_yaml.gsub(/^---\n/,'') + "\n"
- count += 1
+ namespace :db do
+ task :create => :environment do
+ backup_path_db = File.join(Gitlab.config.backup.path, "db")
+ FileUtils.mkdir_p(backup_path_db) unless Dir.exists?(backup_path_db)
+
+ puts "Dumping database tables:"
+ ActiveRecord::Base.connection.tables.each do |tbl|
+ print "- Dumping table #{tbl}... "
+ count = 1
+ File.open(File.join(backup_path_db, tbl + ".yml"), "w+") do |file|
+ ActiveRecord::Base.connection.select_all("SELECT * FROM `#{tbl}`").each do |line|
+ line.delete_if{|k,v| v.blank?}
+ output = {tbl + '_' + count.to_s => line}
+ file << output.to_yaml.gsub(/^---\n/,'') + "\n"
+ count += 1
+ end
+ puts "[DONE]".green
end
- puts "[DONE]".green
end
end
- end
- task :db_restore=> :environment do
- backup_path_db = File.join(Gitlab.config.backup_path, "db")
+ task :restore=> :environment do
+ backup_path_db = File.join(Gitlab.config.backup.path, "db")
- puts "Restoring database tables:"
- Rake::Task["db:reset"].invoke
+ puts "Restoring database tables:"
+ Rake::Task["db:reset"].invoke
- Dir.glob(File.join(backup_path_db, "*.yml") ).each do |dir|
- fixture_file = File.basename(dir, ".*" )
- print "- Loading fixture #{fixture_file}..."
- if File.size(dir) > 0
- ActiveRecord::Fixtures.create_fixtures(backup_path_db, fixture_file)
- puts "[DONE]".green
- else
- puts "[SKIPPING]".yellow
+ Dir.glob(File.join(backup_path_db, "*.yml") ).each do |dir|
+ fixture_file = File.basename(dir, ".*" )
+ print "- Loading fixture #{fixture_file}..."
+ if File.size(dir) > 0
+ ActiveRecord::Fixtures.create_fixtures(backup_path_db, fixture_file)
+ puts "[DONE]".green
+ else
+ puts "[SKIPPING]".yellow
+ end
end
end
end
- end # namespace end: app
+ end # namespace end: backup
end # namespace end: gitlab
diff --git a/lib/tasks/gitlab/bulk_add_permission.rake b/lib/tasks/gitlab/bulk_add_permission.rake
new file mode 100644
index 00000000000..36c51d060bc
--- /dev/null
+++ b/lib/tasks/gitlab/bulk_add_permission.rake
@@ -0,0 +1,24 @@
+namespace :gitlab do
+ namespace :import do
+ desc "GITLAB | Add all users to all projects (admin users are added as masters)"
+ task :all_users_to_all_projects => :environment do |t, args|
+ user_ids = User.where(:admin => false).pluck(:id)
+ admin_ids = User.where(:admin => true).pluck(:id)
+
+ Project.find_each do |project|
+ puts "Importing #{user_ids.size} users into #{project.code}"
+ UsersProject.bulk_import(project, user_ids, UsersProject::DEVELOPER)
+ puts "Importing #{admin_ids.size} admins into #{project.code}"
+ UsersProject.bulk_import(project, admin_ids, UsersProject::MASTER)
+ end
+ end
+
+ desc "GITLAB | Add a specific user to all projects (as a developer)"
+ task :user_to_projects, [:email] => :environment do |t, args|
+ user = User.find_by_email args.email
+ project_ids = Project.pluck(:id)
+
+ UsersProject.user_bulk_import(user, project_ids, UsersProject::DEVELOPER)
+ end
+ end
+end \ No newline at end of file
diff --git a/lib/tasks/gitlab/check.rake b/lib/tasks/gitlab/check.rake
new file mode 100644
index 00000000000..baa706d2bee
--- /dev/null
+++ b/lib/tasks/gitlab/check.rake
@@ -0,0 +1,968 @@
+namespace :gitlab do
+ desc "GITLAB | Check the configuration of GitLab and its environment"
+ task check: %w{gitlab:env:check
+ gitlab:gitolite:check
+ gitlab:resque:check
+ gitlab:app:check}
+
+
+
+ namespace :app do
+ desc "GITLAB | Check the configuration of the GitLab Rails app"
+ task check: :environment do
+ warn_user_is_not_gitlab
+ start_checking "GitLab"
+
+ check_database_config_exists
+ check_database_is_not_sqlite
+ check_migrations_are_up
+ check_gitlab_config_exists
+ check_gitlab_config_not_outdated
+ check_log_writable
+ check_tmp_writable
+ check_init_script_exists
+ check_init_script_up_to_date
+ check_satellites_exist
+
+ finished_checking "GitLab"
+ end
+
+
+ # Checks
+ ########################
+
+ def check_database_config_exists
+ print "Database config exists? ... "
+
+ database_config_file = Rails.root.join("config", "database.yml")
+
+ if File.exists?(database_config_file)
+ puts "yes".green
+ else
+ puts "no".red
+ try_fixing_it(
+ "Copy config/database.yml.<your db> to config/database.yml",
+ "Check that the information in config/database.yml is correct"
+ )
+ for_more_information(
+ see_database_guide,
+ "http://guides.rubyonrails.org/getting_started.html#configuring-a-database"
+ )
+ check_failed
+ end
+ end
+
+ def check_database_is_not_sqlite
+ print "Database is not SQLite ... "
+
+ database_config_file = Rails.root.join("config", "database.yml")
+
+ unless File.read(database_config_file) =~ /sqlite/
+ puts "yes".green
+ else
+ puts "no".red
+ for_more_information(
+ "https://github.com/gitlabhq/gitlabhq/wiki/Migrate-from-SQLite-to-MySQL",
+ see_database_guide
+ )
+ check_failed
+ end
+ end
+
+ def check_gitlab_config_exists
+ print "GitLab config exists? ... "
+
+ gitlab_config_file = Rails.root.join("config", "gitlab.yml")
+
+ if File.exists?(gitlab_config_file)
+ puts "yes".green
+ else
+ puts "no".red
+ try_fixing_it(
+ "Copy config/gitlab.yml.example to config/gitlab.yml",
+ "Update config/gitlab.yml to match your setup"
+ )
+ for_more_information(
+ see_installation_guide_section "GitLab"
+ )
+ check_failed
+ end
+ end
+
+ def check_gitlab_config_not_outdated
+ print "GitLab config outdated? ... "
+
+ gitlab_config_file = Rails.root.join("config", "gitlab.yml")
+ unless File.exists?(gitlab_config_file)
+ puts "can't check because of previous errors".magenta
+ end
+
+ # omniauth or ldap could have been deleted from the file
+ unless Gitlab.config.pre_40_config
+ puts "no".green
+ else
+ puts "yes".red
+ try_fixing_it(
+ "Backup your config/gitlab.yml",
+ "Copy config/gitlab.yml.example to config/gitlab.yml",
+ "Update config/gitlab.yml to match your setup"
+ )
+ for_more_information(
+ see_installation_guide_section "GitLab"
+ )
+ check_failed
+ end
+ end
+
+ def check_init_script_exists
+ print "Init script exists? ... "
+
+ script_path = "/etc/init.d/gitlab"
+
+ if File.exists?(script_path)
+ puts "yes".green
+ else
+ puts "no".red
+ try_fixing_it(
+ "Install the init script"
+ )
+ for_more_information(
+ see_installation_guide_section "Install Init Script"
+ )
+ check_failed
+ end
+ end
+
+ def check_init_script_up_to_date
+ print "Init script up-to-date? ... "
+
+ script_path = "/etc/init.d/gitlab"
+ unless File.exists?(script_path)
+ puts "can't check because of previous errors".magenta
+ return
+ end
+
+ recipe_content = `curl https://raw.github.com/gitlabhq/gitlab-recipes/master/init.d/gitlab 2>/dev/null`
+ script_content = File.read(script_path)
+
+ if recipe_content == script_content
+ puts "yes".green
+ else
+ puts "no".red
+ try_fixing_it(
+ "Redownload the init script"
+ )
+ for_more_information(
+ see_installation_guide_section "Install Init Script"
+ )
+ check_failed
+ end
+ end
+
+ def check_migrations_are_up
+ print "All migrations up? ... "
+
+ migration_status = `bundle exec rake db:migrate:status`
+
+ unless migration_status =~ /down\s+\d{14}/
+ puts "yes".green
+ else
+ puts "no".red
+ try_fixing_it(
+ "sudo -u gitlab -H bundle exec rake db:migrate"
+ )
+ check_failed
+ end
+ end
+
+ def check_satellites_exist
+ print "Projects have satellites? ... "
+
+ unless Project.count > 0
+ puts "can't check, you have no projects".magenta
+ return
+ end
+ puts ""
+
+ Project.find_each(batch_size: 100) do |project|
+ print "#{project.name_with_namespace.yellow} ... "
+
+ if project.satellite.exists?
+ puts "yes".green
+ else
+ puts "no".red
+ try_fixing_it(
+ "sudo -u gitlab -H bundle exec rake gitlab:satellites:create",
+ "If necessary, remove the tmp/repo_satellites directory ...",
+ "... and rerun the above command"
+ )
+ for_more_information(
+ "doc/raketasks/maintenance.md "
+ )
+ check_failed
+ end
+ end
+ end
+
+ def check_log_writable
+ print "Log directory writable? ... "
+
+ log_path = Rails.root.join("log")
+
+ if File.writable?(log_path)
+ puts "yes".green
+ else
+ puts "no".red
+ try_fixing_it(
+ "sudo chown -R gitlab #{log_path}",
+ "sudo chmod -R rwX #{log_path}"
+ )
+ for_more_information(
+ see_installation_guide_section "GitLab"
+ )
+ check_failed
+ end
+ end
+
+ def check_tmp_writable
+ print "Tmp directory writable? ... "
+
+ tmp_path = Rails.root.join("tmp")
+
+ if File.writable?(tmp_path)
+ puts "yes".green
+ else
+ puts "no".red
+ try_fixing_it(
+ "sudo chown -R gitlab #{tmp_path}",
+ "sudo chmod -R rwX #{tmp_path}"
+ )
+ for_more_information(
+ see_installation_guide_section "GitLab"
+ )
+ check_failed
+ end
+ end
+ end
+
+
+
+ namespace :env do
+ desc "GITLAB | Check the configuration of the environment"
+ task check: :environment do
+ warn_user_is_not_gitlab
+ start_checking "Environment"
+
+ check_gitlab_in_git_group
+ check_issue_1056_shell_profile_error
+ check_gitlab_git_config
+ check_python2_exists
+ check_python2_version
+
+ finished_checking "Environment"
+ end
+
+
+ # Checks
+ ########################
+
+ def check_gitlab_git_config
+ print "Git configured for gitlab user? ... "
+
+ options = {
+ "user.name" => "GitLab",
+ "user.email" => Gitlab.config.gitlab.email_from
+ }
+ correct_options = options.map do |name, value|
+ run("git config --global --get #{name}").try(:squish) == value
+ end
+
+ if correct_options.all?
+ puts "yes".green
+ else
+ puts "no".red
+ try_fixing_it(
+ "sudo -u gitlab -H git config --global user.name \"#{options["user.name"]}\"",
+ "sudo -u gitlab -H git config --global user.email \"#{options["user.email"]}\""
+ )
+ for_more_information(
+ see_installation_guide_section "GitLab"
+ )
+ check_failed
+ end
+ end
+
+ def check_gitlab_in_git_group
+ gitolite_ssh_user = Gitlab.config.gitolite.ssh_user
+ print "gitlab user is in #{gitolite_ssh_user} group? ... "
+
+ if run_and_match("id -rnG", /\Wgit\W/)
+ puts "yes".green
+ else
+ puts "no".red
+ try_fixing_it(
+ "sudo usermod -a -G #{gitolite_ssh_user} gitlab"
+ )
+ for_more_information(
+ see_installation_guide_section "System Users"
+ )
+ check_failed
+ end
+ end
+
+ # see https://github.com/gitlabhq/gitlabhq/issues/1059
+ def check_issue_1056_shell_profile_error
+ gitolite_ssh_user = Gitlab.config.gitolite.ssh_user
+ print "Has no \"-e\" in ~#{gitolite_ssh_user}/.profile ... "
+
+ profile_file = File.expand_path("~#{Gitlab.config.gitolite.ssh_user}/.profile")
+
+ unless File.read(profile_file) =~ /^-e PATH/
+ puts "yes".green
+ else
+ puts "no".red
+ try_fixing_it(
+ "Open #{profile_file}",
+ "Find the line starting with \"-e PATH\"",
+ "Remove \"-e \" so the line starts with PATH"
+ )
+ for_more_information(
+ see_installation_guide_section("Gitolite"),
+ "https://github.com/gitlabhq/gitlabhq/issues/1059"
+ )
+ check_failed
+ end
+ end
+
+ def check_python2_exists
+ print "Has python2? ... "
+
+ # Python prints its version to STDERR
+ # so we can't just use run("python2 --version")
+ if run_and_match("which python2", /python2$/)
+ puts "yes".green
+ else
+ puts "no".red
+ try_fixing_it(
+ "Make sure you have Python 2.5+ installed",
+ "Link it to python2"
+ )
+ for_more_information(
+ see_installation_guide_section "Packages / Dependencies"
+ )
+ check_failed
+ end
+ end
+
+ def check_python2_version
+ print "python2 is supported version? ... "
+
+ # Python prints its version to STDERR
+ # so we can't just use run("python2 --version")
+
+ unless run_and_match("which python2", /python2$/)
+ puts "can't check because of previous errors".magenta
+ return
+ end
+
+ if `python2 --version 2>&1` =~ /2\.[567]\.\d/
+ puts "yes".green
+ else
+ puts "no".red
+ try_fixing_it(
+ "Make sure you have Python 2.5+ installed",
+ "Link it to python2"
+ )
+ for_more_information(
+ see_installation_guide_section "Packages / Dependencies"
+ )
+ check_failed
+ end
+ end
+ end
+
+
+
+ namespace :gitolite do
+ desc "GITLAB | Check the configuration of Gitolite"
+ task check: :environment do
+ warn_user_is_not_gitlab
+ start_checking "Gitolite"
+
+ check_gitolite_is_up_to_date
+ check_gitoliterc_repo_umask
+ check_gitoliterc_git_config_keys
+ check_dot_gitolite_exists
+ check_dot_gitolite_user_and_group
+ check_dot_gitolite_permissions
+ check_repo_base_exists
+ check_repo_base_user_and_group
+ check_repo_base_permissions
+ check_can_clone_gitolite_admin
+ check_can_commit_to_gitolite_admin
+ check_post_receive_hook_exists
+ check_post_receive_hook_is_up_to_date
+ check_repos_post_receive_hooks_is_link
+ check_repos_git_config
+
+ finished_checking "Gitolite"
+ end
+
+
+ # Checks
+ ########################
+
+ def check_can_clone_gitolite_admin
+ print "Can clone gitolite-admin? ... "
+
+ test_path = "/tmp/gitlab_gitolite_admin_test"
+ FileUtils.rm_rf(test_path)
+ `git clone -q #{Gitlab.config.gitolite.admin_uri} #{test_path}`
+ raise unless $?.success?
+
+ puts "yes".green
+ rescue
+ puts "no".red
+ try_fixing_it(
+ "Make sure the \"admin_uri\" is set correctly in config/gitlab.yml",
+ "Try cloning it yourself with:",
+ " git clone -q #{Gitlab.config.gitolite.admin_uri} /tmp/gitolite-admin",
+ "Make sure Gitolite is installed correctly."
+ )
+ for_more_information(
+ see_installation_guide_section "Gitolite"
+ )
+ check_failed
+ end
+
+ # assumes #check_can_clone_gitolite_admin has been run before
+ def check_can_commit_to_gitolite_admin
+ print "Can commit to gitolite-admin? ... "
+
+ test_path = "/tmp/gitlab_gitolite_admin_test"
+ unless File.exists?(test_path)
+ puts "can't check because of previous errors".magenta
+ return
+ end
+
+ Dir.chdir(test_path) do
+ `touch foo && git add foo && git commit -qm foo`
+ raise unless $?.success?
+ end
+
+ puts "yes".green
+ rescue
+ puts "no".red
+ try_fixing_it(
+ "Try committing to it yourself with:",
+ " git clone -q #{Gitlab.config.gitolite.admin_uri} /tmp/gitolite-admin",
+ " touch foo",
+ " git add foo",
+ " git commit -m \"foo\"",
+ "Make sure Gitolite is installed correctly."
+ )
+ for_more_information(
+ see_installation_guide_section "Gitolite"
+ )
+ check_failed
+ ensure
+ FileUtils.rm_rf("/tmp/gitolite_gitlab_test")
+ end
+
+ def check_dot_gitolite_exists
+ print "Config directory exists? ... "
+
+ gitolite_config_path = File.expand_path("~#{Gitlab.config.gitolite.ssh_user}/.gitolite")
+
+ if File.directory?(gitolite_config_path)
+ puts "yes".green
+ else
+ puts "no".red
+ puts "#{gitolite_config_path} is missing".red
+ try_fixing_it(
+ "This should have been created when setting up Gitolite.",
+ "Make sure Gitolite is installed correctly."
+ )
+ for_more_information(
+ see_installation_guide_section "Gitolite"
+ )
+ check_failed
+ end
+ end
+
+ def check_dot_gitolite_permissions
+ print "Config directory access is drwxr-x---? ... "
+
+ gitolite_config_path = File.expand_path("~#{Gitlab.config.gitolite.ssh_user}/.gitolite")
+ unless File.exists?(gitolite_config_path)
+ puts "can't check because of previous errors".magenta
+ return
+ end
+
+ if `stat --printf %a #{gitolite_config_path}` == "750"
+ puts "yes".green
+ else
+ puts "no".red
+ puts "#{gitolite_config_path} is not writable".red
+ try_fixing_it(
+ "sudo chmod 750 #{gitolite_config_path}"
+ )
+ for_more_information(
+ see_installation_guide_section "Gitolite"
+ )
+ check_failed
+ end
+ end
+
+ def check_dot_gitolite_user_and_group
+ gitolite_ssh_user = Gitlab.config.gitolite.ssh_user
+ print "Config directory owned by #{gitolite_ssh_user}:#{gitolite_ssh_user} ... "
+
+ gitolite_config_path = File.expand_path("~#{gitolite_ssh_user}/.gitolite")
+ unless File.exists?(gitolite_config_path)
+ puts "can't check because of previous errors".magenta
+ return
+ end
+
+ if `stat --printf %U #{gitolite_config_path}` == gitolite_ssh_user && # user
+ `stat --printf %G #{gitolite_config_path}` == gitolite_ssh_user #group
+ puts "yes".green
+ else
+ puts "no".red
+ puts "#{gitolite_config_path} is not owned by #{gitolite_ssh_user}".red
+ try_fixing_it(
+ "sudo chown -R #{gitolite_ssh_user}:#{gitolite_ssh_user} #{gitolite_config_path}"
+ )
+ for_more_information(
+ see_installation_guide_section "Gitolite"
+ )
+ check_failed
+ end
+ end
+
+ def check_gitolite_is_up_to_date
+ print "Using recommended version ... "
+ if gitolite_version.try(:start_with?, "v3.04")
+ puts "yes".green
+ else
+ puts "no".red
+ try_fixing_it(
+ "We strongly recommend using the version pointed out in the installation guide."
+ )
+ for_more_information(
+ see_installation_guide_section "Gitolite"
+ )
+ # this is not a "hard" failure
+ end
+ end
+
+ def check_gitoliterc_git_config_keys
+ gitoliterc_path = File.join(gitolite_home, ".gitolite.rc")
+
+ print "Allow all Git config keys in .gitolite.rc ... "
+ option_name = if has_gitolite3?
+ # see https://github.com/sitaramc/gitolite/blob/v3.04/src/lib/Gitolite/Rc.pm#L329
+ "GIT_CONFIG_KEYS"
+ else
+ # assume older version
+ # see https://github.com/sitaramc/gitolite/blob/v2.3/conf/example.gitolite.rc#L49
+ "$GL_GITCONFIG_KEYS"
+ end
+ option_value = ".*"
+ if open(gitoliterc_path).grep(/#{option_name}\s*=[>]?\s*["']#{option_value}["']/).any?
+ puts "yes".green
+ else
+ puts "no".red
+ try_fixing_it(
+ "Open #{gitoliterc_path}",
+ "Find the \"#{option_name}\" option",
+ "Change its value to \".*\""
+ )
+ for_more_information(
+ see_installation_guide_section "Gitolite"
+ )
+ check_failed
+ end
+ end
+
+ def check_gitoliterc_repo_umask
+ gitoliterc_path = File.join(gitolite_home, ".gitolite.rc")
+
+ print "Repo umask is 0007 in .gitolite.rc? ... "
+ option_name = if has_gitolite3?
+ # see https://github.com/sitaramc/gitolite/blob/v3.04/src/lib/Gitolite/Rc.pm#L328
+ "UMASK"
+ else
+ # assume older version
+ # see https://github.com/sitaramc/gitolite/blob/v2.3/conf/example.gitolite.rc#L32
+ "$REPO_UMASK"
+ end
+ option_value = "0007"
+ if open(gitoliterc_path).grep(/#{option_name}\s*=[>]?\s*#{option_value}/).any?
+ puts "yes".green
+ else
+ puts "no".red
+ try_fixing_it(
+ "Open #{gitoliterc_path}",
+ "Find the \"#{option_name}\" option",
+ "Change its value to \"0007\""
+ )
+ for_more_information(
+ see_installation_guide_section "Gitolite"
+ )
+ check_failed
+ end
+ end
+
+ def check_post_receive_hook_exists
+ print "post-receive hook exists? ... "
+
+ hook_file = "post-receive"
+ gitolite_hooks_path = File.join(Gitlab.config.gitolite.hooks_path, "common")
+ gitolite_hook_file = File.join(gitolite_hooks_path, hook_file)
+ gitolite_ssh_user = Gitlab.config.gitolite.ssh_user
+
+ gitlab_hook_file = Rails.root.join.join("lib", "hooks", hook_file)
+
+ if File.exists?(gitolite_hook_file)
+ puts "yes".green
+ else
+ puts "no".red
+ try_fixing_it(
+ "sudo -u #{gitolite_ssh_user} cp #{gitlab_hook_file} #{gitolite_hook_file}"
+ )
+ for_more_information(
+ see_installation_guide_section "Setup GitLab Hooks"
+ )
+ check_failed
+ end
+ end
+
+ def check_post_receive_hook_is_up_to_date
+ print "post-receive hook up-to-date? ... "
+
+ hook_file = "post-receive"
+ gitolite_hooks_path = File.join(Gitlab.config.gitolite.hooks_path, "common")
+ gitolite_hook_file = File.join(gitolite_hooks_path, hook_file)
+ gitolite_hook_content = File.read(gitolite_hook_file)
+ gitolite_ssh_user = Gitlab.config.gitolite.ssh_user
+
+ unless File.exists?(gitolite_hook_file)
+ puts "can't check because of previous errors".magenta
+ return
+ end
+
+ gitlab_hook_file = Rails.root.join.join("lib", "hooks", hook_file)
+ gitlab_hook_content = File.read(gitlab_hook_file)
+
+ if gitolite_hook_content == gitlab_hook_content
+ puts "yes".green
+ else
+ puts "no".red
+ try_fixing_it(
+ "sudo -u #{gitolite_ssh_user} cp #{gitlab_hook_file} #{gitolite_hook_file}"
+ )
+ for_more_information(
+ see_installation_guide_section "Setup GitLab Hooks"
+ )
+ check_failed
+ end
+ end
+
+ def check_repo_base_exists
+ print "Repo base directory exists? ... "
+
+ repo_base_path = Gitlab.config.gitolite.repos_path
+
+ if File.exists?(repo_base_path)
+ puts "yes".green
+ else
+ puts "no".red
+ puts "#{repo_base_path} is missing".red
+ try_fixing_it(
+ "This should have been created when setting up Gitolite.",
+ "Make sure it's set correctly in config/gitlab.yml",
+ "Make sure Gitolite is installed correctly."
+ )
+ for_more_information(
+ see_installation_guide_section "Gitolite"
+ )
+ check_failed
+ end
+ end
+
+ def check_repo_base_permissions
+ print "Repo base access is drwsrws---? ... "
+
+ repo_base_path = Gitlab.config.gitolite.repos_path
+ unless File.exists?(repo_base_path)
+ puts "can't check because of previous errors".magenta
+ return
+ end
+
+ if `stat --printf %a #{repo_base_path}` == "6770"
+ puts "yes".green
+ else
+ puts "no".red
+ puts "#{repo_base_path} is not writable".red
+ try_fixing_it(
+ "sudo chmod -R ug+rwXs,o-rwx #{repo_base_path}"
+ )
+ for_more_information(
+ see_installation_guide_section "Gitolite"
+ )
+ check_failed
+ end
+ end
+
+ def check_repo_base_user_and_group
+ gitolite_ssh_user = Gitlab.config.gitolite.ssh_user
+ print "Repo base owned by #{gitolite_ssh_user}:#{gitolite_ssh_user}? ... "
+
+ repo_base_path = Gitlab.config.gitolite.repos_path
+ unless File.exists?(repo_base_path)
+ puts "can't check because of previous errors".magenta
+ return
+ end
+
+ if `stat --printf %U #{repo_base_path}` == gitolite_ssh_user && # user
+ `stat --printf %G #{repo_base_path}` == gitolite_ssh_user #group
+ puts "yes".green
+ else
+ puts "no".red
+ puts "#{repo_base_path} is not owned by #{gitolite_ssh_user}".red
+ try_fixing_it(
+ "sudo chown -R #{gitolite_ssh_user}:#{gitolite_ssh_user} #{repo_base_path}"
+ )
+ for_more_information(
+ see_installation_guide_section "Gitolite"
+ )
+ check_failed
+ end
+ end
+
+ def check_repos_git_config
+ print "Git config in repos: ... "
+
+ unless Project.count > 0
+ puts "can't check, you have no projects".magenta
+ return
+ end
+ puts ""
+
+ options = {
+ "core.sharedRepository" => "0660",
+ }
+
+ Project.find_each(batch_size: 100) do |project|
+ print "#{project.name_with_namespace.yellow} ... "
+
+ correct_options = options.map do |name, value|
+ run("git --git-dir=\"#{project.path_to_repo}\" config --get #{name}").try(:chomp) == value
+ end
+
+ if correct_options.all?
+ puts "ok".green
+ else
+ puts "wrong or missing".red
+ try_fixing_it(
+ "sudo -u gitlab -H bundle exec rake gitlab:gitolite:update_repos"
+ )
+ for_more_information(
+ "doc/raketasks/maintenance.md"
+ )
+ check_failed
+ end
+ end
+ end
+
+ def check_repos_post_receive_hooks_is_link
+ print "post-receive hooks in repos are links: ... "
+
+ hook_file = "post-receive"
+ gitolite_hooks_path = File.join(Gitlab.config.gitolite.hooks_path, "common")
+ gitolite_hook_file = File.join(gitolite_hooks_path, hook_file)
+ gitolite_ssh_user = Gitlab.config.gitolite.ssh_user
+
+ unless File.exists?(gitolite_hook_file)
+ puts "can't check because of previous errors".magenta
+ return
+ end
+
+ unless Project.count > 0
+ puts "can't check, you have no projects".magenta
+ return
+ end
+ puts ""
+
+ Project.find_each(batch_size: 100) do |project|
+ print "#{project.name_with_namespace.yellow} ... "
+ project_hook_file = File.join(project.path_to_repo, "hooks", hook_file)
+
+ unless File.exists?(project_hook_file)
+ puts "missing".red
+ try_fixing_it(
+ "sudo -u #{gitolite_ssh_user} ln -sf #{gitolite_hook_file} #{project_hook_file}"
+ )
+ for_more_information(
+ "lib/support/rewrite-hooks.sh"
+ )
+ check_failed
+ next
+ end
+
+ if run_and_match("stat --format %N #{project_hook_file}", /#{hook_file}.+->.+#{gitolite_hook_file}/)
+ puts "ok".green
+ else
+ puts "not a link to Gitolite's hook".red
+ try_fixing_it(
+ "sudo -u #{gitolite_ssh_user} ln -sf #{gitolite_hook_file} #{project_hook_file}"
+ )
+ for_more_information(
+ "lib/support/rewrite-hooks.sh"
+ )
+ check_failed
+ end
+ end
+ end
+
+
+ # Helper methods
+ ########################
+
+ def gitolite_home
+ File.expand_path("~#{Gitlab.config.gitolite.ssh_user}")
+ end
+
+ def gitolite_version
+ gitolite_version_file = "#{gitolite_home}/gitolite/src/VERSION"
+ if File.readable?(gitolite_version_file)
+ File.read(gitolite_version_file)
+ end
+ end
+
+ def has_gitolite3?
+ gitolite_version.try(:start_with?, "v3.")
+ end
+ end
+
+
+
+ namespace :resque do
+ desc "GITLAB | Check the configuration of Resque"
+ task check: :environment do
+ warn_user_is_not_gitlab
+ start_checking "Resque"
+
+ check_resque_running
+
+ finished_checking "Resque"
+ end
+
+
+ # Checks
+ ########################
+
+ def check_resque_running
+ print "Running? ... "
+
+ if run_and_match("ps aux | grep -i resque", /resque-[\d\.]+:.+$/)
+ puts "yes".green
+ else
+ puts "no".red
+ try_fixing_it(
+ "sudo service gitlab restart",
+ "or",
+ "sudo /etc/init.d/gitlab restart"
+ )
+ for_more_information(
+ see_installation_guide_section("Install Init Script"),
+ "see log/resque.log for possible errors"
+ )
+ check_failed
+ end
+ end
+ end
+
+
+ # Helper methods
+ ##########################
+
+ def check_failed
+ puts " Please #{"fix the error above"} and rerun the checks.".red
+ end
+
+ def for_more_information(*sources)
+ sources = sources.shift if sources.first.is_a?(Array)
+
+ puts " For more information see:".blue
+ sources.each do |source|
+ puts " #{source}"
+ end
+ end
+
+ def finished_checking(component)
+ puts ""
+ puts "Checking #{component.yellow} ... #{"Finished".green}"
+ puts ""
+ end
+
+ # Runs the given command
+ #
+ # Returns nil if the command was not found
+ # Returns the output of the command otherwise
+ #
+ # see also #run_and_match
+ def run(command)
+ unless `#{command} 2>/dev/null`.blank?
+ `#{command}`
+ end
+ end
+
+ # Runs the given command and matches the output agains the given pattern
+ #
+ # Returns nil if nothing matched
+ # Retunrs the MatchData if the pattern matched
+ #
+ # see also #run
+ # see also String#match
+ def run_and_match(command, pattern)
+ run(command).try(:match, pattern)
+ end
+
+ def see_database_guide
+ "doc/install/databases.md"
+ end
+
+ def see_installation_guide_section(section)
+ "doc/install/installation.md in section \"#{section}\""
+ end
+
+ def start_checking(component)
+ puts "Checking #{component.yellow} ..."
+ puts ""
+ end
+
+ def try_fixing_it(*steps)
+ steps = steps.shift if steps.first.is_a?(Array)
+
+ puts " Try fixing it:".blue
+ steps.each do |step|
+ puts " #{step}"
+ end
+ end
+
+ def warn_user_is_not_gitlab
+ unless @warned_user_not_gitlab
+ current_user = run("whoami").chomp
+ unless current_user == "gitlab"
+ puts "#{Colored.color(:black)+Colored.color(:on_yellow)} Warning #{Colored.extra(:clear)}"
+ puts " You are running as user #{current_user.magenta}, we hope you know what you are doing."
+ puts " Some tests may pass\/fail for the wrong reason."
+ puts " For meaningful results you should run this as user #{"gitlab".magenta}."
+ puts ""
+ end
+ @warned_user_not_gitlab = true
+ end
+ end
+end
diff --git a/lib/tasks/gitlab/enable_automerge.rake b/lib/tasks/gitlab/enable_automerge.rake
index 13b4bab6edc..ed3d6368a99 100644
--- a/lib/tasks/gitlab/enable_automerge.rake
+++ b/lib/tasks/gitlab/enable_automerge.rake
@@ -1,17 +1,20 @@
namespace :gitlab do
- namespace :app do
- desc "GITLAB | Enable auto merge"
- task :enable_automerge => :environment do
- Gitlab::Gitolite.new.enable_automerge
+ desc "GITLAB | Enable auto merge"
+ task :enable_automerge => :environment do
+ Gitlab::Gitolite.new.enable_automerge
- Project.find_each do |project|
- if project.repo_exists? && !project.satellite.exists?
- puts "Creating satellite for #{project.name}...".green
- project.satellite.create
- end
+ Project.find_each do |project|
+ if project.repo_exists? && !project.satellite.exists?
+ puts "Creating satellite for #{project.name}...".green
+ project.satellite.create
end
-
- puts "Done!".green
end
+
+ puts "Done!".green
+ end
+
+ namespace :satellites do
+ desc "GITLAB | Create satellite repos"
+ task create: 'gitlab:enable_automerge'
end
end
diff --git a/lib/tasks/gitlab/activate_namespaces.rake b/lib/tasks/gitlab/enable_namespaces.rake
index 08df0a8040b..1be9ba6469d 100644
--- a/lib/tasks/gitlab/activate_namespaces.rake
+++ b/lib/tasks/gitlab/enable_namespaces.rake
@@ -1,6 +1,6 @@
namespace :gitlab do
desc "GITLAB | Enable usernames and namespaces for user projects"
- task activate_namespaces: :environment do
+ task enable_namespaces: :environment do
print "\nUsernames for users:".yellow
User.find_each(batch_size: 500) do |user|
@@ -27,7 +27,7 @@ namespace :gitlab do
end
print "\n\nMove projects from groups under groups dirs:".yellow
- git_path = Gitlab.config.git_base_path
+ git_path = Gitlab.config.gitolite.repos_path
Project.where('namespace_id IS NOT NULL').find_each(batch_size: 500) do |project|
next unless project.group
diff --git a/lib/tasks/gitlab/import.rake b/lib/tasks/gitlab/import.rake
index 09f0dc9e459..81f66e2e406 100644
--- a/lib/tasks/gitlab/import.rake
+++ b/lib/tasks/gitlab/import.rake
@@ -12,7 +12,7 @@ namespace :gitlab do
desc "GITLAB | Import bare repositories from git_host -> base_path into GitLab project instance"
task :repos => :environment do
- git_base_path = Gitlab.config.git_base_path
+ git_base_path = Gitlab.config.gitolite.repos_path
repos_to_import = Dir.glob(git_base_path + '/*')
repos_to_import.each do |repo_path|
diff --git a/lib/tasks/gitlab/info.rake b/lib/tasks/gitlab/info.rake
index 231c05b4c59..85458fe2c43 100644
--- a/lib/tasks/gitlab/info.rake
+++ b/lib/tasks/gitlab/info.rake
@@ -16,6 +16,8 @@ namespace :gitlab do
# check if there is an RVM environment
rvm_version = run_and_match("rvm --version", /[\d\.]+/).try(:to_s)
+ # check Ruby version
+ ruby_version = run_and_match("ruby --version", /[\d\.p]+/).try(:to_s)
# check Gem version
gem_version = run("gem --version")
# check Bundler version
@@ -29,7 +31,7 @@ namespace :gitlab do
puts "Current User:\t#{`whoami`}"
puts "Using RVM:\t#{rvm_version.present? ? "yes".green : "no"}"
puts "RVM Version:\t#{rvm_version}" if rvm_version.present?
- puts "Ruby Version:\t#{ENV['RUBY_VERSION'] || "unknown".red}"
+ puts "Ruby Version:\t#{ruby_version || "unknown".red}"
puts "Gem Version:\t#{gem_version || "unknown".red}"
puts "Bundler Version:#{bunder_version || "unknown".red}"
puts "Rake Version:\t#{rake_version || "unknown".red}"
@@ -44,23 +46,26 @@ namespace :gitlab do
http_clone_url = project.http_url_to_repo
ssh_clone_url = project.ssh_url_to_repo
+ omniauth_providers = Gitlab.config.omniauth.providers
+ omniauth_providers.map! { |provider| provider['name'] }
+
puts ""
puts "GitLab information".yellow
puts "Version:\t#{Gitlab::Version}"
puts "Revision:\t#{Gitlab::Revision}"
puts "Directory:\t#{Rails.root}"
puts "DB Adapter:\t#{database_adapter}"
- puts "URL:\t\t#{Gitlab.config.url}"
+ puts "URL:\t\t#{Gitlab.config.gitlab.url}"
puts "HTTP Clone URL:\t#{http_clone_url}"
puts "SSH Clone URL:\t#{ssh_clone_url}"
- puts "Using LDAP:\t#{Gitlab.config.ldap_enabled? ? "yes".green : "no"}"
- puts "Using Omniauth:\t#{Gitlab.config.omniauth_enabled? ? "yes".green : "no"}"
- puts "Omniauth Providers:\t#{Gitlab.config.omniauth_providers}" if Gitlab.config.omniauth_enabled?
+ puts "Using LDAP:\t#{Gitlab.config.ldap.enabled ? "yes".green : "no"}"
+ puts "Using Omniauth:\t#{Gitlab.config.omniauth.enabled ? "yes".green : "no"}"
+ puts "Omniauth Providers: #{omniauth_providers.map(&:magenta).join(', ')}" if Gitlab.config.omniauth.enabled
# check Gitolite version
- gitolite_version_file = "#{Gitlab.config.git_base_path}/../gitolite/src/VERSION"
+ gitolite_version_file = "#{Gitlab.config.gitolite.repos_path}/../gitolite/src/VERSION"
if File.exists?(gitolite_version_file) && File.readable?(gitolite_version_file)
gitolite_version = File.read(gitolite_version_file)
end
@@ -68,18 +73,24 @@ namespace :gitlab do
puts ""
puts "Gitolite information".yellow
puts "Version:\t#{gitolite_version || "unknown".red}"
- puts "Admin URI:\t#{Gitlab.config.gitolite_admin_uri}"
- puts "Admin Key:\t#{Gitlab.config.gitolite_admin_key}"
- puts "Repositories:\t#{Gitlab.config.git_base_path}"
- puts "Hooks:\t\t#{Gitlab.config.git_hooks_path}"
- puts "Git:\t\t#{Gitlab.config.git.path}"
+ puts "Admin URI:\t#{Gitlab.config.gitolite.admin_uri}"
+ puts "Admin Key:\t#{Gitlab.config.gitolite.admin_key}"
+ puts "Repositories:\t#{Gitlab.config.gitolite.repos_path}"
+ puts "Hooks:\t\t#{Gitlab.config.gitolite.hooks_path}"
+ puts "Git:\t\t#{Gitlab.config.git.bin_path}"
end
# Helper methods
- # Runs the given command and matches the output agains the given RegExp
+ # Runs the given command and matches the output agains the given pattern
+ #
+ # Returns nil if nothing matched
+ # Retunrs the MatchData if the pattern matched
+ #
+ # see also #run
+ # see also String#match
def run_and_match(command, regexp)
run(command).try(:match, regexp)
end
@@ -88,6 +99,8 @@ namespace :gitlab do
#
# Returns nil if the command was not found
# Returns the output of the command otherwise
+ #
+ # see also #run_and_match
def run(command)
unless `#{command} 2>/dev/null`.blank?
`#{command}`
diff --git a/lib/tasks/gitlab/setup.rake b/lib/tasks/gitlab/setup.rake
index 08f35c7e3f0..572a22aa1f6 100644
--- a/lib/tasks/gitlab/setup.rake
+++ b/lib/tasks/gitlab/setup.rake
@@ -4,7 +4,7 @@ namespace :gitlab do
task :setup => [
'db:setup',
'db:seed_fu',
- 'gitlab:app:enable_automerge'
+ 'gitlab:enable_automerge'
]
end
end
diff --git a/lib/tasks/gitlab/status.rake b/lib/tasks/gitlab/status.rake
deleted file mode 100644
index cbc77abb97a..00000000000
--- a/lib/tasks/gitlab/status.rake
+++ /dev/null
@@ -1,113 +0,0 @@
-namespace :gitlab do
- namespace :app do
- desc "GITLAB | Check GitLab installation status"
- task :status => :environment do
- puts "\nStarting diagnostics".yellow
- git_base_path = Gitlab.config.git_base_path
-
- print "config/database.yml............"
- if File.exists?(Rails.root.join "config", "database.yml")
- puts "exists".green
- else
- puts "missing".red
- return
- end
-
- print "config/gitlab.yml............"
- if File.exists?(Rails.root.join "config", "gitlab.yml")
- puts "exists".green
- else
- puts "missing".red
- return
- end
-
- print "#{git_base_path}............"
- if File.exists?(git_base_path)
- puts "exists".green
- else
- puts "missing".red
- return
- end
-
- print "#{git_base_path} is writable?............"
- if File.stat(git_base_path).writable?
- puts "YES".green
- else
- puts "NO".red
- return
- end
-
- FileUtils.rm_rf("/tmp/gitolite_gitlab_test")
- begin
- `git clone -q #{Gitlab.config.gitolite_admin_uri} /tmp/gitolite_gitlab_test`
- raise unless $?.success?
- print "Can clone gitolite-admin?............"
- puts "YES".green
- rescue
- print "Can clone gitolite-admin?............"
- puts "NO".red
- return
- end
-
- begin
- Dir.chdir("/tmp/gitolite_gitlab_test") do
- `touch blah && git add blah && git commit -qm blah -- blah`
- raise unless $?.success?
- end
- print "Can git commit?............"
- puts "YES".green
- rescue
- print "Can git commit?............"
- puts "NO".red
- return
- ensure
- FileUtils.rm_rf("/tmp/gitolite_gitlab_test")
- end
-
- print "UMASK for .gitolite.rc is 0007? ............"
- if open(File.absolute_path("#{git_base_path}/../.gitolite.rc")).grep(/UMASK([ \t]*)=([ \t>]*)0007/).any?
- puts "YES".green
- else
- puts "NO".red
- return
- end
-
- gitolite_hooks_path = File.join(Gitlab.config.git_hooks_path, "common")
- gitlab_hook_files = ['post-receive']
- gitlab_hook_files.each do |file_name|
- dest = File.join(gitolite_hooks_path, file_name)
- print "#{dest} exists? ............"
- if File.exists?(dest)
- puts "YES".green
- else
- puts "NO".red
- return
- end
- end
-
- if Project.count > 0
- puts "\nValidating projects repositories:".yellow
- Project.find_each(:batch_size => 100) do |project|
- print "* #{project.name}....."
- hook_file = File.join(project.path_to_repo, 'hooks', 'post-receive')
-
- unless File.exists?(hook_file)
- puts "post-receive file missing".red
- next
- end
-
- original_content = File.read(Rails.root.join('lib', 'hooks', 'post-receive'))
- new_content = File.read(hook_file)
-
- if original_content == new_content
- puts "post-receive file ok".green
- else
- puts "post-receive file content does not match".red
- end
- end
- end
-
- puts "\nFinished".blue
- end
- end
-end
diff --git a/lib/tasks/resque.rake b/lib/tasks/resque.rake
index e6987e17639..0825324a424 100644
--- a/lib/tasks/resque.rake
+++ b/lib/tasks/resque.rake
@@ -1,12 +1,8 @@
require 'resque/tasks'
-# Fix Exception
-# ActiveRecord::StatementInvalid
-# Error
-# PGError: ERROR: prepared statement "a3" already exists
task "resque:setup" => :environment do
- Resque.after_fork do |job|
- ActiveRecord::Base.establish_connection
+ Resque.after_fork do
+ Resque.redis.client.reconnect
end
end
diff --git a/lib/tasks/travis.rake b/lib/tasks/travis.rake
index 13e32135c66..e04bfbaf1c0 100644
--- a/lib/tasks/travis.rake
+++ b/lib/tasks/travis.rake
@@ -1,5 +1,5 @@
task :travis do
- ["spinach", "rspec spec"].each do |cmd|
+ ["rake spinach", "rake spec"].each do |cmd|
puts "Starting to run #{cmd}..."
system("export DISPLAY=:99.0 && bundle exec #{cmd}")
raise "#{cmd} failed!" unless $?.exitstatus == 0
diff --git a/spec/helpers/application_helper_spec.rb b/spec/helpers/application_helper_spec.rb
index df66e3b48bd..ba1af08421b 100644
--- a/spec/helpers/application_helper_spec.rb
+++ b/spec/helpers/application_helper_spec.rb
@@ -43,7 +43,7 @@ describe ApplicationHelper do
let(:user_email) { 'user@email.com' }
it "should return a generic avatar path when Gravatar is disabled" do
- Gitlab.config.stub(:disable_gravatar?).and_return(true)
+ Gitlab.config.gravatar.stub(:enabled).and_return(false)
gravatar_icon(user_email).should == 'no_avatar.png'
end
@@ -63,7 +63,7 @@ describe ApplicationHelper do
it "should return custom gravatar path when gravatar_url is set" do
stub!(:request).and_return(double(:ssl? => false))
- Gitlab.config.stub(:gravatar_url).and_return('http://example.local/?s=%{size}&hash=%{hash}')
+ Gitlab.config.gravatar.stub(:plain_url).and_return('http://example.local/?s=%{size}&hash=%{hash}')
gravatar_icon(user_email, 20).should == 'http://example.local/?s=20&hash=b58c6f14d292556214bd64909bcdb118'
end
diff --git a/spec/lib/gitolite_spec.rb b/spec/lib/gitolite_spec.rb
index cc8ce8b2cce..8075b99ed99 100644
--- a/spec/lib/gitolite_spec.rb
+++ b/spec/lib/gitolite_spec.rb
@@ -16,7 +16,7 @@ describe Gitlab::Gitolite do
it { should respond_to :create_repository }
it { should respond_to :remove_repository }
- it { gitolite.url_to_repo('diaspora').should == Gitlab.config.ssh_path + "diaspora.git" }
+ it { gitolite.url_to_repo('diaspora').should == Gitlab.config.gitolite.ssh_path_prefix + "diaspora.git" }
it "should call config update" do
gitolite_config.should_receive(:update_project!)
diff --git a/spec/lib/project_mover_spec.rb b/spec/lib/project_mover_spec.rb
index af24635d82b..2362bc2667b 100644
--- a/spec/lib/project_mover_spec.rb
+++ b/spec/lib/project_mover_spec.rb
@@ -6,7 +6,7 @@ describe Gitlab::ProjectMover do
before do
FileUtils.rm_rf base_path if File.exists? base_path
- Gitlab.config.stub(git_base_path: base_path)
+ Gitlab.config.gitolite.stub(repos_path: base_path)
@project = create(:project)
end
diff --git a/spec/models/event_spec.rb b/spec/models/event_spec.rb
index 49cb49db375..82b46b68b64 100644
--- a/spec/models/event_spec.rb
+++ b/spec/models/event_spec.rb
@@ -59,7 +59,7 @@ describe Event do
end
it { @event.push?.should be_true }
- it { @event.allowed?.should be_true }
+ it { @event.proper?.should be_true }
it { @event.new_branch?.should be_true }
it { @event.tag?.should be_false }
it { @event.branch_name.should == "master" }
diff --git a/spec/models/merge_request_spec.rb b/spec/models/merge_request_spec.rb
index d70647f668d..a0849401254 100644
--- a/spec/models/merge_request_spec.rb
+++ b/spec/models/merge_request_spec.rb
@@ -42,7 +42,7 @@ describe MergeRequest do
before do
merge_request.stub(:commits) { [merge_request.project.commit] }
- create(:note, noteable: merge_request.commits.first)
+ create(:note, commit_id: merge_request.commits.first.id, noteable_type: 'Commit')
create(:note, noteable: merge_request)
end
diff --git a/spec/models/note_spec.rb b/spec/models/note_spec.rb
index 4f9352b9a14..61aaf6455eb 100644
--- a/spec/models/note_spec.rb
+++ b/spec/models/note_spec.rb
@@ -81,18 +81,18 @@ describe Note do
describe "Commit notes" do
before do
@note = create(:note,
- noteable_id: commit.id,
+ commit_id: commit.id,
noteable_type: "Commit")
end
it "should be accessible through #noteable" do
- @note.noteable_id.should == commit.id
+ @note.commit_id.should == commit.id
@note.noteable.should be_a(Commit)
@note.noteable.should == commit
end
it "should save a valid note" do
- @note.noteable_id.should == commit.id
+ @note.commit_id.should == commit.id
@note.noteable == commit
end
@@ -104,13 +104,13 @@ describe Note do
describe "Pre-line commit notes" do
before do
@note = create(:note,
- noteable_id: commit.id,
+ commit_id: commit.id,
noteable_type: "Commit",
line_code: "0_16_1")
end
it "should save a valid note" do
- @note.noteable_id.should == commit.id
+ @note.commit_id.should == commit.id
@note.noteable.id.should == commit.id
end
diff --git a/spec/models/project_hooks_spec.rb b/spec/models/project_hooks_spec.rb
index 7c8f05b17a3..df6a3831e30 100644
--- a/spec/models/project_hooks_spec.rb
+++ b/spec/models/project_hooks_spec.rb
@@ -108,7 +108,7 @@ describe Project, "Hooks" do
it { should include(id: @commit.id) }
it { should include(message: @commit.safe_message) }
it { should include(timestamp: @commit.date.xmlschema) }
- it { should include(url: "#{Gitlab.config.url}/#{project.code}/commits/#{@commit.id}") }
+ it { should include(url: "#{Gitlab.config.gitlab.url}/#{project.code}/commit/#{@commit.id}") }
context "with a author" do
subject { @data[:commits].first[:author] }
diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb
index db0d30727b4..83a76976098 100644
--- a/spec/models/project_spec.rb
+++ b/spec/models/project_spec.rb
@@ -129,6 +129,13 @@ describe Project do
it { should respond_to(:execute_hooks) }
it { should respond_to(:post_receive_data) }
it { should respond_to(:trigger_post_receive) }
+
+ # Namespaced Project Role
+ it { should respond_to(:transfer) }
+ it { should respond_to(:name_with_namespace) }
+ it { should respond_to(:namespace_owner) }
+ it { should respond_to(:chief) }
+ it { should respond_to(:path_with_namespace) }
end
describe 'modules' do
@@ -136,11 +143,12 @@ describe Project do
it { should include_module(PushObserver) }
it { should include_module(Authority) }
it { should include_module(Team) }
+ it { should include_module(NamespacedProject) }
end
it "should return valid url to repo" do
project = Project.new(path: "somewhere")
- project.url_to_repo.should == Gitlab.config.ssh_path + "somewhere.git"
+ project.url_to_repo.should == Gitlab.config.gitolite.ssh_path_prefix + "somewhere.git"
end
it "should return path to repo" do
@@ -150,19 +158,7 @@ describe Project do
it "returns the full web URL for this repo" do
project = Project.new(path: "somewhere")
- project.web_url.should == "#{Gitlab.config.url}/somewhere"
- end
-
- describe :valid_repo? do
- it "should be valid repo" do
- project = create(:project)
- project.valid_repo?.should be_true
- end
-
- it "should be invalid repo" do
- project = Project.new(name: "ok_name", path: "/INVALID_PATH/", path: "NEOK")
- project.valid_repo?.should be_false
- end
+ project.web_url.should == "#{Gitlab.config.gitlab.url}/somewhere"
end
describe "last_activity methods" do
@@ -188,85 +184,6 @@ describe Project do
end
end
- describe "fresh commits" do
- let(:project) { create(:project) }
-
- it { project.fresh_commits(3).count.should == 3 }
- it { project.fresh_commits.first.id.should == "bcf03b5de6c33f3869ef70d68cf06e679d1d7f9a" }
- it { project.fresh_commits.last.id.should == "f403da73f5e62794a0447aca879360494b08f678" }
- end
-
- describe "commits_between" do
- let(:project) { create(:project) }
-
- subject do
- commits = project.commits_between("3a4b4fb4cde7809f033822a171b9feae19d41fff",
- "8470d70da67355c9c009e4401746b1d5410af2e3")
- commits.map { |c| c.id }
- end
-
- it { should have(3).elements }
- it { should include("f0f14c8eaba69ebddd766498a9d0b0e79becd633") }
- it { should_not include("bcf03b5de6c33f3869ef70d68cf06e679d1d7f9a") }
- end
-
- describe "Git methods" do
- let(:project) { create(:project) }
-
- describe :repo do
- it "should return valid repo" do
- project.repo.should be_kind_of(Grit::Repo)
- end
-
- it "should return nil" do
- lambda { Project.new(path: "invalid").repo }.should raise_error(Grit::NoSuchPathError)
- end
-
- it "should return nil" do
- lambda { Project.new.repo }.should raise_error(TypeError)
- end
- end
-
- describe :commit do
- it "should return first head commit if without params" do
- project.commit.id.should == project.repo.commits.first.id
- end
-
- it "should return valid commit" do
- project.commit(ValidCommit::ID).should be_valid_commit
- end
-
- it "should return nil" do
- project.commit("+123_4532530XYZ").should be_nil
- end
- end
-
- describe :tree do
- before do
- @commit = project.commit(ValidCommit::ID)
- end
-
- it "should raise error w/o arguments" do
- lambda { project.tree }.should raise_error
- end
-
- it "should return root tree for commit" do
- tree = project.tree(@commit)
- tree.contents.size.should == ValidCommit::FILES_COUNT
- tree.contents.map(&:name).should == ValidCommit::FILES
- end
-
- it "should return root tree for commit with correct path" do
- tree = project.tree(@commit, ValidCommit::C_FILE_PATH)
- tree.contents.map(&:name).should == ValidCommit::C_FILES
- end
-
- it "should return root tree for commit with incorrect path" do
- project.tree(@commit, "invalid_path").should be_nil
- end
- end
- end
-
describe :update_merge_requests do
let(:project) { create(:project) }
diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb
index 279e315b693..d09484f8fe0 100644
--- a/spec/models/user_spec.rb
+++ b/spec/models/user_spec.rb
@@ -41,7 +41,6 @@ describe User do
it { should have_many(:users_projects).dependent(:destroy) }
it { should have_many(:projects) }
it { should have_many(:groups) }
- it { should have_many(:my_own_projects).class_name('Project') }
it { should have_many(:keys).dependent(:destroy) }
it { should have_many(:events).class_name('Event').dependent(:destroy) }
it { should have_many(:recent_events).class_name('Event') }
@@ -67,6 +66,10 @@ describe User do
it { should ensure_length_of(:bio).is_within(0..255) }
end
+ describe 'modules' do
+ it { should include_module(Account) }
+ end
+
describe "Respond to" do
it { should respond_to(:is_admin?) }
it { should respond_to(:identifier) }
diff --git a/spec/observers/activity_observer_spec.rb b/spec/observers/activity_observer_spec.rb
index 0eec41f44e9..6af5d070888 100644
--- a/spec/observers/activity_observer_spec.rb
+++ b/spec/observers/activity_observer_spec.rb
@@ -34,15 +34,17 @@ describe ActivityObserver do
it { @event.target.should == @issue }
end
- #describe "Issue commented" do
- #before do
- #@issue = create(:issue, project: project)
- #@note = create(:note, noteable: @issue, project: project)
- #@event = Event.last
- #end
-
- #it_should_be_valid_event
- #it { @event.action.should == Event::Commented }
- #it { @event.target.should == @note }
- #end
+ describe "Issue commented" do
+ before do
+ Note.observers.enable :activity_observer do
+ @issue = create(:issue, project: project)
+ @note = create(:note, noteable: @issue, project: project, author: @issue.author)
+ @event = Event.last
+ end
+ end
+
+ it_should_be_valid_event
+ it { @event.action.should == Event::Commented }
+ it { @event.target.should == @note }
+ end
end
diff --git a/spec/requests/api/projects_spec.rb b/spec/requests/api/projects_spec.rb
index b4e2fbbdab8..a396516438d 100644
--- a/spec/requests/api/projects_spec.rb
+++ b/spec/requests/api/projects_spec.rb
@@ -117,6 +117,14 @@ describe Gitlab::API do
json_response.count.should == 2
json_response.first['email'].should == user.email
end
+
+ it "finds team members with query string" do
+ get api("/projects/#{project.path}/members", user), query: user.username
+ response.status.should == 200
+ json_response.should be_an Array
+ json_response.count.should == 1
+ json_response.first['email'].should == user.email
+ end
end
describe "GET /projects/:id/members/:user_id" do
diff --git a/spec/requests/issues_spec.rb b/spec/requests/issues_spec.rb
index a4b026862ef..0814108523b 100644
--- a/spec/requests/issues_spec.rb
+++ b/spec/requests/issues_spec.rb
@@ -11,7 +11,7 @@ describe "Issues" do
project.add_access(user2, :read, :write)
end
- describe "Edit issue", js: true do
+ describe "Edit issue" do
let!(:issue) do
create(:issue,
author: @user,
@@ -91,13 +91,13 @@ describe "Issues" do
title: title)
end
- issue = Issue.first # with title 'foobar'
- issue.milestone = create(:milestone, project: project)
- issue.assignee = nil
- issue.save
+ @issue = Issue.first # with title 'foobar'
+ @issue.milestone = create(:milestone, project: project)
+ @issue.assignee = nil
+ @issue.save
end
- let(:issue) { Issue.first }
+ let(:issue) { @issue }
it "should allow filtering by issues with no specified milestone" do
visit project_issues_path(project, milestone_id: '0')
diff --git a/spec/requests/snippets_spec.rb b/spec/requests/snippets_spec.rb
index 9ef217ba62c..b231b940a84 100644
--- a/spec/requests/snippets_spec.rb
+++ b/spec/requests/snippets_spec.rb
@@ -48,11 +48,11 @@ describe "Snippets" do
page.current_path.should == new_project_snippet_path(project)
end
- describe "fill in" do
+ describe "fill in", js: true do
before do
fill_in "snippet_title", with: "login function"
fill_in "snippet_file_name", with: "test.rb"
- fill_in "snippet_content", with: "def login; end"
+ page.execute_script("editor.insert('def login; end');")
end
it { expect { click_button "Save" }.to change {Snippet.count}.by(1) }
@@ -83,7 +83,6 @@ describe "Snippets" do
before do
fill_in "snippet_title", with: "login function"
fill_in "snippet_file_name", with: "test.rb"
- fill_in "snippet_content", with: "def login; end"
end
it { expect { click_button "Save" }.to_not change {Snippet.count} }
diff --git a/spec/roles/account_role_spec.rb b/spec/roles/account_role_spec.rb
new file mode 100644
index 00000000000..4b214551453
--- /dev/null
+++ b/spec/roles/account_role_spec.rb
@@ -0,0 +1,44 @@
+require 'spec_helper'
+
+describe User, "Account" do
+ describe 'normal user' do
+ let(:user) { create(:user, name: 'John Smith') }
+
+ it { user.is_admin?.should be_false }
+ it { user.require_ssh_key?.should be_true }
+ it { user.can_create_group?.should be_false }
+ it { user.can_create_project?.should be_true }
+ it { user.first_name.should == 'John' }
+ end
+
+ describe 'blocking user' do
+ let(:user) { create(:user, name: 'John Smith') }
+
+ it "should block user" do
+ user.block
+ user.blocked.should be_true
+ end
+ end
+
+ describe 'projects' do
+ before do
+ ActiveRecord::Base.observers.enable(:user_observer)
+ @user = create :user
+ @project = create :project, namespace: @user.namespace
+ end
+
+ it { @user.authorized_projects.should include(@project) }
+ it { @user.my_own_projects.should include(@project) }
+ end
+
+ describe 'namespaced' do
+ before do
+ ActiveRecord::Base.observers.enable(:user_observer)
+ @user = create :user
+ @project = create :project, namespace: @user.namespace
+ end
+
+ it { @user.several_namespaces?.should be_false }
+ it { @user.namespaces.should == [@user.namespace] }
+ end
+end
diff --git a/spec/roles/repository_spec.rb b/spec/roles/repository_spec.rb
index 3507585aa8d..e1d01cbfeaf 100644
--- a/spec/roles/repository_spec.rb
+++ b/spec/roles/repository_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe Project, "Repository" do
- let(:project) { build(:project) }
+ let(:project) { create(:project) }
describe "#empty_repo?" do
it "should return true if the repo doesn't exist" do
@@ -69,4 +69,91 @@ describe Project, "Repository" do
project.root_ref?('stable').should be_false
end
end
+
+ describe :repo do
+ it "should return valid repo" do
+ project.repo.should be_kind_of(Grit::Repo)
+ end
+
+ it "should return nil" do
+ lambda { Project.new(path: "invalid").repo }.should raise_error(Grit::NoSuchPathError)
+ end
+
+ it "should return nil" do
+ lambda { Project.new.repo }.should raise_error(TypeError)
+ end
+ end
+
+ describe :commit do
+ it "should return first head commit if without params" do
+ project.commit.id.should == project.repo.commits.first.id
+ end
+
+ it "should return valid commit" do
+ project.commit(ValidCommit::ID).should be_valid_commit
+ end
+
+ it "should return nil" do
+ project.commit("+123_4532530XYZ").should be_nil
+ end
+ end
+
+ describe :tree do
+ before do
+ @commit = project.commit(ValidCommit::ID)
+ end
+
+ it "should raise error w/o arguments" do
+ lambda { project.tree }.should raise_error
+ end
+
+ it "should return root tree for commit" do
+ tree = project.tree(@commit)
+ tree.contents.size.should == ValidCommit::FILES_COUNT
+ tree.contents.map(&:name).should == ValidCommit::FILES
+ end
+
+ it "should return root tree for commit with correct path" do
+ tree = project.tree(@commit, ValidCommit::C_FILE_PATH)
+ tree.contents.map(&:name).should == ValidCommit::C_FILES
+ end
+
+ it "should return root tree for commit with incorrect path" do
+ project.tree(@commit, "invalid_path").should be_nil
+ end
+ end
+
+ describe "fresh commits" do
+ let(:project) { create(:project) }
+
+ it { project.fresh_commits(3).count.should == 3 }
+ it { project.fresh_commits.first.id.should == "bcf03b5de6c33f3869ef70d68cf06e679d1d7f9a" }
+ it { project.fresh_commits.last.id.should == "f403da73f5e62794a0447aca879360494b08f678" }
+ end
+
+ describe "commits_between" do
+ let(:project) { create(:project) }
+
+ subject do
+ commits = project.commits_between("3a4b4fb4cde7809f033822a171b9feae19d41fff",
+ "8470d70da67355c9c009e4401746b1d5410af2e3")
+ commits.map { |c| c.id }
+ end
+
+ it { should have(3).elements }
+ it { should include("f0f14c8eaba69ebddd766498a9d0b0e79becd633") }
+ it { should_not include("bcf03b5de6c33f3869ef70d68cf06e679d1d7f9a") }
+ end
+
+ describe :valid_repo? do
+ it "should be valid repo" do
+ project = create(:project)
+ project.valid_repo?.should be_true
+ end
+
+ it "should be invalid repo" do
+ project = Project.new(name: "ok_name", path: "/INVALID_PATH/", path: "NEOK")
+ project.valid_repo?.should be_false
+ end
+ end
end
diff --git a/spec/routing/project_routing_spec.rb b/spec/routing/project_routing_spec.rb
index 25db2f91d4d..09e11588164 100644
--- a/spec/routing/project_routing_spec.rb
+++ b/spec/routing/project_routing_spec.rb
@@ -245,6 +245,7 @@ describe MergeRequestsController, "routing" do
it_behaves_like "RESTful project resources" do
let(:controller) { 'merge_requests' }
+ let(:actions) { [:index, :create, :new, :edit, :show, :update] }
end
end
@@ -325,6 +326,7 @@ end
describe MilestonesController, "routing" do
it_behaves_like "RESTful project resources" do
let(:controller) { 'milestones' }
+ let(:actions) { [:index, :create, :new, :edit, :show, :update] }
end
end
@@ -360,6 +362,7 @@ describe IssuesController, "routing" do
it_behaves_like "RESTful project resources" do
let(:controller) { 'issues' }
+ let(:actions) { [:index, :create, :new, :edit, :show, :update] }
end
end
diff --git a/spec/routing/routing_spec.rb b/spec/routing/routing_spec.rb
index 988063db4b0..57fd70e7497 100644
--- a/spec/routing/routing_spec.rb
+++ b/spec/routing/routing_spec.rb
@@ -33,6 +33,7 @@ end
# help_system_hooks GET /help/system_hooks(.:format) help#system_hooks
# help_markdown GET /help/markdown(.:format) help#markdown
# help_ssh GET /help/ssh(.:format) help#ssh
+# help_raketasks GET /help/raketasks(.:format) help#raketasks
describe HelpController, "routing" do
it "to #index" do
get("/help").should route_to('help#index')
@@ -65,6 +66,10 @@ describe HelpController, "routing" do
it "to #ssh" do
get("/help/ssh").should route_to('help#ssh')
end
+
+ it "to #raketasks" do
+ get("/help/raketasks").should route_to('help#raketasks')
+ end
end
# errors_githost GET /errors/githost(.:format) errors#githost
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
index 7728b1e9d84..9f066c0e7f3 100644
--- a/spec/spec_helper.rb
+++ b/spec/spec_helper.rb
@@ -42,8 +42,8 @@ RSpec.configure do |config|
# ActiveRecord::Base.observers.enable(:all)
# Use tmp dir for FS manipulations
- Gitlab.config.stub(git_base_path: Rails.root.join('tmp', 'test-git-base-path'))
- FileUtils.rm_rf Gitlab.config.git_base_path
- FileUtils.mkdir_p Gitlab.config.git_base_path
+ Gitlab.config.gitolite.stub(repos_path: Rails.root.join('tmp', 'test-git-base-path'))
+ FileUtils.rm_rf Gitlab.config.gitolite.repos_path
+ FileUtils.mkdir_p Gitlab.config.gitolite.repos_path
end
end
diff --git a/spec/workers/post_receive_spec.rb b/spec/workers/post_receive_spec.rb
index bbc91f4474a..26b461c3825 100644
--- a/spec/workers/post_receive_spec.rb
+++ b/spec/workers/post_receive_spec.rb
@@ -14,8 +14,8 @@ describe PostReceive do
let(:key_id) { key.identifier }
it "fetches the correct project" do
- Project.should_receive(:find_by_path).with(project.path).and_return(project)
- PostReceive.perform(project.path, 'sha-old', 'sha-new', 'refs/heads/master', key_id)
+ Project.should_receive(:find_with_namespace).with(project.path_with_namespace).and_return(project)
+ PostReceive.perform(pwd(project), 'sha-old', 'sha-new', 'refs/heads/master', key_id)
end
it "does not run if the author is not in the project" do
@@ -24,17 +24,21 @@ describe PostReceive do
project.should_not_receive(:observe_push)
project.should_not_receive(:execute_hooks)
- PostReceive.perform(project.path, 'sha-old', 'sha-new', 'refs/heads/master', key_id).should be_false
+ PostReceive.perform(pwd(project), 'sha-old', 'sha-new', 'refs/heads/master', key_id).should be_false
end
it "asks the project to trigger all hooks" do
- Project.stub(find_by_path: project)
+ Project.stub(find_with_namespace: project)
project.should_receive(:execute_hooks)
project.should_receive(:execute_services)
project.should_receive(:update_merge_requests)
project.should_receive(:observe_push)
- PostReceive.perform(project.path, 'sha-old', 'sha-new', 'refs/heads/master', key_id)
+ PostReceive.perform(pwd(project), 'sha-old', 'sha-new', 'refs/heads/master', key_id)
end
end
+
+ def pwd(project)
+ File.join(Gitlab.config.gitolite.repos_path, project.path_with_namespace)
+ end
end
diff --git a/vendor/assets/javascripts/branch-graph.js b/vendor/assets/javascripts/branch-graph.js
index 11c74554c45..a7e1e152bd2 100644
--- a/vendor/assets/javascripts/branch-graph.js
+++ b/vendor/assets/javascripts/branch-graph.js
@@ -252,4 +252,4 @@ Raphael.fn.tooltip = function (x, y, set, dir, size) {
, xy = [{x: x, y: y + size * 2 + h}, {x: x - size * 2 - w, y: y}, {x: x, y: y - size * 2 - h}, {x: x + size * 2 + w, y: y}][dir];
set.translate(xy.x - w - bb.x, xy.y - h - bb.y);
return this.set(this.path(p).attr({fill: "#234", stroke: "none"}).insertBefore(set.node ? set : set[0]), set);
-}; \ No newline at end of file
+};