Commit bda7fe38d0b0e39a408c4eb44374a330c24c3a49

Authored by Riyad Preukschas
2 parents d28176b1 d8e697ac

Merge branch 'master' into discussions

Showing 70 changed files with 570 additions and 310 deletions   Show diff stats
  1 +language: ruby
1 env: 2 env:
2 - DB=postgresql 3 - DB=postgresql
3 - DB=mysql 4 - DB=mysql
@@ -8,7 +9,7 @@ branches: @@ -8,7 +9,7 @@ branches:
8 only: 9 only:
9 - 'master' 10 - 'master'
10 rvm: 11 rvm:
11 - - 1.9.2 12 + - 1.9.3-p327
12 services: 13 services:
13 - mysql 14 - mysql
14 - postgresql 15 - postgresql
  1 +v 4.1.0
  2 + - Project public mode (only admin can set now)
  3 + - Public area with unauthorized access
  4 + - Load dashboard events with ajax
  5 + - remember dashboard filter in cookies
  6 + - replace resque with sidekiq
  7 + - fix routing issues
  8 + - cleanup rake tasks
  9 + - fix backup/restore
  10 + - scss cleanup
  11 + - show preview for note images
  12 + - improved network-graph
  13 + - get rid of app/roles/
  14 + - added new classes Team, Repository
  15 + - Reduce amount of gitolite calls
  16 + - Ability to add user in all group projects
  17 + - remove derecated configs
  18 + - replaced Korolev font with open font
  19 + - restyled admin/dashboard page
  20 + - restyled admin/projects page
  21 +
1 v 4.0.0 22 v 4.0.0
2 - Remove project code and path from API. Use id instead 23 - Remove project code and path from API. Use id instead
3 - Return valid clonable url to repo for web hook 24 - Return valid clonable url to repo for web hook
@@ -71,7 +71,6 @@ gem "redcarpet", "~> 2.2.2" @@ -71,7 +71,6 @@ gem "redcarpet", "~> 2.2.2"
71 gem "github-markup", "~> 0.7.4", require: 'github/markup' 71 gem "github-markup", "~> 0.7.4", require: 'github/markup'
72 72
73 # Servers 73 # Servers
74 -gem "thin", '~> 1.5.0'  
75 gem "unicorn", "~> 4.4.0" 74 gem "unicorn", "~> 4.4.0"
76 75
77 # Issue tags 76 # Issue tags
@@ -111,7 +110,7 @@ group :assets do @@ -111,7 +110,7 @@ group :assets do
111 gem "modernizr", "2.6.2" 110 gem "modernizr", "2.6.2"
112 gem "raphael-rails", git: "https://github.com/gitlabhq/raphael-rails.git" 111 gem "raphael-rails", git: "https://github.com/gitlabhq/raphael-rails.git"
113 gem 'bootstrap-sass', "2.2.1.1" 112 gem 'bootstrap-sass', "2.2.1.1"
114 - gem "font-awesome-sass-rails", "~> 2.0.0" 113 + gem "font-awesome-sass-rails", "~> 3.0.0"
115 gem "gemoji", "~> 1.2.1", require: 'emoji/railtie' 114 gem "gemoji", "~> 1.2.1", require: 'emoji/railtie'
116 end 115 end
117 116
@@ -144,7 +144,6 @@ GEM @@ -144,7 +144,6 @@ GEM
144 colorize (0.5.8) 144 colorize (0.5.8)
145 connection_pool (1.0.0) 145 connection_pool (1.0.0)
146 crack (0.3.1) 146 crack (0.3.1)
147 - daemons (1.1.9)  
148 devise (2.1.2) 147 devise (2.1.2)
149 bcrypt-ruby (~> 3.0) 148 bcrypt-ruby (~> 3.0)
150 orm_adapter (~> 0.1) 149 orm_adapter (~> 0.1)
@@ -174,7 +173,7 @@ GEM @@ -174,7 +173,7 @@ GEM
174 eventmachine (>= 0.12.0) 173 eventmachine (>= 0.12.0)
175 ffaker (1.15.0) 174 ffaker (1.15.0)
176 ffi (1.1.5) 175 ffi (1.1.5)
177 - font-awesome-sass-rails (2.0.0.0) 176 + font-awesome-sass-rails (3.0.0.1)
178 railties (>= 3.1.1) 177 railties (>= 3.1.1)
179 sass-rails (>= 3.1.1) 178 sass-rails (>= 3.1.1)
180 foreman (0.60.2) 179 foreman (0.60.2)
@@ -381,7 +380,7 @@ GEM @@ -381,7 +380,7 @@ GEM
381 rspec-mocks (~> 2.12.0) 380 rspec-mocks (~> 2.12.0)
382 rubyntlm (0.1.1) 381 rubyntlm (0.1.1)
383 rubyzip (0.9.9) 382 rubyzip (0.9.9)
384 - sass (3.2.3) 383 + sass (3.2.5)
385 sass-rails (3.2.5) 384 sass-rails (3.2.5)
386 railties (~> 3.2.0) 385 railties (~> 3.2.0)
387 sass (>= 3.1.10) 386 sass (>= 3.1.10)
@@ -437,10 +436,6 @@ GEM @@ -437,10 +436,6 @@ GEM
437 test_after_commit (0.0.1) 436 test_after_commit (0.0.1)
438 therubyracer (0.10.2) 437 therubyracer (0.10.2)
439 libv8 (~> 3.3.10) 438 libv8 (~> 3.3.10)
440 - thin (1.5.0)  
441 - daemons (>= 1.0.9)  
442 - eventmachine (>= 0.12.6)  
443 - rack (>= 1.0.0)  
444 thor (0.16.0) 439 thor (0.16.0)
445 tilt (1.3.3) 440 tilt (1.3.3)
446 timers (1.0.2) 441 timers (1.0.2)
@@ -488,7 +483,7 @@ DEPENDENCIES @@ -488,7 +483,7 @@ DEPENDENCIES
488 email_spec 483 email_spec
489 factory_girl_rails 484 factory_girl_rails
490 ffaker 485 ffaker
491 - font-awesome-sass-rails (~> 2.0.0) 486 + font-awesome-sass-rails (~> 3.0.0)
492 foreman 487 foreman
493 gemoji (~> 1.2.1) 488 gemoji (~> 1.2.1)
494 git 489 git
@@ -547,7 +542,6 @@ DEPENDENCIES @@ -547,7 +542,6 @@ DEPENDENCIES
547 stamp 542 stamp
548 test_after_commit 543 test_after_commit
549 therubyracer 544 therubyracer
550 - thin (~> 1.5.0)  
551 uglifier (~> 1.3.0) 545 uglifier (~> 1.3.0)
552 unicorn (~> 4.4.0) 546 unicorn (~> 4.4.0)
553 webmock 547 webmock
1 -web: bundle exec rails s -p $PORT 1 +web: bundle exec unicorn_rails -p $PORT
2 worker: bundle exec sidekiq -q post_receive,mailer,system_hook,common,default 2 worker: bundle exec sidekiq -q post_receive,mailer,system_hook,common,default
app/assets/images/diff_file_add.png

177 Bytes

app/assets/images/diff_file_delete.png

295 Bytes

app/assets/images/diff_file_info.png

749 Bytes

app/assets/images/diff_file_notice.png

302 Bytes

app/assets/images/event_filter_comments.png

750 Bytes

app/assets/images/event_filter_merged.png

463 Bytes

app/assets/images/event_filter_push.png

632 Bytes

app/assets/images/event_filter_team.png

1.31 KB

app/assets/images/event_mr_merged.png

463 Bytes

app/assets/images/event_push.png

632 Bytes

app/assets/images/list_view_icon.jpg

357 Bytes

app/assets/javascripts/dashboard.js.coffee
1 -$ ->  
2 - dashboardPage()  
3 -  
4 -dashboardPage = -> 1 +window.dashboardPage = ->
5 Pager.init 20, true 2 Pager.init 20, true
6 $(".event_filter_link").bind "click", (event) -> 3 $(".event_filter_link").bind "click", (event) ->
7 event.preventDefault() 4 event.preventDefault()
app/assets/stylesheets/application.scss
@@ -32,6 +32,7 @@ @@ -32,6 +32,7 @@
32 @import "sections/profile.scss"; 32 @import "sections/profile.scss";
33 @import "sections/login.scss"; 33 @import "sections/login.scss";
34 @import "sections/editor.scss"; 34 @import "sections/editor.scss";
  35 +@import "sections/admin.scss";
35 36
36 @import "highlight/white.scss"; 37 @import "highlight/white.scss";
37 @import "highlight/dark.scss"; 38 @import "highlight/dark.scss";
app/assets/stylesheets/common.scss
@@ -371,6 +371,7 @@ li.note { @@ -371,6 +371,7 @@ li.note {
371 font-size: 48px; 371 font-size: 48px;
372 padding: 20px; 372 padding: 20px;
373 text-align: center; 373 text-align: center;
  374 + font-weight: normal;
374 } 375 }
375 } 376 }
376 } 377 }
@@ -445,6 +446,19 @@ li.note { @@ -445,6 +446,19 @@ li.note {
445 } 446 }
446 } 447 }
447 448
  449 +.warning_message {
  450 + border-left: 4px solid #ed9;
  451 + color: #b90;
  452 + padding: 10px;
  453 + margin-bottom: 10px;
  454 + background: #ffffe6;
  455 + padding-left: 20px;
  456 +
  457 + &.centered {
  458 + text-align: center;
  459 + }
  460 +}
  461 +
448 .oauth_select_holder { 462 .oauth_select_holder {
449 padding: 20px; 463 padding: 20px;
450 img { 464 img {
app/assets/stylesheets/gitlab_bootstrap/files.scss
@@ -37,24 +37,6 @@ @@ -37,24 +37,6 @@
37 background: #fff; 37 background: #fff;
38 font-size: 11px; 38 font-size: 11px;
39 39
40 - &.wiki {  
41 - font-size: 13px;  
42 - code {  
43 - padding: 0 4px;  
44 - }  
45 - padding: 20px;  
46 -  
47 - h1 { font-size: 26px; line-height: 46px; }  
48 - h2 { font-size: 22px; line-height: 42px; }  
49 - h3 { font-size: 20px; line-height: 40px; }  
50 - h4 { font-size: 18px; line-height: 32px; }  
51 - h5 { font-size: 16px; line-height: 26px; }  
52 -  
53 - .white .highlight pre {  
54 - background: #f5f5f5;  
55 - }  
56 - }  
57 -  
58 &.image_file { 40 &.image_file {
59 background: #eee; 41 background: #eee;
60 text-align: center; 42 text-align: center;
@@ -64,6 +46,11 @@ @@ -64,6 +46,11 @@
64 } 46 }
65 } 47 }
66 48
  49 + &.wiki {
  50 + padding: 20px;
  51 + font-size: 13px;
  52 + }
  53 +
67 &.blob_file { 54 &.blob_file {
68 55
69 } 56 }
app/assets/stylesheets/gitlab_bootstrap/typography.scss
@@ -81,3 +81,22 @@ a:focus { @@ -81,3 +81,22 @@ a:focus {
81 .monospace { 81 .monospace {
82 font-family: 'Menlo', 'Liberation Mono', 'Consolas', 'Courier New', 'andale mono','lucida console',monospace; 82 font-family: 'Menlo', 'Liberation Mono', 'Consolas', 'Courier New', 'andale mono','lucida console',monospace;
83 } 83 }
  84 +
  85 +/**
  86 + * Wiki typography
  87 + *
  88 + */
  89 +.wiki {
  90 + font-size: 13px;
  91 +
  92 + code { padding: 0 4px; }
  93 + p { font-size: 13px; }
  94 + h1 { font-size: 32px; line-height: 40px; margin: 10px 0;}
  95 + h2 { font-size: 26px; line-height: 40px; margin: 10px 0;}
  96 + h3 { font-size: 22px; line-height: 40px; margin: 10px 0;}
  97 + h4 { font-size: 18px; line-height: 20px; margin: 10px 0;}
  98 + h5 { font-size: 14px; line-height: 20px; margin: 10px 0;}
  99 + h6 { font-size: 12px; line-height: 20px; margin: 10px 0;}
  100 + .white .highlight pre { background: #f5f5f5; }
  101 + ul { margin: 0 0 9px 25px !important; }
  102 +}
app/assets/stylesheets/sections/admin.scss 0 → 100644
@@ -0,0 +1,5 @@ @@ -0,0 +1,5 @@
  1 +.admin-filter form {
  2 + label { width: 110px; }
  3 + .controls { margin-left: 130px; }
  4 + .form-actions { padding-left: 130px; background: #fff }
  5 +}
app/assets/stylesheets/sections/events.scss
@@ -132,21 +132,25 @@ @@ -132,21 +132,25 @@
132 .event_filter { 132 .event_filter {
133 position: absolute; 133 position: absolute;
134 width: 40px; 134 width: 40px;
135 - margin-left: -50px; 135 + margin-left: -55px;
136 136
137 .filter_icon { 137 .filter_icon {
138 - float: left;  
139 - border-left: 3px solid #4bc;  
140 - padding: 7px;  
141 - background: #f9f9f9;  
142 - margin-bottom: 10px;  
143 - img {  
144 - width: 20px; 138 + a {
  139 + text-align:center;
  140 + border-left: 3px solid #29B;
  141 + background: #f9f9f9;
  142 + margin-bottom: 10px;
  143 + float: left;
  144 + padding: 9px 7px;
  145 + font-size: 18px;
  146 + width: 26px;
145 } 147 }
146 148
147 &.inactive { 149 &.inactive {
148 - border-left: 3px solid #EEE;  
149 - opacity: 0.5; 150 + a {
  151 + color: #DDD;
  152 + border-left: 3px solid #EEE;
  153 + }
150 } 154 }
151 } 155 }
152 } 156 }
app/assets/stylesheets/sections/tree.scss
@@ -80,6 +80,18 @@ @@ -80,6 +80,18 @@
80 margin: 0; 80 margin: 0;
81 padding: 0; 81 padding: 0;
82 } 82 }
  83 + td.blame-commit {
  84 + background: #f9f9f9;
  85 + min-width: 350px;
  86 + }
  87 + td.blame-numbers {
  88 + pre {
  89 + color: #AAA;
  90 + white-space: pre;
  91 + }
  92 + background: #f1f1f1;
  93 + border-left: 1px solid #DDD;
  94 + }
83 } 95 }
84 } 96 }
85 97
app/controllers/admin/projects_controller.rb
@@ -4,6 +4,9 @@ class Admin::ProjectsController < AdminController @@ -4,6 +4,9 @@ class Admin::ProjectsController < AdminController
4 def index 4 def index
5 @projects = Project.scoped 5 @projects = Project.scoped
6 @projects = @projects.where(namespace_id: params[:namespace_id]) if params[:namespace_id].present? 6 @projects = @projects.where(namespace_id: params[:namespace_id]) if params[:namespace_id].present?
  7 + @projects = @projects.where(public: true) if params[:public_only].present?
  8 + @projects = @projects.with_push if params[:with_push].present?
  9 + @projects = @projects.abandoned if params[:abandoned].present?
7 @projects = @projects.where(namespace_id: nil) if params[:namespace_id] == Namespace.global_id 10 @projects = @projects.where(namespace_id: nil) if params[:namespace_id] == Namespace.global_id
8 @projects = @projects.search(params[:name]) if params[:name].present? 11 @projects = @projects.search(params[:name]) if params[:name].present?
9 @projects = @projects.includes(:namespace).order("namespaces.path, projects.name ASC").page(params[:page]).per(20) 12 @projects = @projects.includes(:namespace).order("namespaces.path, projects.name ASC").page(params[:page]).per(20)
app/controllers/public/projects_controller.rb 0 → 100644
@@ -0,0 +1,12 @@ @@ -0,0 +1,12 @@
  1 +class Public::ProjectsController < ApplicationController
  2 + skip_before_filter :authenticate_user!,
  3 + :reject_blocked, :set_current_user_for_observers,
  4 + :add_abilities
  5 +
  6 + layout 'public'
  7 +
  8 + def index
  9 + @projects = Project.public
  10 + @projects = @projects.includes(:namespace).order("namespaces.path, projects.name ASC").page(params[:page]).per(20)
  11 + end
  12 +end
app/controllers/wikis_controller.rb
@@ -2,20 +2,19 @@ class WikisController &lt; ProjectResourceController @@ -2,20 +2,19 @@ class WikisController &lt; ProjectResourceController
2 before_filter :authorize_read_wiki! 2 before_filter :authorize_read_wiki!
3 before_filter :authorize_write_wiki!, only: [:edit, :create, :history] 3 before_filter :authorize_write_wiki!, only: [:edit, :create, :history]
4 before_filter :authorize_admin_wiki!, only: :destroy 4 before_filter :authorize_admin_wiki!, only: :destroy
5 - 5 +
6 def pages 6 def pages
7 - @wikis = @project.wikis.group(:slug).order("created_at") 7 + @wiki_pages = @project.wikis.group(:slug).ordered
8 end 8 end
9 9
10 def show 10 def show
11 - if params[:old_page_id]  
12 - @wiki = @project.wikis.find(params[:old_page_id]) 11 + @most_recent_wiki = @project.wikis.where(slug: params[:id]).ordered.first
  12 + if params[:version_id]
  13 + @wiki = @project.wikis.find(params[:version_id])
13 else 14 else
14 - @wiki = @project.wikis.where(slug: params[:id]).order("created_at").last 15 + @wiki = @most_recent_wiki
15 end 16 end
16 17
17 - @note = @project.notes.new(noteable: @wiki)  
18 -  
19 if @wiki 18 if @wiki
20 render 'show' 19 render 'show'
21 else 20 else
@@ -29,7 +28,7 @@ class WikisController &lt; ProjectResourceController @@ -29,7 +28,7 @@ class WikisController &lt; ProjectResourceController
29 end 28 end
30 29
31 def edit 30 def edit
32 - @wiki = @project.wikis.where(slug: params[:id]).order("created_at").last 31 + @wiki = @project.wikis.where(slug: params[:id]).ordered.first
33 @wiki = Wiki.regenerate_from @wiki 32 @wiki = Wiki.regenerate_from @wiki
34 end 33 end
35 34
@@ -47,9 +46,9 @@ class WikisController &lt; ProjectResourceController @@ -47,9 +46,9 @@ class WikisController &lt; ProjectResourceController
47 end 46 end
48 47
49 def history 48 def history
50 - @wikis = @project.wikis.where(slug: params[:id]).order("created_at") 49 + @wiki_pages = @project.wikis.where(slug: params[:id]).ordered
51 end 50 end
52 - 51 +
53 def destroy 52 def destroy
54 @wikis = @project.wikis.where(slug: params[:id]).delete_all 53 @wikis = @project.wikis.where(slug: params[:id]).delete_all
55 54
app/helpers/events_helper.rb
@@ -30,8 +30,17 @@ module EventsHelper @@ -30,8 +30,17 @@ module EventsHelper
30 30
31 content_tag :div, class: "filter_icon #{inactive}" do 31 content_tag :div, class: "filter_icon #{inactive}" do
32 link_to dashboard_path, class: 'has_tooltip event_filter_link', id: "#{key}_event_filter", 'data-original-title' => tooltip do 32 link_to dashboard_path, class: 'has_tooltip event_filter_link', id: "#{key}_event_filter", 'data-original-title' => tooltip do
33 - image_tag "event_filter_#{key}.png" 33 + content_tag :i, nil, class: icon_for_event[key]
34 end 34 end
35 end 35 end
36 end 36 end
  37 +
  38 + def icon_for_event
  39 + {
  40 + EventFilter.push => "icon-upload-alt",
  41 + EventFilter.merged => "icon-check",
  42 + EventFilter.comments => "icon-comments",
  43 + EventFilter.team => "icon-user",
  44 + }
  45 + end
37 end 46 end
app/helpers/projects_helper.rb
@@ -26,19 +26,17 @@ module ProjectsHelper @@ -26,19 +26,17 @@ module ProjectsHelper
26 # Build avatar image tag 26 # Build avatar image tag
27 avatar = image_tag(gravatar_icon(author.try(:email)), width: 16, class: "lil_av") 27 avatar = image_tag(gravatar_icon(author.try(:email)), width: 16, class: "lil_av")
28 28
29 - # Build name strong tag  
30 - name = content_tag :strong, author.name, class: 'author' 29 + # Build name span tag
  30 + name = content_tag :span, author.name, class: 'author'
31 31
32 author_html = avatar + name 32 author_html = avatar + name
33 33
34 tm = project.team_member_by_id(author) 34 tm = project.team_member_by_id(author)
35 35
36 - content_tag :span, class: 'member-link' do  
37 - if tm  
38 - link_to author_html, project_team_member_path(project, tm), class: "author_link"  
39 - else  
40 - author_html  
41 - end 36 + if tm
  37 + link_to author_html, project_team_member_path(project, tm), class: "author_link"
  38 + else
  39 + author_html
42 end 40 end
43 end 41 end
44 42
app/models/project.rb
@@ -28,7 +28,7 @@ class Project &lt; ActiveRecord::Base @@ -28,7 +28,7 @@ class Project &lt; ActiveRecord::Base
28 attr_accessible :name, :path, :description, :default_branch, :issues_enabled, 28 attr_accessible :name, :path, :description, :default_branch, :issues_enabled,
29 :wall_enabled, :merge_requests_enabled, :wiki_enabled, as: [:default, :admin] 29 :wall_enabled, :merge_requests_enabled, :wiki_enabled, as: [:default, :admin]
30 30
31 - attr_accessible :namespace_id, :creator_id, as: :admin 31 + attr_accessible :namespace_id, :creator_id, :public, as: :admin
32 32
33 attr_accessor :error_code 33 attr_accessor :error_code
34 34
@@ -81,8 +81,21 @@ class Project &lt; ActiveRecord::Base @@ -81,8 +81,21 @@ class Project &lt; ActiveRecord::Base
81 scope :sorted_by_activity, ->() { order("(SELECT max(events.created_at) FROM events WHERE events.project_id = projects.id) DESC") } 81 scope :sorted_by_activity, ->() { order("(SELECT max(events.created_at) FROM events WHERE events.project_id = projects.id) DESC") }
82 scope :personal, ->(user) { where(namespace_id: user.namespace_id) } 82 scope :personal, ->(user) { where(namespace_id: user.namespace_id) }
83 scope :joined, ->(user) { where("namespace_id != ?", user.namespace_id) } 83 scope :joined, ->(user) { where("namespace_id != ?", user.namespace_id) }
  84 + scope :public, where(public: true)
84 85
85 class << self 86 class << self
  87 + def abandoned
  88 + project_ids = Event.select('max(created_at) as latest_date, project_id').
  89 + group('project_id').
  90 + having('latest_date < ?', 6.months.ago).map(&:project_id)
  91 +
  92 + where(id: project_ids)
  93 + end
  94 +
  95 + def with_push
  96 + includes(:events).where('events.action = ?', Event::Pushed)
  97 + end
  98 +
86 def active 99 def active
87 joins(:issues, :notes, :merge_requests).order("issues.created_at, notes.created_at, merge_requests.created_at DESC") 100 joins(:issues, :notes, :merge_requests).order("issues.created_at, notes.created_at, merge_requests.created_at DESC")
88 end 101 end
app/models/repository.rb
@@ -151,12 +151,12 @@ class Repository @@ -151,12 +151,12 @@ class Repository
151 return nil unless commit 151 return nil unless commit
152 152
153 # Build file path 153 # Build file path
154 - file_name = self.path + "-" + commit.id.to_s + ".tar.gz"  
155 - storage_path = Rails.root.join("tmp", "repositories", self.path_with_namespace) 154 + file_name = self.path_with_namespace + "-" + commit.id.to_s + ".tar.gz"
  155 + storage_path = Rails.root.join("tmp", "repositories")
156 file_path = File.join(storage_path, file_name) 156 file_path = File.join(storage_path, file_name)
157 157
158 # Put files into a directory before archiving 158 # Put files into a directory before archiving
159 - prefix = self.path + "/" 159 + prefix = self.path_with_namespace + "/"
160 160
161 # Create file if not exists 161 # Create file if not exists
162 unless File.exists?(file_path) 162 unless File.exists?(file_path)
app/models/wiki.rb
@@ -25,6 +25,8 @@ class Wiki &lt; ActiveRecord::Base @@ -25,6 +25,8 @@ class Wiki &lt; ActiveRecord::Base
25 25
26 before_update :set_slug 26 before_update :set_slug
27 27
  28 + scope :ordered, order("created_at DESC")
  29 +
28 def to_param 30 def to_param
29 slug 31 slug
30 end 32 end
app/views/admin/dashboard/index.html.haml
@@ -25,17 +25,51 @@ @@ -25,17 +25,51 @@
25 = link_to 'New User', new_admin_user_path, class: "btn small" 25 = link_to 'New User', new_admin_user_path, class: "btn small"
26 26
27 .row 27 .row
28 - .span6  
29 - %h3 Latest projects 28 + .span4
  29 + %h4 Latest projects
30 %hr 30 %hr
31 - @projects.each do |project| 31 - @projects.each do |project|
32 %p 32 %p
33 = link_to project.name_with_namespace, [:admin, project] 33 = link_to project.name_with_namespace, [:admin, project]
34 - .span6  
35 - %h3 Latest users 34 + %span.light.right
  35 + = time_ago_in_words project.created_at
  36 + ago
  37 +
  38 + .span4
  39 + %h4 Latest users
36 %hr 40 %hr
37 - @users.each do |user| 41 - @users.each do |user|
38 %p 42 %p
39 = link_to [:admin, user] do 43 = link_to [:admin, user] do
40 = user.name 44 = user.name
41 - %small= user.email 45 + %span.light.right
  46 + = time_ago_in_words user.created_at
  47 + ago
  48 +
  49 + .span4
  50 + %h4 Stats
  51 + %hr
  52 + %p
  53 + Issues
  54 + %span.light.right
  55 + = Issue.count
  56 + %p
  57 + Merge Requests
  58 + %span.light.right
  59 + = MergeRequest.count
  60 + %p
  61 + Notes
  62 + %span.light.right
  63 + = Note.count
  64 + %p
  65 + Snippets
  66 + %span.light.right
  67 + = Snippet.count
  68 + %p
  69 + SSH Keys
  70 + %span.light.right
  71 + = Key.count
  72 + %p
  73 + Milestones
  74 + %span.light.right
  75 + = Milestone.count
app/views/admin/logs/show.html.haml
@@ -5,6 +5,8 @@ @@ -5,6 +5,8 @@
5 = link_to "application.log", "#application", 'data-toggle' => 'tab' 5 = link_to "application.log", "#application", 'data-toggle' => 'tab'
6 %li 6 %li
7 = link_to "production.log", "#production", 'data-toggle' => 'tab' 7 = link_to "production.log", "#production", 'data-toggle' => 'tab'
  8 + %li
  9 + = link_to "sidekiq.log", "#sidekiq", 'data-toggle' => 'tab'
8 10
9 %p.light To prevent perfomance issues admin logs output the last 2000 lines 11 %p.light To prevent perfomance issues admin logs output the last 2000 lines
10 .tab-content 12 .tab-content
@@ -50,3 +52,17 @@ @@ -50,3 +52,17 @@
50 - Gitlab::Logger.read_latest_for('production.log').each do |line| 52 - Gitlab::Logger.read_latest_for('production.log').each do |line|
51 %li 53 %li
52 %p= line 54 %p= line
  55 + .tab-pane#sidekiq
  56 + .file_holder#README
  57 + .file_title
  58 + %i.icon-file
  59 + sidekiq.log
  60 + .right
  61 + = link_to '#', class: 'log-bottom' do
  62 + %i.icon-arrow-down
  63 + Scroll down
  64 + .file_content.logs
  65 + %ol
  66 + - Gitlab::Logger.read_latest_for('sidekiq.log').each do |line|
  67 + %li
  68 + %p= line
app/views/admin/projects/_form.html.haml
@@ -44,6 +44,13 @@ @@ -44,6 +44,13 @@
44 .input= f.check_box :wiki_enabled 44 .input= f.check_box :wiki_enabled
45 45
46 %fieldset.features 46 %fieldset.features
  47 + %legend Public mode:
  48 + .clearfix
  49 + = f.label :public do
  50 + %span Allow public http clone
  51 + .input= f.check_box :public
  52 +
  53 + %fieldset.features
47 %legend Transfer: 54 %legend Transfer:
48 .control-group 55 .control-group
49 = f.label :namespace_id do 56 = f.label :namespace_id do
app/views/admin/projects/index.html.haml
1 %h3.page_title 1 %h3.page_title
2 - Projects (#{Project.count}) 2 + Projects
3 = link_to 'New Project', new_project_path, class: "btn small right" 3 = link_to 'New Project', new_project_path, class: "btn small right"
4 -%br  
5 -= form_tag admin_projects_path, method: :get, class: 'form-inline' do  
6 - = select_tag :namespace_id, namespaces_options(params[:namespace_id], :all), class: "chosen xlarge", prompt: "Project namespace"  
7 - = text_field_tag :name, params[:name], class: "xlarge"  
8 - = submit_tag "Search", class: "btn submit primary"  
9 4
10 -%table  
11 - %thead  
12 - %tr  
13 - %th  
14 - Name  
15 - %i.icon-sort-down  
16 - %th Path  
17 - %th Team Members  
18 - %th Owner  
19 - %th Last Commit  
20 - %th Edit  
21 - %th.cred Danger Zone! 5 +%hr
22 6
23 - - @projects.each do |project|  
24 - %tr  
25 - %td  
26 - = link_to project.name_with_namespace, [:admin, project]  
27 - %td  
28 - %span.monospace= project.path_with_namespace + ".git"  
29 - %td= project.users_projects.count  
30 - %td  
31 - - if project.owner  
32 - = link_to project.owner.name, [:admin, project.owner] 7 +.row
  8 + .span4
  9 + .admin-filter
  10 + = form_tag admin_projects_path, method: :get, class: 'form-inline' do
  11 + .control-group
  12 + = label_tag :name, 'Name:', class: 'control-label'
  13 + .controls
  14 + = text_field_tag :name, params[:name], class: "span2"
  15 +
  16 + .control-group
  17 + = label_tag :namespace_id, 'Namespace:', class: 'control-label'
  18 + .controls
  19 + = select_tag :namespace_id, namespaces_options(params[:namespace_id], :all), class: "chosen span2", prompt: "Any"
  20 + .control-group
  21 + = label_tag :public_only, 'Public Only', class: 'control-label'
  22 + .controls
  23 + = check_box_tag :public_only, 1, params[:public_only]
  24 + .control-group
  25 + = label_tag :with_push, 'Not empty', class: 'control-label'
  26 + .controls
  27 + = check_box_tag :with_push, 1, params[:with_push]
  28 + &nbsp;
  29 + %span.light Projects with push events
  30 + .control-group
  31 + = label_tag :abandoned, 'Abandoned', class: 'control-label'
  32 + .controls
  33 + = check_box_tag :abandoned, 1, params[:abandoned]
  34 + &nbsp;
  35 + %span.light No activity over 6 month
  36 +
  37 +
  38 +
  39 + .form-actions
  40 + = submit_tag "Search", class: "btn submit primary"
  41 + = link_to "Reset", admin_projects_path, class: "btn"
  42 + .span8
  43 + .ui-box
  44 + %h5.title
  45 + Projects (#{@projects.total_count})
  46 + %ul.well-list
  47 + - @projects.each do |project|
  48 + %li
  49 + - if project.public
  50 + %i.icon-unlock.cred
  51 + - else
  52 + %i.icon-lock.cgreen
  53 + = link_to project.name_with_namespace, [:admin, project]
  54 + .right
  55 + = link_to 'Edit', edit_admin_project_path(project), id: "edit_#{dom_id(project)}", class: "btn small"
  56 + = link_to 'Destroy', [:admin, project], confirm: "REMOVE #{project.name}? Are you sure?", method: :delete, class: "btn small danger"
  57 + - if @projects.blank?
  58 + %p.nothing_here_message 0 projects matches
33 - else 59 - else
34 - (deleted)  
35 - %td= last_commit(project)  
36 - %td= link_to 'Edit', edit_admin_project_path(project), id: "edit_#{dom_id(project)}", class: "btn small"  
37 - %td.bgred= link_to 'Destroy', [:admin, project], confirm: "REMOVE #{project.name}? Are you sure?", method: :delete, class: "btn small danger"  
38 -= paginate @projects, theme: "admin" 60 + %li.bottom
  61 + = paginate @projects, theme: "gitlab"
app/views/admin/projects/show.html.haml
@@ -77,6 +77,13 @@ @@ -77,6 +77,13 @@
77 SSH: 77 SSH:
78 %td 78 %td
79 = link_to @project.ssh_url_to_repo 79 = link_to @project.ssh_url_to_repo
  80 + - if @project.public
  81 + %tr.bgred
  82 + %td
  83 + %b
  84 + Public Read-Only Code access:
  85 + %td
  86 + = check_box_tag 'public', nil, @project.public
80 87
81 - if @repository 88 - if @repository
82 %table.zebra-striped 89 %table.zebra-striped
app/views/blame/show.html.haml
@@ -20,16 +20,27 @@ @@ -20,16 +20,27 @@
20 %span.options= render "tree/blob_actions" 20 %span.options= render "tree/blob_actions"
21 .file_content.blame 21 .file_content.blame
22 %table 22 %table
  23 + - current_line = 1
23 - @blame.each do |commit, lines| 24 - @blame.each do |commit, lines|
24 - - commit = Commit.new(commit)  
25 - - commit = CommitDecorator.decorate(commit) 25 + - commit = CommitDecorator.decorate(Commit.new(commit))
26 %tr 26 %tr
27 - %td.author= commit.author_link avatar: true, size: 16  
28 - %td.blame_commit  
29 - &nbsp;  
30 - %code= link_to commit.short_id, project_commit_path(@project, commit)  
31 - = link_to_gfm truncate(commit.title, length: 30), project_commit_path(@project, commit), class: "row_title" rescue "--broken encoding" 27 + %td.blame-commit
  28 + %span.commit
  29 + = link_to commit.short_id(8), project_commit_path(@project, commit), class: "commit_short_id"
  30 + &nbsp;
  31 + = commit.author_link avatar: true, size: 16
  32 + &nbsp;
  33 + = link_to_gfm truncate(commit.title, length: 20), project_commit_path(@project, commit.id), class: "row_title"
  34 + %td.lines.blame-numbers
  35 + %pre
  36 + - if lines.empty?
  37 + = current_line
  38 + - current_line += 1
  39 + - else
  40 + - lines.each do |line|
  41 + = current_line
  42 + - current_line += 1
32 %td.lines 43 %td.lines
33 - = preserve do  
34 - %pre  
35 - = lines.join("\n") 44 + %pre
  45 + - lines.each do |line|
  46 + = line
app/views/dashboard/index.html.haml
@@ -7,3 +7,6 @@ @@ -7,3 +7,6 @@
7 7
8 - else 8 - else
9 = render "zero_authorized_projects" 9 = render "zero_authorized_projects"
  10 +
  11 +:javascript
  12 + dashboardPage();
app/views/dashboard/issues.html.haml
@@ -12,9 +12,9 @@ @@ -12,9 +12,9 @@
12 - if @issues.any? 12 - if @issues.any?
13 - @issues.group_by(&:project).each do |group| 13 - @issues.group_by(&:project).each do |group|
14 %div.ui-box 14 %div.ui-box
15 - - @project = group[0] 15 + - project = group[0]
16 %h5.title 16 %h5.title
17 - = link_to_project @project 17 + = link_to_project project
18 %ul.well-list.issues_table 18 %ul.well-list.issues_table
19 - group[1].each do |issue| 19 - group[1].each do |issue|
20 = render(partial: 'issues/show', locals: {issue: issue}) 20 = render(partial: 'issues/show', locals: {issue: issue})
app/views/dashboard/merge_requests.html.haml
@@ -8,17 +8,4 @@ @@ -8,17 +8,4 @@
8 .span3 8 .span3
9 = render 'filter', entity: 'merge_request' 9 = render 'filter', entity: 'merge_request'
10 .span9 10 .span9
11 - - if @merge_requests.any?  
12 - - @merge_requests.group_by(&:project).each do |group|  
13 - .ui-box  
14 - - @project = group[0]  
15 - %h5.title  
16 - = link_to_project @project  
17 - %ul.well-list  
18 - - group[1].each do |merge_request|  
19 - = render(partial: 'merge_requests/merge_request', locals: {merge_request: merge_request})  
20 - %hr  
21 - = paginate @merge_requests, theme: "gitlab"  
22 -  
23 - - else  
24 - %h3.nothing_here_message Nothing to show here 11 + = render 'shared/merge_requests'
app/views/events/_event_last_push.html.haml
1 - if show_last_push_widget?(event) 1 - if show_last_push_widget?(event)
2 .event_lp 2 .event_lp
3 - = image_tag "event_push.png"  
4 - &nbsp;  
5 %span You pushed to 3 %span You pushed to
6 = link_to project_commits_path(event.project, event.ref_name) do 4 = link_to project_commits_path(event.project, event.ref_name) do
7 %strong= truncate(event.ref_name, length: 28) 5 %strong= truncate(event.ref_name, length: 28)
app/views/groups/issues.html.haml
@@ -11,9 +11,9 @@ @@ -11,9 +11,9 @@
11 - if @issues.any? 11 - if @issues.any?
12 - @issues.group_by(&:project).each do |group| 12 - @issues.group_by(&:project).each do |group|
13 %div.ui-box 13 %div.ui-box
14 - - @project = group[0] 14 + - project = group[0]
15 %h5.title 15 %h5.title
16 - = link_to_project @project 16 + = link_to_project project
17 %ul.well-list.issues_table 17 %ul.well-list.issues_table
18 - group[1].each do |issue| 18 - group[1].each do |issue|
19 = render(partial: 'issues/show', locals: {issue: issue}) 19 = render(partial: 'issues/show', locals: {issue: issue})
app/views/groups/merge_requests.html.haml
@@ -8,17 +8,4 @@ @@ -8,17 +8,4 @@
8 .span3 8 .span3
9 = render 'filter', entity: 'merge_request' 9 = render 'filter', entity: 'merge_request'
10 .span9 10 .span9
11 - - if @merge_requests.any?  
12 - - @merge_requests.group_by(&:project).each do |group|  
13 - .ui-box  
14 - - @project = group[0]  
15 - %h5.title  
16 - = link_to_project @project  
17 - %ul.well-list  
18 - - group[1].each do |merge_request|  
19 - = render(partial: 'merge_requests/merge_request', locals: {merge_request: merge_request})  
20 - %hr  
21 - = paginate @merge_requests, theme: "gitlab"  
22 -  
23 - - else  
24 - %h3.nothing_here_message Nothing to show here 11 + = render 'shared/merge_requests'
app/views/help/index.html.haml
@@ -47,3 +47,5 @@ @@ -47,3 +47,5 @@
47 %li 47 %li
48 %span= link_to "System Hooks", help_system_hooks_path 48 %span= link_to "System Hooks", help_system_hooks_path
49 49
  50 + %li
  51 + %span= link_to "Public Area", help_public_area_path
app/views/help/public_area.html.haml 0 → 100644
@@ -0,0 +1,16 @@ @@ -0,0 +1,16 @@
  1 +%h3.page_title Public Area
  2 +.back_link
  3 + = link_to help_path do
  4 + &larr; to index
  5 +%hr
  6 +
  7 +%p
  8 + Public area - is part of application with public access.
  9 + %br
  10 + It used to list all projects with public read-only access.
  11 + %br
  12 + If you enable public http access to the project - it will appears there
  13 + %br
  14 +
  15 + Follow #{link_to "this link", public_root_path} to visit Public Area
  16 +
app/views/issues/show.html.haml
@@ -51,8 +51,9 @@ @@ -51,8 +51,9 @@
51 51
52 - if @issue.description.present? 52 - if @issue.description.present?
53 .ui-box-bottom 53 .ui-box-bottom
54 - = preserve do  
55 - = markdown @issue.description 54 + .wiki
  55 + = preserve do
  56 + = markdown @issue.description
56 57
57 58
58 .voting_notes#notes= render "notes/notes_with_form" 59 .voting_notes#notes= render "notes/notes_with_form"
app/views/keys/create.js.haml
@@ -1,9 +0,0 @@ @@ -1,9 +0,0 @@
1 -- if @key.valid?  
2 - :plain  
3 - $("#new_key_dialog").dialog("close");  
4 - $("#keys-table .data").append("#{escape_javascript(render(partial: 'show', locals: {key: @key}))}");  
5 - $("#no_ssh_key_defined").hide();  
6 -- else  
7 - :plain  
8 - $("#new_key_dialog").empty();  
9 - $("#new_key_dialog").append("#{escape_javascript(render('form'))}");  
app/views/keys/new.js.haml
@@ -1,11 +0,0 @@ @@ -1,11 +0,0 @@
1 -:plain  
2 - var new_key_dialog = $("<div id='new_key_dialog'></div>");  
3 - new_key_dialog.html("#{escape_javascript(render('form'))}");  
4 - $(new_key_dialog).dialog({  
5 - width: 350,  
6 - resizable: false,  
7 - draggable: false,  
8 - title: "Add new public key",  
9 - close: function(event, ui) { $("#new_key_dialog").remove();},  
10 - modal: true  
11 - });  
app/views/layouts/_head.html.haml
@@ -6,12 +6,14 @@ @@ -6,12 +6,14 @@
6 = favicon_link_tag 'favicon.ico' 6 = favicon_link_tag 'favicon.ico'
7 = stylesheet_link_tag "application" 7 = stylesheet_link_tag "application"
8 = javascript_include_tag "application" 8 = javascript_include_tag "application"
9 - -# Atom feed  
10 - - if controller_name == 'projects' && action_name == 'index'  
11 - = auto_discovery_link_tag :atom, projects_url(:atom, private_token: current_user.private_token), title: "Dashboard feed"  
12 - - if @project && !@project.new_record?  
13 - - if current_controller?(:tree, :commits)  
14 - = auto_discovery_link_tag(:atom, project_commits_url(@project, @ref, format: :atom, private_token: current_user.private_token), title: "Recent commits to #{@project.name}:#{@ref}")  
15 - - if current_controller?(:issues)  
16 - = auto_discovery_link_tag(:atom, project_issues_url(@project, :atom, private_token: current_user.private_token), title: "#{@project.name} issues")  
17 = csrf_meta_tags 9 = csrf_meta_tags
  10 +
  11 + -# Atom feed
  12 + - if current_user
  13 + - if controller_name == 'projects' && action_name == 'index'
  14 + = auto_discovery_link_tag :atom, projects_url(:atom, private_token: current_user.private_token), title: "Dashboard feed"
  15 + - if @project && !@project.new_record?
  16 + - if current_controller?(:tree, :commits)
  17 + = auto_discovery_link_tag(:atom, project_commits_url(@project, @ref, format: :atom, private_token: current_user.private_token), title: "Recent commits to #{@project.name}:#{@ref}")
  18 + - if current_controller?(:issues)
  19 + = auto_discovery_link_tag(:atom, project_issues_url(@project, :atom, private_token: current_user.private_token), title: "#{@project.name} issues")
app/views/layouts/application.html.haml
@@ -18,7 +18,7 @@ @@ -18,7 +18,7 @@
18 %span.count= current_user.cared_merge_requests.opened.count 18 %span.count= current_user.cared_merge_requests.opened.count
19 = nav_link(path: 'search#show') do 19 = nav_link(path: 'search#show') do
20 = link_to "Search", search_path 20 = link_to "Search", search_path
21 - = nav_link(path: 'help#index') do 21 + = nav_link(controller: :help) do
22 = link_to "Help", help_path 22 = link_to "Help", help_path
23 23
24 .content= yield 24 .content= yield
app/views/layouts/public.html.haml 0 → 100644
@@ -0,0 +1,17 @@ @@ -0,0 +1,17 @@
  1 +!!! 5
  2 +%html{ lang: "en"}
  3 + = render "layouts/head", title: "Public Area"
  4 + %body{class: "#{app_theme} application"}
  5 + %header.navbar.navbar-static-top.navbar-gitlab
  6 + .navbar-inner
  7 + .container
  8 + %div.app_logo
  9 + %span.separator
  10 + = link_to root_path, class: "home" do
  11 + %h1 GITLAB
  12 + %span.separator
  13 + %h1.project_name Public Area
  14 + .container
  15 + .content
  16 + .prepend-top-20
  17 + = yield
app/views/public/projects/index.html.haml 0 → 100644
@@ -0,0 +1,17 @@ @@ -0,0 +1,17 @@
  1 +%h3.page_title
  2 + Projects
  3 + %small Read-Only Access
  4 +%hr
  5 +
  6 +%ul.unstyled
  7 + - @projects.each do |project|
  8 + %li.clearfix
  9 + %h5
  10 + %i.icon-star.cgreen
  11 + = project.name_with_namespace
  12 + .right
  13 + %span.monospace.tiny
  14 + git clone #{project.http_url_to_repo}
  15 +
  16 +
  17 += paginate @projects, theme: "admin"
app/views/shared/_clone_panel.html.haml
1 .input-prepend.project_clone_holder 1 .input-prepend.project_clone_holder
2 %button{class: "btn active", :"data-clone" => @project.ssh_url_to_repo} SSH 2 %button{class: "btn active", :"data-clone" => @project.ssh_url_to_repo} SSH
3 %button{class: "btn", :"data-clone" => @project.http_url_to_repo}= Gitlab.config.gitlab.protocol.upcase 3 %button{class: "btn", :"data-clone" => @project.http_url_to_repo}= Gitlab.config.gitlab.protocol.upcase
  4 +
4 = text_field_tag :project_clone, @project.url_to_repo, class: "one_click_select input-xxlarge" 5 = text_field_tag :project_clone, @project.url_to_repo, class: "one_click_select input-xxlarge"
app/views/shared/_merge_requests.html.haml 0 → 100644
@@ -0,0 +1,14 @@ @@ -0,0 +1,14 @@
  1 +- if @merge_requests.any?
  2 + - @merge_requests.group_by(&:project).each do |group|
  3 + .ui-box
  4 + - project = group[0]
  5 + %h5.title
  6 + = link_to_project project
  7 + %ul.well-list
  8 + - group[1].each do |merge_request|
  9 + = render(partial: 'merge_requests/merge_request', locals: {merge_request: merge_request})
  10 + %hr
  11 + = paginate @merge_requests, theme: "gitlab"
  12 +
  13 +- else
  14 + %h3.nothing_here_message Nothing to show here
app/views/wikis/edit.html.haml
1 %h3.page_title Editing page 1 %h3.page_title Editing page
2 %hr 2 %hr
3 = render 'form' 3 = render 'form'
  4 +
  5 +.right
  6 + - if can? current_user, :admin_wiki, @project
  7 + = link_to project_wiki_path(@project, @wiki), confirm: "Are you sure you want to delete this page?", method: :delete, class: "btn small danger" do
  8 + Delete this page
4 \ No newline at end of file 9 \ No newline at end of file
app/views/wikis/empty.html.haml
1 %h3.page_title Empty page 1 %h3.page_title Empty page
2 %hr 2 %hr
3 -.alert-message.block-message.warning  
4 - %span You are not allowed to create wiki pages 3 +.error_message
  4 + You are not allowed to create wiki pages
app/views/wikis/history.html.haml
1 %h3.page_title 1 %h3.page_title
2 %span.cgray History for 2 %span.cgray History for
3 - = @wikis.last.title 3 + = @wiki_pages.first.title
4 %br 4 %br
5 %table 5 %table
6 %thead 6 %thead
7 %tr 7 %tr
8 - %th #  
9 - %th last edit  
10 - %th created by 8 + %th Page version
  9 + %th Last updated
  10 + %th Updated by
11 %tbody 11 %tbody
12 - - @wikis.each_with_index do |wiki_page, i| 12 + - @wiki_pages.each_with_index do |wiki_page, i|
13 %tr 13 %tr
14 - %td= i + 1  
15 %td 14 %td
16 - = link_to wiki_page.created_at.to_s(:short), project_wiki_path(@project, wiki_page, old_page_id: wiki_page.id) 15 + %strong
  16 + = link_to project_wiki_path(@project, wiki_page, version_id: wiki_page.id) do
  17 + Version
  18 + = @wiki_pages.count - i
  19 + %td
  20 + = wiki_page.created_at.to_s(:short)
17 (#{time_ago_in_words(wiki_page.created_at)} 21 (#{time_ago_in_words(wiki_page.created_at)}
18 ago) 22 ago)
19 - %td= wiki_page.user.name  
20 - 23 + %td= link_to_member(@project, wiki_page.user)
app/views/wikis/pages.html.haml
@@ -4,15 +4,17 @@ @@ -4,15 +4,17 @@
4 %thead 4 %thead
5 %tr 5 %tr
6 %th Title 6 %th Title
7 - %th slug  
8 - %th created by 7 + %th Slug
  8 + %th Last updated
  9 + %th Updated by
9 %tbody 10 %tbody
10 - - @wikis.each_with_index do |wiki_page, i| 11 + - @wiki_pages.each do |wiki_page|
11 %tr 12 %tr
12 %td 13 %td
13 - = link_to wiki_page.title, project_wiki_path(@project, wiki_page, old_page_id: wiki_page.id)  
14 - (#{time_ago_in_words(wiki_page.created_at)}  
15 - ago) 14 + %strong= link_to wiki_page.title, project_wiki_path(@project, wiki_page)
16 %td= wiki_page.slug 15 %td= wiki_page.slug
17 - %td= wiki_page.user.name  
18 - 16 + %td
  17 + = wiki_page.created_at.to_s(:short) do
  18 + (#{time_ago_in_words(wiki_page.created_at)}
  19 + ago)
  20 + %td= link_to_member(@project, wiki_page.user)
app/views/wikis/show.html.haml
@@ -10,12 +10,14 @@ @@ -10,12 +10,14 @@
10 %i.icon-edit 10 %i.icon-edit
11 Edit 11 Edit
12 %br 12 %br
  13 +- if @wiki != @most_recent_wiki
  14 + .warning_message
  15 + This is an old version of this page.
  16 + You can view the #{link_to "most recent version", project_wiki_path(@project, @wiki)} or browse the #{link_to "history", history_project_wiki_path(@project, @wiki)}.
  17 +
13 .file_holder 18 .file_holder
14 .file_content.wiki 19 .file_content.wiki
15 = preserve do 20 = preserve do
16 = markdown @wiki.content 21 = markdown @wiki.content
17 22
18 -%p.time Last edited by #{@wiki.user.name}, #{time_ago_in_words @wiki.created_at} ago  
19 -- if can? current_user, :admin_wiki, @project  
20 - = link_to project_wiki_path(@project, @wiki), confirm: "Are you sure you want to delete this page?", method: :delete do  
21 - Delete this page 23 +%p.time Last edited by #{link_to_member @project, @wiki.user}, #{time_ago_in_words @wiki.created_at} ago
config/initializers/passenger_fix.rb
@@ -1,16 +0,0 @@ @@ -1,16 +0,0 @@
1 -if defined?(PhusionPassenger)  
2 -  
3 - # When you're using Passenger with smart-lv2 (default) or smart spawn method,  
4 - # Resque doesn't recognize that it has been forked and should re-establish  
5 - # Redis connection. You can see this error message in log:  
6 - # Redis::InheritedError, Tried to use a connection from a child process  
7 - # without reconnecting. You need to reconnect to Redis after forking.  
8 - #  
9 - # This solution is based on  
10 - # https://github.com/redis/redis-rb/wiki/redis-rb-on-Phusion-Passenger  
11 - #  
12 - PhusionPassenger.on_event(:starting_worker_process) do |forked|  
13 - # if we're in smart spawning mode, reconnect to Redis  
14 - Resque.redis.client.reconnect if forked  
15 - end  
16 -end  
config/routes.rb
@@ -35,6 +35,15 @@ Gitlab::Application.routes.draw do @@ -35,6 +35,15 @@ Gitlab::Application.routes.draw do
35 get 'help/markdown' => 'help#markdown' 35 get 'help/markdown' => 'help#markdown'
36 get 'help/ssh' => 'help#ssh' 36 get 'help/ssh' => 'help#ssh'
37 get 'help/raketasks' => 'help#raketasks' 37 get 'help/raketasks' => 'help#raketasks'
  38 + get 'help/public_area' => 'help#public_area'
  39 +
  40 + #
  41 + # Public namespace
  42 + #
  43 + namespace :public do
  44 + resources :projects, only: [:index]
  45 + root to: "projects#index"
  46 + end
38 47
39 # 48 #
40 # Admin Area 49 # Admin Area
db/migrate/20130110172407_add_public_to_project.rb 0 → 100644
@@ -0,0 +1,5 @@ @@ -0,0 +1,5 @@
  1 +class AddPublicToProject < ActiveRecord::Migration
  2 + def change
  3 + add_column :projects, :public, :boolean, default: false, null: false
  4 + end
  5 +end
@@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@
11 # 11 #
12 # It's strongly recommended to check this file into your version control system. 12 # It's strongly recommended to check this file into your version control system.
13 13
14 -ActiveRecord::Schema.define(:version => 20130102143055) do 14 +ActiveRecord::Schema.define(:version => 20130110172407) do
15 15
16 create_table "events", :force => true do |t| 16 create_table "events", :force => true do |t|
17 t.string "target_type" 17 t.string "target_type"
@@ -145,16 +145,17 @@ ActiveRecord::Schema.define(:version =&gt; 20130102143055) do @@ -145,16 +145,17 @@ ActiveRecord::Schema.define(:version =&gt; 20130102143055) do
145 t.string "name" 145 t.string "name"
146 t.string "path" 146 t.string "path"
147 t.text "description" 147 t.text "description"
148 - t.datetime "created_at", :null => false  
149 - t.datetime "updated_at", :null => false  
150 - t.boolean "private_flag", :default => true, :null => false 148 + t.datetime "created_at", :null => false
  149 + t.datetime "updated_at", :null => false
  150 + t.boolean "private_flag", :default => true, :null => false
151 t.integer "creator_id" 151 t.integer "creator_id"
152 t.string "default_branch" 152 t.string "default_branch"
153 - t.boolean "issues_enabled", :default => true, :null => false  
154 - t.boolean "wall_enabled", :default => true, :null => false  
155 - t.boolean "merge_requests_enabled", :default => true, :null => false  
156 - t.boolean "wiki_enabled", :default => true, :null => false 153 + t.boolean "issues_enabled", :default => true, :null => false
  154 + t.boolean "wall_enabled", :default => true, :null => false
  155 + t.boolean "merge_requests_enabled", :default => true, :null => false
  156 + t.boolean "wiki_enabled", :default => true, :null => false
157 t.integer "namespace_id" 157 t.integer "namespace_id"
  158 + t.boolean "public", :default => false, :null => false
158 end 159 end
159 160
160 add_index "projects", ["creator_id"], :name => "index_projects_on_owner_id" 161 add_index "projects", ["creator_id"], :name => "index_projects_on_owner_id"
doc/install/installation.md
@@ -270,20 +270,6 @@ used for the `email.from` setting in `config/gitlab.yml`) @@ -270,20 +270,6 @@ used for the `email.from` setting in `config/gitlab.yml`)
270 sudo -u gitlab -H bundle exec rake gitlab:app:setup RAILS_ENV=production 270 sudo -u gitlab -H bundle exec rake gitlab:app:setup RAILS_ENV=production
271 271
272 272
273 -## Check Application Status  
274 -  
275 -Check if GitLab and its environment is configured correctly:  
276 -  
277 - sudo -u gitlab -H bundle exec rake gitlab:env:info RAILS_ENV=production  
278 -  
279 -To make sure you didn't miss anything run a more thorough check with:  
280 -  
281 - sudo -u gitlab -H bundle exec rake gitlab:check RAILS_ENV=production  
282 -  
283 -If you are all green: congratulations, you successfully installed GitLab!  
284 -Although this is the case, there are still a few steps to go.  
285 -  
286 -  
287 ## Install Init Script 273 ## Install Init Script
288 274
289 Download the init script (will be /etc/init.d/gitlab): 275 Download the init script (will be /etc/init.d/gitlab):
@@ -296,7 +282,20 @@ Make GitLab start on boot: @@ -296,7 +282,20 @@ Make GitLab start on boot:
296 sudo update-rc.d gitlab defaults 21 282 sudo update-rc.d gitlab defaults 21
297 283
298 284
299 -Start your GitLab instance: 285 +## Check Application Status
  286 +
  287 +Check if GitLab and its environment is configured correctly:
  288 +
  289 + sudo -u gitlab -H bundle exec rake gitlab:env:info RAILS_ENV=production
  290 +
  291 +To make sure you didn't miss anything run a more thorough check with:
  292 +
  293 + sudo -u gitlab -H bundle exec rake gitlab:check RAILS_ENV=production
  294 +
  295 +If all items are green, then congratulations on successfully installing GitLab!
  296 +However there are still a few steps left.
  297 +
  298 +## Start Your GitLab Instance
300 299
301 sudo service gitlab start 300 sudo service gitlab start
302 # or 301 # or
lib/gitlab/backend/grack_auth.rb
@@ -2,25 +2,41 @@ module Grack @@ -2,25 +2,41 @@ module Grack
2 class Auth < Rack::Auth::Basic 2 class Auth < Rack::Auth::Basic
3 attr_accessor :user, :project 3 attr_accessor :user, :project
4 4
5 - def valid?  
6 - # Authentication with username and password  
7 - login, password = @auth.credentials 5 + def call(env)
  6 + @env = env
  7 + @request = Rack::Request.new(env)
  8 + @auth = Request.new(env)
8 9
9 - self.user = User.find_by_email(login) || User.find_by_username(login) 10 + # Pass Gitolite update hook
  11 + ENV['GL_BYPASS_UPDATE_HOOK'] = "true"
10 12
11 - return false unless user.try(:valid_password?, password) 13 + # Need this patch due to the rails mount
  14 + @env['PATH_INFO'] = @request.path
  15 + @env['SCRIPT_NAME'] = ""
12 16
13 - email = user.email 17 + return render_not_found unless project
  18 + return unauthorized unless project.public || @auth.provided?
  19 + return bad_request if @auth.provided? && !@auth.basic?
14 20
15 - # Set GL_USER env variable  
16 - ENV['GL_USER'] = email  
17 - # Pass Gitolite update hook  
18 - ENV['GL_BYPASS_UPDATE_HOOK'] = "true" 21 + if valid?
  22 + if @auth.provided?
  23 + @env['REMOTE_USER'] = @auth.username
  24 + end
  25 + return @app.call(env)
  26 + else
  27 + unauthorized
  28 + end
  29 + end
19 30
20 - # Find project by PATH_INFO from env  
21 - if m = /^\/([\w\.\/-]+)\.git/.match(@request.path_info).to_a  
22 - self.project = Project.find_with_namespace(m.last)  
23 - return false unless project 31 + def valid?
  32 + if @auth.provided?
  33 + # Authentication with username and password
  34 + login, password = @auth.credentials
  35 + self.user = User.find_by_email(login) || User.find_by_username(login)
  36 + return false unless user.try(:valid_password?, password)
  37 +
  38 + # Set GL_USER env variable
  39 + ENV['GL_USER'] = user.email
24 end 40 end
25 41
26 # Git upload and receive 42 # Git upload and receive
@@ -34,12 +50,12 @@ module Grack @@ -34,12 +50,12 @@ module Grack
34 end 50 end
35 51
36 def validate_get_request 52 def validate_get_request
37 - can?(user, :download_code, project) 53 + project.public || can?(user, :download_code, project)
38 end 54 end
39 55
40 def validate_post_request 56 def validate_post_request
41 if @request.path_info.end_with?('git-upload-pack') 57 if @request.path_info.end_with?('git-upload-pack')
42 - can?(user, :download_code, project) 58 + project.public || can?(user, :download_code, project)
43 elsif @request.path_info.end_with?('git-receive-pack') 59 elsif @request.path_info.end_with?('git-receive-pack')
44 action = if project.protected_branch?(current_ref) 60 action = if project.protected_branch?(current_ref)
45 :push_code_to_protected_branches 61 :push_code_to_protected_branches
@@ -68,6 +84,22 @@ module Grack @@ -68,6 +84,22 @@ module Grack
68 /refs\/heads\/([\w\.-]+)/.match(input).to_a.first 84 /refs\/heads\/([\w\.-]+)/.match(input).to_a.first
69 end 85 end
70 86
  87 + def project
  88 + unless instance_variable_defined? :@project
  89 + # Find project by PATH_INFO from env
  90 + if m = /^\/([\w\.\/-]+)\.git/.match(@request.path_info).to_a
  91 + @project = Project.find_with_namespace(m.last)
  92 + end
  93 + end
  94 + return @project
  95 + end
  96 +
  97 + PLAIN_TYPE = {"Content-Type" => "text/plain"}
  98 +
  99 + def render_not_found
  100 + [404, PLAIN_TYPE, ["Not Found"]]
  101 + end
  102 +
71 protected 103 protected
72 104
73 def abilities 105 def abilities
lib/tasks/gitlab/check.rake
@@ -2,7 +2,7 @@ namespace :gitlab do @@ -2,7 +2,7 @@ namespace :gitlab do
2 desc "GITLAB | Check the configuration of GitLab and its environment" 2 desc "GITLAB | Check the configuration of GitLab and its environment"
3 task check: %w{gitlab:env:check 3 task check: %w{gitlab:env:check
4 gitlab:gitolite:check 4 gitlab:gitolite:check
5 - gitlab:resque:check 5 + gitlab:sidekiq:check
6 gitlab:app:check} 6 gitlab:app:check}
7 7
8 8
@@ -317,7 +317,7 @@ namespace :gitlab do @@ -317,7 +317,7 @@ namespace :gitlab do
317 gitolite_ssh_user = Gitlab.config.gitolite.ssh_user 317 gitolite_ssh_user = Gitlab.config.gitolite.ssh_user
318 print "Has no \"-e\" in ~#{gitolite_ssh_user}/.profile ... " 318 print "Has no \"-e\" in ~#{gitolite_ssh_user}/.profile ... "
319 319
320 - profile_file = File.join(gitolite_home, ".profile") 320 + profile_file = File.join(gitolite_user_home, ".profile")
321 321
322 unless File.read(profile_file) =~ /^-e PATH/ 322 unless File.read(profile_file) =~ /^-e PATH/
323 puts "yes".green 323 puts "yes".green
@@ -475,7 +475,7 @@ namespace :gitlab do @@ -475,7 +475,7 @@ namespace :gitlab do
475 def check_dot_gitolite_exists 475 def check_dot_gitolite_exists
476 print "Config directory exists? ... " 476 print "Config directory exists? ... "
477 477
478 - gitolite_config_path = File.join(gitolite_home, ".gitolite") 478 + gitolite_config_path = File.join(gitolite_user_home, ".gitolite")
479 479
480 if File.directory?(gitolite_config_path) 480 if File.directory?(gitolite_config_path)
481 puts "yes".green 481 puts "yes".green
@@ -496,13 +496,13 @@ namespace :gitlab do @@ -496,13 +496,13 @@ namespace :gitlab do
496 def check_dot_gitolite_permissions 496 def check_dot_gitolite_permissions
497 print "Config directory access is drwxr-x---? ... " 497 print "Config directory access is drwxr-x---? ... "
498 498
499 - gitolite_config_path = File.join(gitolite_home, ".gitolite") 499 + gitolite_config_path = File.join(gitolite_user_home, ".gitolite")
500 unless File.exists?(gitolite_config_path) 500 unless File.exists?(gitolite_config_path)
501 puts "can't check because of previous errors".magenta 501 puts "can't check because of previous errors".magenta
502 return 502 return
503 end 503 end
504 504
505 - if `stat --printf %a #{gitolite_config_path}` == "750" 505 + if File.stat(gitolite_config_path).mode.to_s(8).ends_with?("750")
506 puts "yes".green 506 puts "yes".green
507 else 507 else
508 puts "no".red 508 puts "no".red
@@ -520,18 +520,17 @@ namespace :gitlab do @@ -520,18 +520,17 @@ namespace :gitlab do
520 gitolite_ssh_user = Gitlab.config.gitolite.ssh_user 520 gitolite_ssh_user = Gitlab.config.gitolite.ssh_user
521 print "Config directory owned by #{gitolite_ssh_user}:#{gitolite_ssh_user} ... " 521 print "Config directory owned by #{gitolite_ssh_user}:#{gitolite_ssh_user} ... "
522 522
523 - gitolite_config_path = File.join(gitolite_home, ".gitolite") 523 + gitolite_config_path = File.join(gitolite_user_home, ".gitolite")
524 unless File.exists?(gitolite_config_path) 524 unless File.exists?(gitolite_config_path)
525 puts "can't check because of previous errors".magenta 525 puts "can't check because of previous errors".magenta
526 return 526 return
527 end 527 end
528 528
529 - if `stat --printf %U #{gitolite_config_path}` == gitolite_ssh_user && # user  
530 - `stat --printf %G #{gitolite_config_path}` == gitolite_ssh_user #group 529 + if File.stat(gitolite_config_path).uid == uid_for(gitolite_ssh_user) &&
  530 + File.stat(gitolite_config_path).gid == gid_for(gitolite_ssh_user)
531 puts "yes".green 531 puts "yes".green
532 else 532 else
533 puts "no".red 533 puts "no".red
534 - puts "#{gitolite_config_path} is not owned by #{gitolite_ssh_user}".red  
535 try_fixing_it( 534 try_fixing_it(
536 "sudo chown -R #{gitolite_ssh_user}:#{gitolite_ssh_user} #{gitolite_config_path}" 535 "sudo chown -R #{gitolite_ssh_user}:#{gitolite_ssh_user} #{gitolite_config_path}"
537 ) 536 )
@@ -559,7 +558,7 @@ namespace :gitlab do @@ -559,7 +558,7 @@ namespace :gitlab do
559 end 558 end
560 559
561 def check_gitoliterc_git_config_keys 560 def check_gitoliterc_git_config_keys
562 - gitoliterc_path = File.join(gitolite_home, ".gitolite.rc") 561 + gitoliterc_path = File.join(gitolite_user_home, ".gitolite.rc")
563 562
564 print "Allow all Git config keys in .gitolite.rc ... " 563 print "Allow all Git config keys in .gitolite.rc ... "
565 option_name = if has_gitolite3? 564 option_name = if has_gitolite3?
@@ -588,7 +587,7 @@ namespace :gitlab do @@ -588,7 +587,7 @@ namespace :gitlab do
588 end 587 end
589 588
590 def check_gitoliterc_repo_umask 589 def check_gitoliterc_repo_umask
591 - gitoliterc_path = File.join(gitolite_home, ".gitolite.rc") 590 + gitoliterc_path = File.join(gitolite_user_home, ".gitolite.rc")
592 591
593 print "Repo umask is 0007 in .gitolite.rc? ... " 592 print "Repo umask is 0007 in .gitolite.rc? ... "
594 option_name = if has_gitolite3? 593 option_name = if has_gitolite3?
@@ -722,11 +721,10 @@ namespace :gitlab do @@ -722,11 +721,10 @@ namespace :gitlab do
722 return 721 return
723 end 722 end
724 723
725 - if `stat --printf %a #{repo_base_path}` == "6770" 724 + if File.stat(repo_base_path).mode.to_s(8).ends_with?("6770")
726 puts "yes".green 725 puts "yes".green
727 else 726 else
728 puts "no".red 727 puts "no".red
729 - puts "#{repo_base_path} is not writable".red  
730 try_fixing_it( 728 try_fixing_it(
731 "sudo chmod -R ug+rwXs,o-rwx #{repo_base_path}" 729 "sudo chmod -R ug+rwXs,o-rwx #{repo_base_path}"
732 ) 730 )
@@ -747,12 +745,11 @@ namespace :gitlab do @@ -747,12 +745,11 @@ namespace :gitlab do
747 return 745 return
748 end 746 end
749 747
750 - if `stat --printf %U #{repo_base_path}` == gitolite_ssh_user && # user  
751 - `stat --printf %G #{repo_base_path}` == gitolite_ssh_user #group 748 + if File.stat(repo_base_path).uid == uid_for(gitolite_ssh_user) &&
  749 + File.stat(repo_base_path).gid == gid_for(gitolite_ssh_user)
752 puts "yes".green 750 puts "yes".green
753 else 751 else
754 puts "no".red 752 puts "no".red
755 - puts "#{repo_base_path} is not owned by #{gitolite_ssh_user}".red  
756 try_fixing_it( 753 try_fixing_it(
757 "sudo chown -R #{gitolite_ssh_user}:#{gitolite_ssh_user} #{repo_base_path}" 754 "sudo chown -R #{gitolite_ssh_user}:#{gitolite_ssh_user} #{repo_base_path}"
758 ) 755 )
@@ -833,7 +830,8 @@ namespace :gitlab do @@ -833,7 +830,8 @@ namespace :gitlab do
833 next 830 next
834 end 831 end
835 832
836 - if run_and_match("stat --format %N #{project_hook_file}", /#{hook_file}.+->.+#{gitolite_hook_file}/) 833 + if File.lstat(project_hook_file).symlink? &&
  834 + File.realpath(project_hook_file) == File.realpath(gitolite_hook_file)
837 puts "ok".green 835 puts "ok".green
838 else 836 else
839 puts "not a link to Gitolite's hook".red 837 puts "not a link to Gitolite's hook".red
@@ -852,12 +850,12 @@ namespace :gitlab do @@ -852,12 +850,12 @@ namespace :gitlab do
852 # Helper methods 850 # Helper methods
853 ######################## 851 ########################
854 852
855 - def gitolite_home 853 + def gitolite_user_home
856 File.expand_path("~#{Gitlab.config.gitolite.ssh_user}") 854 File.expand_path("~#{Gitlab.config.gitolite.ssh_user}")
857 end 855 end
858 856
859 def gitolite_version 857 def gitolite_version
860 - gitolite_version_file = "#{gitolite_home}/gitolite/src/VERSION" 858 + gitolite_version_file = "#{gitolite_user_home}/gitolite/src/VERSION"
861 if File.readable?(gitolite_version_file) 859 if File.readable?(gitolite_version_file)
862 File.read(gitolite_version_file) 860 File.read(gitolite_version_file)
863 end 861 end
@@ -870,22 +868,22 @@ namespace :gitlab do @@ -870,22 +868,22 @@ namespace :gitlab do
870 868
871 869
872 870
873 - namespace :resque do 871 + namespace :sidekiq do
874 desc "GITLAB | Check the configuration of Sidekiq" 872 desc "GITLAB | Check the configuration of Sidekiq"
875 task check: :environment do 873 task check: :environment do
876 warn_user_is_not_gitlab 874 warn_user_is_not_gitlab
877 - start_checking "Resque" 875 + start_checking "Sidekiq"
878 876
879 - check_resque_running 877 + check_sidekiq_running
880 878
881 - finished_checking "Resque" 879 + finished_checking "Sidekiq"
882 end 880 end
883 881
884 882
885 # Checks 883 # Checks
886 ######################## 884 ########################
887 885
888 - def check_resque_running 886 + def check_sidekiq_running
889 print "Running? ... " 887 print "Running? ... "
890 888
891 if run_and_match("ps aux | grep -i sidekiq", /sidekiq \d\.\d\.\d.+$/) 889 if run_and_match("ps aux | grep -i sidekiq", /sidekiq \d\.\d\.\d.+$/)
@@ -893,9 +891,7 @@ namespace :gitlab do @@ -893,9 +891,7 @@ namespace :gitlab do
893 else 891 else
894 puts "no".red 892 puts "no".red
895 try_fixing_it( 893 try_fixing_it(
896 - "sudo service gitlab restart",  
897 - "or",  
898 - "sudo /etc/init.d/gitlab restart" 894 + "sudo -u gitlab -H bundle exec rake sidekiq:start"
899 ) 895 )
900 for_more_information( 896 for_more_information(
901 see_installation_guide_section("Install Init Script"), 897 see_installation_guide_section("Install Init Script"),
lib/tasks/gitlab/info.rake
@@ -3,20 +3,6 @@ namespace :gitlab do @@ -3,20 +3,6 @@ namespace :gitlab do
3 desc "GITLAB | Show information about GitLab and its environment" 3 desc "GITLAB | Show information about GitLab and its environment"
4 task info: :environment do 4 task info: :environment do
5 5
6 - # check which OS is running  
7 - os_name = run("lsb_release -irs")  
8 - os_name ||= if File.readable?('/etc/system-release')  
9 - File.read('/etc/system-release')  
10 - end  
11 - os_name ||= if File.readable?('/etc/debian_version')  
12 - debian_version = File.read('/etc/debian_version')  
13 - "Debian #{debian_version}"  
14 - end  
15 - os_name ||= if File.readable?('/etc/SuSE-release')  
16 - File.read('/etc/SuSE-release')  
17 - end  
18 - os_name.try(:squish!)  
19 -  
20 # check if there is an RVM environment 6 # check if there is an RVM environment
21 rvm_version = run_and_match("rvm --version", /[\d\.]+/).try(:to_s) 7 rvm_version = run_and_match("rvm --version", /[\d\.]+/).try(:to_s)
22 # check Ruby version 8 # check Ruby version
lib/tasks/gitlab/task_helpers.rake
1 namespace :gitlab do 1 namespace :gitlab do
2 2
  3 + # Check which OS is running
  4 + #
  5 + # It will primarily use lsb_relase to determine the OS.
  6 + # It has fallbacks to Debian, SuSE and OS X.
  7 + def os_name
  8 + os_name = run("lsb_release -irs")
  9 + os_name ||= if File.readable?('/etc/system-release')
  10 + File.read('/etc/system-release')
  11 + end
  12 + os_name ||= if File.readable?('/etc/debian_version')
  13 + debian_version = File.read('/etc/debian_version')
  14 + "Debian #{debian_version}"
  15 + end
  16 + os_name ||= if File.readable?('/etc/SuSE-release')
  17 + File.read('/etc/SuSE-release')
  18 + end
  19 + os_name ||= if os_x_version = run("sw_vers -productVersion")
  20 + "Mac OS X #{os_x_version}"
  21 + end
  22 + os_name.try(:squish!)
  23 + end
  24 +
3 # Runs the given command and matches the output agains the given pattern 25 # Runs the given command and matches the output agains the given pattern
4 # 26 #
5 # Returns nil if nothing matched 27 # Returns nil if nothing matched
@@ -23,6 +45,15 @@ namespace :gitlab do @@ -23,6 +45,15 @@ namespace :gitlab do
23 end 45 end
24 end 46 end
25 47
  48 + def uid_for(user_name)
  49 + run("id -u #{user_name}").chomp.to_i
  50 + end
  51 +
  52 + def gid_for(group_name)
  53 + group_line = File.read("/etc/group").lines.select{|l| l.start_with?("#{group_name}:")}.first
  54 + group_line.split(":")[2].to_i
  55 + end
  56 +
26 def warn_user_is_not_gitlab 57 def warn_user_is_not_gitlab
27 unless @warned_user_not_gitlab 58 unless @warned_user_not_gitlab
28 current_user = run("whoami").chomp 59 current_user = run("whoami").chomp
lib/tasks/sidekiq.rake
@@ -6,18 +6,10 @@ namespace :sidekiq do @@ -6,18 +6,10 @@ namespace :sidekiq do
6 6
7 desc "GITLAB | Start sidekiq" 7 desc "GITLAB | Start sidekiq"
8 task :start do 8 task :start do
9 - run "nohup bundle exec sidekiq -q post_receive,mailer,system_hook,common,default -e #{rails_env} -P #{pidfile} >> #{root_path}/log/sidekiq.log 2>&1 &"  
10 - end  
11 -  
12 - def root_path  
13 - @root_path ||= File.join(File.expand_path(File.dirname(__FILE__)), "../..") 9 + run "nohup bundle exec sidekiq -q post_receive,mailer,system_hook,common,default -e #{Rails.env} -P #{pidfile} >> #{Rails.root.join("log", "sidekiq.log")} 2>&1 &"
14 end 10 end
15 11
16 def pidfile 12 def pidfile
17 - "#{root_path}/tmp/pids/sidekiq.pid"  
18 - end  
19 -  
20 - def rails_env  
21 - ENV['RAILS_ENV'] || "production" 13 + Rails.root.join("tmp", "pids", "sidekiq.pid")
22 end 14 end
23 end 15 end