Commit eefb27f5ae0edf0c005eb8ce6da56cbd17c9aa8a
Exists in
master
and in
4 other branches
Merge branch 'master' into fixes/api
Conflicts: spec/requests/api/projects_spec.rb
Showing
135 changed files
with
1141 additions
and
884 deletions
Show diff stats
Too many changes.
To preserve performance only 100 of 135 files displayed.
.gitignore
@@ -2,7 +2,7 @@ | @@ -2,7 +2,7 @@ | ||
2 | .rbx/ | 2 | .rbx/ |
3 | db/*.sqlite3 | 3 | db/*.sqlite3 |
4 | db/*.sqlite3-journal | 4 | db/*.sqlite3-journal |
5 | -log/*.log | 5 | +log/*.log* |
6 | tmp/ | 6 | tmp/ |
7 | .sass-cache/ | 7 | .sass-cache/ |
8 | coverage/* | 8 | coverage/* |
@@ -20,6 +20,7 @@ config/database.yml | @@ -20,6 +20,7 @@ config/database.yml | ||
20 | config/initializers/omniauth.rb | 20 | config/initializers/omniauth.rb |
21 | config/unicorn.rb | 21 | config/unicorn.rb |
22 | config/resque.yml | 22 | config/resque.yml |
23 | +config/aws.yml | ||
23 | db/data.yml | 24 | db/data.yml |
24 | .idea | 25 | .idea |
25 | .DS_Store | 26 | .DS_Store |
Gemfile
@@ -70,6 +70,9 @@ gem "github-markup", "~> 0.7.4", require: 'github/markup' | @@ -70,6 +70,9 @@ gem "github-markup", "~> 0.7.4", require: 'github/markup' | ||
70 | # Servers | 70 | # Servers |
71 | gem "unicorn", "~> 4.4.0" | 71 | gem "unicorn", "~> 4.4.0" |
72 | 72 | ||
73 | +# State machine | ||
74 | +gem "state_machine" | ||
75 | + | ||
73 | # Issue tags | 76 | # Issue tags |
74 | gem "acts-as-taggable-on", "2.3.3" | 77 | gem "acts-as-taggable-on", "2.3.3" |
75 | 78 |
Gemfile.lock
@@ -425,6 +425,7 @@ GEM | @@ -425,6 +425,7 @@ GEM | ||
425 | rack (~> 1.0) | 425 | rack (~> 1.0) |
426 | tilt (~> 1.1, != 1.3.0) | 426 | tilt (~> 1.1, != 1.3.0) |
427 | stamp (0.3.0) | 427 | stamp (0.3.0) |
428 | + state_machine (1.1.2) | ||
428 | temple (0.5.5) | 429 | temple (0.5.5) |
429 | test_after_commit (0.0.1) | 430 | test_after_commit (0.0.1) |
430 | therubyracer (0.10.2) | 431 | therubyracer (0.10.2) |
@@ -536,6 +537,7 @@ DEPENDENCIES | @@ -536,6 +537,7 @@ DEPENDENCIES | ||
536 | slim | 537 | slim |
537 | spinach-rails | 538 | spinach-rails |
538 | stamp | 539 | stamp |
540 | + state_machine | ||
539 | test_after_commit | 541 | test_after_commit |
540 | therubyracer | 542 | therubyracer |
541 | thin | 543 | thin |
app/assets/javascripts/main.js.coffee
@@ -49,6 +49,10 @@ $ -> | @@ -49,6 +49,10 @@ $ -> | ||
49 | # Bottom tooltip | 49 | # Bottom tooltip |
50 | $('.has_bottom_tooltip').tooltip(placement: 'bottom') | 50 | $('.has_bottom_tooltip').tooltip(placement: 'bottom') |
51 | 51 | ||
52 | + # Form submitter | ||
53 | + $('.trigger-submit').on 'change', -> | ||
54 | + $(@).parents('form').submit() | ||
55 | + | ||
52 | # Flash | 56 | # Flash |
53 | if (flash = $("#flash-container")).length > 0 | 57 | if (flash = $("#flash-container")).length > 0 |
54 | flash.click -> $(@).slideUp("slow") | 58 | flash.click -> $(@).slideUp("slow") |
app/assets/javascripts/merge_requests.js.coffee
@@ -27,7 +27,7 @@ class MergeRequest | @@ -27,7 +27,7 @@ class MergeRequest | ||
27 | this.$el.find(selector) | 27 | this.$el.find(selector) |
28 | 28 | ||
29 | initMergeWidget: -> | 29 | initMergeWidget: -> |
30 | - this.showState( @opts.current_state ) | 30 | + this.showState( @opts.current_status ) |
31 | 31 | ||
32 | if this.$('.automerge_widget').length and @opts.check_enable | 32 | if this.$('.automerge_widget').length and @opts.check_enable |
33 | $.get @opts.url_to_automerge_check, (data) => | 33 | $.get @opts.url_to_automerge_check, (data) => |
app/assets/stylesheets/gitlab_bootstrap/mixins.scss
@@ -63,7 +63,7 @@ | @@ -63,7 +63,7 @@ | ||
63 | color: $style_color; | 63 | color: $style_color; |
64 | text-shadow: 0 1px 1px #FFF; | 64 | text-shadow: 0 1px 1px #FFF; |
65 | font-family: 'Yanone', sans-serif; | 65 | font-family: 'Yanone', sans-serif; |
66 | - font-size: 26px; | ||
67 | - line-height: 42px; | 66 | + font-size: 24px; |
67 | + line-height: 36px; | ||
68 | font-weight: normal; | 68 | font-weight: normal; |
69 | } | 69 | } |
app/assets/stylesheets/sections/commits.scss
@@ -29,7 +29,7 @@ | @@ -29,7 +29,7 @@ | ||
29 | a{ | 29 | a{ |
30 | color: $style_color; | 30 | color: $style_color; |
31 | } | 31 | } |
32 | - | 32 | + |
33 | > span { | 33 | > span { |
34 | font-family: $monospace_font; | 34 | font-family: $monospace_font; |
35 | font-size: 14px; | 35 | font-size: 14px; |
@@ -124,7 +124,7 @@ | @@ -124,7 +124,7 @@ | ||
124 | .wrap{ | 124 | .wrap{ |
125 | display: inline-block; | 125 | display: inline-block; |
126 | } | 126 | } |
127 | - | 127 | + |
128 | .frame { | 128 | .frame { |
129 | display: inline-block; | 129 | display: inline-block; |
130 | background-color: #fff; | 130 | background-color: #fff; |
@@ -149,7 +149,7 @@ | @@ -149,7 +149,7 @@ | ||
149 | 149 | ||
150 | .view.swipe{ | 150 | .view.swipe{ |
151 | position: relative; | 151 | position: relative; |
152 | - | 152 | + |
153 | .swipe-frame{ | 153 | .swipe-frame{ |
154 | display: block; | 154 | display: block; |
155 | margin: auto; | 155 | margin: auto; |
@@ -228,7 +228,7 @@ | @@ -228,7 +228,7 @@ | ||
228 | bottom: 0px; | 228 | bottom: 0px; |
229 | left: 50%; | 229 | left: 50%; |
230 | margin-left: -150px; | 230 | margin-left: -150px; |
231 | - | 231 | + |
232 | .drag-track{ | 232 | .drag-track{ |
233 | display: block; | 233 | display: block; |
234 | position: absolute; | 234 | position: absolute; |
@@ -237,7 +237,7 @@ | @@ -237,7 +237,7 @@ | ||
237 | width: 276px; | 237 | width: 276px; |
238 | background: url('onion_skin_sprites.gif') -4px -20px repeat-x; | 238 | background: url('onion_skin_sprites.gif') -4px -20px repeat-x; |
239 | } | 239 | } |
240 | - | 240 | + |
241 | .dragger { | 241 | .dragger { |
242 | display: block; | 242 | display: block; |
243 | position: absolute; | 243 | position: absolute; |
@@ -248,7 +248,7 @@ | @@ -248,7 +248,7 @@ | ||
248 | background: url('onion_skin_sprites.gif') 0px -34px repeat-x; | 248 | background: url('onion_skin_sprites.gif') 0px -34px repeat-x; |
249 | cursor: pointer; | 249 | cursor: pointer; |
250 | } | 250 | } |
251 | - | 251 | + |
252 | .transparent { | 252 | .transparent { |
253 | display: block; | 253 | display: block; |
254 | position: absolute; | 254 | position: absolute; |
@@ -258,7 +258,7 @@ | @@ -258,7 +258,7 @@ | ||
258 | width: 10px; | 258 | width: 10px; |
259 | background: url('onion_skin_sprites.gif') -2px 0px no-repeat; | 259 | background: url('onion_skin_sprites.gif') -2px 0px no-repeat; |
260 | } | 260 | } |
261 | - | 261 | + |
262 | .opaque { | 262 | .opaque { |
263 | display: block; | 263 | display: block; |
264 | position: absolute; | 264 | position: absolute; |
@@ -275,19 +275,19 @@ | @@ -275,19 +275,19 @@ | ||
275 | 275 | ||
276 | padding: 10px; | 276 | padding: 10px; |
277 | text-align: center; | 277 | text-align: center; |
278 | - | 278 | + |
279 | background-image: -webkit-gradient(linear, 0 0, 0 30, color-stop(0.066, #eee), to(#dfdfdf)); | 279 | background-image: -webkit-gradient(linear, 0 0, 0 30, color-stop(0.066, #eee), to(#dfdfdf)); |
280 | background-image: -webkit-linear-gradient(#eee 6.6%, #dfdfdf); | 280 | background-image: -webkit-linear-gradient(#eee 6.6%, #dfdfdf); |
281 | background-image: -moz-linear-gradient(#eee 6.6%, #dfdfdf); | 281 | background-image: -moz-linear-gradient(#eee 6.6%, #dfdfdf); |
282 | background-image: -o-linear-gradient(#eee 6.6%, #dfdfdf); | 282 | background-image: -o-linear-gradient(#eee 6.6%, #dfdfdf); |
283 | - | 283 | + |
284 | ul, li{ | 284 | ul, li{ |
285 | list-style: none; | 285 | list-style: none; |
286 | margin: 0; | 286 | margin: 0; |
287 | padding: 0; | 287 | padding: 0; |
288 | display: inline-block; | 288 | display: inline-block; |
289 | } | 289 | } |
290 | - | 290 | + |
291 | li{ | 291 | li{ |
292 | color: grey; | 292 | color: grey; |
293 | border-left: 1px solid #c1c1c1; | 293 | border-left: 1px solid #c1c1c1; |
@@ -322,12 +322,12 @@ | @@ -322,12 +322,12 @@ | ||
322 | } | 322 | } |
323 | .commit-author, .commit-committer{ | 323 | .commit-author, .commit-committer{ |
324 | display: block; | 324 | display: block; |
325 | - color: #999; | ||
326 | - font-weight: normal; | 325 | + color: #999; |
326 | + font-weight: normal; | ||
327 | font-style: italic; | 327 | font-style: italic; |
328 | } | 328 | } |
329 | .commit-author strong, .commit-committer strong{ | 329 | .commit-author strong, .commit-committer strong{ |
330 | - font-weight: bold; | 330 | + font-weight: bold; |
331 | font-style: normal; | 331 | font-style: normal; |
332 | } | 332 | } |
333 | 333 | ||
@@ -337,7 +337,6 @@ | @@ -337,7 +337,6 @@ | ||
337 | */ | 337 | */ |
338 | .commit { | 338 | .commit { |
339 | .browse_code_link_holder { | 339 | .browse_code_link_holder { |
340 | - @extend .span2; | ||
341 | float: right; | 340 | float: right; |
342 | } | 341 | } |
343 | 342 |
app/assets/stylesheets/sections/header.scss
@@ -5,15 +5,16 @@ | @@ -5,15 +5,16 @@ | ||
5 | header { | 5 | header { |
6 | &.navbar-gitlab { | 6 | &.navbar-gitlab { |
7 | .navbar-inner { | 7 | .navbar-inner { |
8 | - height: 45px; | ||
9 | - padding: 5px; | 8 | + height: 40px; |
9 | + padding: 3px; | ||
10 | background: #F1F1F1; | 10 | background: #F1F1F1; |
11 | + filter: none; | ||
11 | 12 | ||
12 | .nav > li > a { | 13 | .nav > li > a { |
13 | color: $style_color; | 14 | color: $style_color; |
14 | text-shadow: 0 1px 0 #fff; | 15 | text-shadow: 0 1px 0 #fff; |
15 | - font-size: 18px; | ||
16 | - padding: 12px; | 16 | + font-size: 16px; |
17 | + padding: 10px; | ||
17 | } | 18 | } |
18 | 19 | ||
19 | /** NAV block with links and profile **/ | 20 | /** NAV block with links and profile **/ |
@@ -25,7 +26,6 @@ header { | @@ -25,7 +26,6 @@ header { | ||
25 | } | 26 | } |
26 | 27 | ||
27 | z-index: 10; | 28 | z-index: 10; |
28 | - /*height: 60px;*/ | ||
29 | 29 | ||
30 | /** | 30 | /** |
31 | * | 31 | * |
@@ -34,7 +34,7 @@ header { | @@ -34,7 +34,7 @@ header { | ||
34 | */ | 34 | */ |
35 | .app_logo { | 35 | .app_logo { |
36 | float: left; | 36 | float: left; |
37 | - margin-right: 15px; | 37 | + margin-right: 9px; |
38 | position: relative; | 38 | position: relative; |
39 | top: -5px; | 39 | top: -5px; |
40 | padding-top: 5px; | 40 | padding-top: 5px; |
@@ -42,10 +42,10 @@ header { | @@ -42,10 +42,10 @@ header { | ||
42 | a { | 42 | a { |
43 | float: left; | 43 | float: left; |
44 | padding: 0px; | 44 | padding: 0px; |
45 | - margin: 0 10px; | 45 | + margin: 0 6px; |
46 | 46 | ||
47 | h1 { | 47 | h1 { |
48 | - background: url('logo_dark.png') no-repeat 0px 2px; | 48 | + background: url('logo_dark.png') no-repeat center 1px; |
49 | float: left; | 49 | float: left; |
50 | height: 40px; | 50 | height: 40px; |
51 | width: 40px; | 51 | width: 40px; |
@@ -79,7 +79,6 @@ header { | @@ -79,7 +79,6 @@ header { | ||
79 | .search { | 79 | .search { |
80 | margin-right: 45px; | 80 | margin-right: 45px; |
81 | margin-left: 10px; | 81 | margin-left: 10px; |
82 | - margin-top: 2px; | ||
83 | 82 | ||
84 | .search-input { | 83 | .search-input { |
85 | @extend .span2; | 84 | @extend .span2; |
@@ -105,7 +104,7 @@ header { | @@ -105,7 +104,7 @@ header { | ||
105 | .account-box { | 104 | .account-box { |
106 | position: absolute; | 105 | position: absolute; |
107 | right: 0; | 106 | right: 0; |
108 | - top: 6px; | 107 | + top: 4px; |
109 | z-index: 10000; | 108 | z-index: 10000; |
110 | width: 128px; | 109 | width: 128px; |
111 | font-size: 11px; | 110 | font-size: 11px; |
@@ -228,6 +227,7 @@ header { | @@ -228,6 +227,7 @@ header { | ||
228 | .search-input { | 227 | .search-input { |
229 | background-color: #D2D5DA; | 228 | background-color: #D2D5DA; |
230 | background-color: rgba(255, 255, 255, 0.5); | 229 | background-color: rgba(255, 255, 255, 0.5); |
230 | + border: 1px solid #AAA; | ||
231 | 231 | ||
232 | &:focus { | 232 | &:focus { |
233 | background-color: white; | 233 | background-color: white; |
@@ -240,13 +240,16 @@ header { | @@ -240,13 +240,16 @@ header { | ||
240 | .app_logo { | 240 | .app_logo { |
241 | a { | 241 | a { |
242 | h1 { | 242 | h1 { |
243 | - background: url('logo_white.png') no-repeat center center; | 243 | + background: url('logo_white.png') no-repeat center 1px; |
244 | color: #fff; | 244 | color: #fff; |
245 | text-shadow: 0 1px 1px #111; | 245 | text-shadow: 0 1px 1px #111; |
246 | } | 246 | } |
247 | } | 247 | } |
248 | } | 248 | } |
249 | .project_name { | 249 | .project_name { |
250 | + a { | ||
251 | + color: #FFF; | ||
252 | + } | ||
250 | color: #fff; | 253 | color: #fff; |
251 | text-shadow: 0 1px 1px #111; | 254 | text-shadow: 0 1px 1px #111; |
252 | } | 255 | } |
@@ -261,11 +264,11 @@ header { | @@ -261,11 +264,11 @@ header { | ||
261 | 264 | ||
262 | .separator { | 265 | .separator { |
263 | float: left; | 266 | float: left; |
264 | - height: 60px; | 267 | + height: 46px; |
265 | width: 1px; | 268 | width: 1px; |
266 | background: white; | 269 | background: white; |
267 | border-left: 1px solid #DDD; | 270 | border-left: 1px solid #DDD; |
268 | - margin-top: -10px; | 271 | + margin-top: -3px; |
269 | margin-left: 10px; | 272 | margin-left: 10px; |
270 | margin-right: 10px; | 273 | margin-right: 10px; |
271 | } | 274 | } |
app/assets/stylesheets/sections/projects.scss
app/assets/stylesheets/themes/ui_mars.scss
@@ -8,66 +8,27 @@ | @@ -8,66 +8,27 @@ | ||
8 | * | 8 | * |
9 | */ | 9 | */ |
10 | .ui_mars { | 10 | .ui_mars { |
11 | - | ||
12 | /* | 11 | /* |
13 | * Application Header | 12 | * Application Header |
14 | * | 13 | * |
15 | */ | 14 | */ |
16 | header { | 15 | header { |
17 | - | 16 | + @extend .header-dark; |
18 | &.navbar-gitlab { | 17 | &.navbar-gitlab { |
19 | .navbar-inner { | 18 | .navbar-inner { |
20 | - background: #474D57 url('bg-header.png') repeat-x bottom; | ||
21 | - border-bottom: 1px solid #444; | ||
22 | - | ||
23 | - .nav > li > a { | ||
24 | - color: #eee; | ||
25 | - text-shadow: 0 1px 0 #444; | 19 | + background: #474D57; |
20 | + border-bottom: 1px solid #373D47; | ||
21 | + .app_logo { | ||
22 | + &:hover { | ||
23 | + background-color: #373D47; | ||
24 | + } | ||
26 | } | 25 | } |
27 | } | 26 | } |
28 | } | 27 | } |
29 | 28 | ||
30 | - .search { | ||
31 | - float: right; | ||
32 | - margin-right: 45px; | ||
33 | - .search-input { | ||
34 | - border: 1px solid rgba(0, 0, 0, 0.7); | ||
35 | - background-color: #D2D5DA; | ||
36 | - background-color: rgba(255, 255, 255, 0.5); | ||
37 | - | ||
38 | - &:focus { | ||
39 | - background-color: white; | ||
40 | - } | ||
41 | - } | ||
42 | - } | ||
43 | - .search-input::-webkit-input-placeholder { | ||
44 | - color: #666; | ||
45 | - } | ||
46 | - .app_logo { | ||
47 | - a { | ||
48 | - h1 { | ||
49 | - background: url('logo_white.png') no-repeat center center; | ||
50 | - color: #eee; | ||
51 | - text-shadow: 0 1px 1px #111; | ||
52 | - } | ||
53 | - } | ||
54 | - &:hover { | ||
55 | - background-color: #41464e; | ||
56 | - } | ||
57 | - } | ||
58 | - .project_name { | ||
59 | - color: #eee; | ||
60 | - text-shadow: 0 1px 1px #111; | 29 | + .separator { |
30 | + background: #31363E; | ||
31 | + border-left: 1px solid #666; | ||
61 | } | 32 | } |
62 | } | 33 | } |
63 | - | ||
64 | - .separator { | ||
65 | - background: #31363E; | ||
66 | - border-left: 1px solid #666; | ||
67 | - } | ||
68 | - | ||
69 | - /* | ||
70 | - * End of Application Header | ||
71 | - * | ||
72 | - */ | ||
73 | } | 34 | } |
app/contexts/merge_requests_load_context.rb
@@ -14,7 +14,7 @@ class MergeRequestsLoadContext < BaseContext | @@ -14,7 +14,7 @@ class MergeRequestsLoadContext < BaseContext | ||
14 | end | 14 | end |
15 | 15 | ||
16 | merge_requests = merge_requests.page(params[:page]).per(20) | 16 | merge_requests = merge_requests.page(params[:page]).per(20) |
17 | - merge_requests = merge_requests.includes(:author, :project).order("closed, created_at desc") | 17 | + merge_requests = merge_requests.includes(:author, :project).order("state, created_at desc") |
18 | 18 | ||
19 | # Filter by specific assignee_id (or lack thereof)? | 19 | # Filter by specific assignee_id (or lack thereof)? |
20 | if params[:assignee_id].present? | 20 | if params[:assignee_id].present? |
app/contexts/projects/create_context.rb
@@ -38,6 +38,8 @@ module Projects | @@ -38,6 +38,8 @@ module Projects | ||
38 | if @project.valid? && @project.import_url.present? | 38 | if @project.valid? && @project.import_url.present? |
39 | shell = Gitlab::Shell.new | 39 | shell = Gitlab::Shell.new |
40 | if shell.import_repository(@project.path_with_namespace, @project.import_url) | 40 | if shell.import_repository(@project.path_with_namespace, @project.import_url) |
41 | + # We should create satellite for imported repo | ||
42 | + @project.satellite.create unless @project.satellite.exists? | ||
41 | true | 43 | true |
42 | else | 44 | else |
43 | @project.errors.add(:import_url, 'cannot clone repo') | 45 | @project.errors.add(:import_url, 'cannot clone repo') |
app/controllers/dashboard_controller.rb
@@ -5,7 +5,7 @@ class DashboardController < ApplicationController | @@ -5,7 +5,7 @@ class DashboardController < ApplicationController | ||
5 | before_filter :event_filter, only: :show | 5 | before_filter :event_filter, only: :show |
6 | 6 | ||
7 | def show | 7 | def show |
8 | - @groups = current_user.authorized_groups | 8 | + @groups = current_user.authorized_groups.sort_by(&:human_name) |
9 | @has_authorized_projects = @projects.count > 0 | 9 | @has_authorized_projects = @projects.count > 0 |
10 | @teams = current_user.authorized_teams | 10 | @teams = current_user.authorized_teams |
11 | @projects_count = @projects.count | 11 | @projects_count = @projects.count |
@@ -0,0 +1,13 @@ | @@ -0,0 +1,13 @@ | ||
1 | +class FilesController < ApplicationController | ||
2 | + def download | ||
3 | + note = Note.find(params[:id]) | ||
4 | + | ||
5 | + if can?(current_user, :read_project, note.project) | ||
6 | + uploader = note.attachment | ||
7 | + send_file uploader.file.path, disposition: 'attachment' | ||
8 | + else | ||
9 | + not_found! | ||
10 | + end | ||
11 | + end | ||
12 | +end | ||
13 | + |
app/controllers/merge_requests_controller.rb
@@ -73,14 +73,14 @@ class MergeRequestsController < ProjectResourceController | @@ -73,14 +73,14 @@ class MergeRequestsController < ProjectResourceController | ||
73 | if @merge_request.unchecked? | 73 | if @merge_request.unchecked? |
74 | @merge_request.check_if_can_be_merged | 74 | @merge_request.check_if_can_be_merged |
75 | end | 75 | end |
76 | - render json: {state: @merge_request.human_state} | 76 | + render json: {merge_status: @merge_request.human_merge_status} |
77 | rescue Gitlab::SatelliteNotExistError | 77 | rescue Gitlab::SatelliteNotExistError |
78 | - render json: {state: :no_satellite} | 78 | + render json: {merge_status: :no_satellite} |
79 | end | 79 | end |
80 | 80 | ||
81 | def automerge | 81 | def automerge |
82 | return access_denied! unless can?(current_user, :accept_mr, @project) | 82 | return access_denied! unless can?(current_user, :accept_mr, @project) |
83 | - if @merge_request.open? && @merge_request.can_be_merged? | 83 | + if @merge_request.opened? && @merge_request.can_be_merged? |
84 | @merge_request.should_remove_source_branch = params[:should_remove_source_branch] | 84 | @merge_request.should_remove_source_branch = params[:should_remove_source_branch] |
85 | @merge_request.automerge!(current_user) | 85 | @merge_request.automerge!(current_user) |
86 | @status = true | 86 | @status = true |
app/controllers/milestones_controller.rb
@@ -12,7 +12,7 @@ class MilestonesController < ProjectResourceController | @@ -12,7 +12,7 @@ class MilestonesController < ProjectResourceController | ||
12 | 12 | ||
13 | def index | 13 | def index |
14 | @milestones = case params[:f] | 14 | @milestones = case params[:f] |
15 | - when 'all'; @project.milestones.order("closed, due_date DESC") | 15 | + when 'all'; @project.milestones.order("state, due_date DESC") |
16 | when 'closed'; @project.milestones.closed.order("due_date DESC") | 16 | when 'closed'; @project.milestones.closed.order("due_date DESC") |
17 | else @project.milestones.active.order("due_date ASC") | 17 | else @project.milestones.active.order("due_date ASC") |
18 | end | 18 | end |
app/controllers/profiles_controller.rb
@@ -51,7 +51,9 @@ class ProfilesController < ApplicationController | @@ -51,7 +51,9 @@ class ProfilesController < ApplicationController | ||
51 | end | 51 | end |
52 | 52 | ||
53 | def update_username | 53 | def update_username |
54 | - @user.update_attributes(username: params[:user][:username]) | 54 | + if @user.can_change_username? |
55 | + @user.update_attributes(username: params[:user][:username]) | ||
56 | + end | ||
55 | 57 | ||
56 | respond_to do |format| | 58 | respond_to do |format| |
57 | format.js | 59 | format.js |
app/controllers/team_members_controller.rb
@@ -4,7 +4,11 @@ class TeamMembersController < ProjectResourceController | @@ -4,7 +4,11 @@ class TeamMembersController < ProjectResourceController | ||
4 | before_filter :authorize_admin_project!, except: [:index, :show] | 4 | before_filter :authorize_admin_project!, except: [:index, :show] |
5 | 5 | ||
6 | def index | 6 | def index |
7 | - @teams = UserTeam.scoped | 7 | + @team = @project.users_projects.scoped |
8 | + @team = @team.send(params[:type]) if %w(masters developers reporters guests).include?(params[:type]) | ||
9 | + @team = @team.sort_by(&:project_access).reverse.group_by(&:project_access) | ||
10 | + | ||
11 | + @assigned_teams = @project.user_team_project_relationships | ||
8 | end | 12 | end |
9 | 13 | ||
10 | def show | 14 | def show |
app/controllers/teams/members_controller.rb
@@ -27,7 +27,13 @@ class Teams::MembersController < Teams::ApplicationController | @@ -27,7 +27,13 @@ class Teams::MembersController < Teams::ApplicationController | ||
27 | end | 27 | end |
28 | 28 | ||
29 | def update | 29 | def update |
30 | - options = {default_projects_access: params[:default_project_access], group_admin: params[:group_admin]} | 30 | + member_params = params[:team_member] |
31 | + | ||
32 | + options = { | ||
33 | + default_projects_access: member_params[:permission], | ||
34 | + group_admin: member_params[:group_admin] | ||
35 | + } | ||
36 | + | ||
31 | if user_team.update_membership(team_member, options) | 37 | if user_team.update_membership(team_member, options) |
32 | redirect_to team_members_path(user_team), notice: "Membership for #{team_member.name} was successfully updated in Team of users." | 38 | redirect_to team_members_path(user_team), notice: "Membership for #{team_member.name} was successfully updated in Team of users." |
33 | else | 39 | else |
@@ -45,5 +51,4 @@ class Teams::MembersController < Teams::ApplicationController | @@ -45,5 +51,4 @@ class Teams::MembersController < Teams::ApplicationController | ||
45 | def team_member | 51 | def team_member |
46 | @member ||= user_team.members.find_by_username(params[:id]) | 52 | @member ||= user_team.members.find_by_username(params[:id]) |
47 | end | 53 | end |
48 | - | ||
49 | end | 54 | end |
app/controllers/teams_controller.rb
@@ -9,13 +9,11 @@ class TeamsController < ApplicationController | @@ -9,13 +9,11 @@ class TeamsController < ApplicationController | ||
9 | layout 'user_team', except: [:new, :create] | 9 | layout 'user_team', except: [:new, :create] |
10 | 10 | ||
11 | def show | 11 | def show |
12 | - user_team | ||
13 | projects | 12 | projects |
14 | @events = Event.in_projects(user_team.project_ids).limit(20).offset(params[:offset] || 0) | 13 | @events = Event.in_projects(user_team.project_ids).limit(20).offset(params[:offset] || 0) |
15 | end | 14 | end |
16 | 15 | ||
17 | def edit | 16 | def edit |
18 | - user_team | ||
19 | end | 17 | end |
20 | 18 | ||
21 | def update | 19 | def update |
@@ -41,6 +39,9 @@ class TeamsController < ApplicationController | @@ -41,6 +39,9 @@ class TeamsController < ApplicationController | ||
41 | @team.path = @team.name.dup.parameterize if @team.name | 39 | @team.path = @team.name.dup.parameterize if @team.name |
42 | 40 | ||
43 | if @team.save | 41 | if @team.save |
42 | + # Add current user as Master to the team | ||
43 | + @team.add_members([current_user.id], UsersProject::MASTER, true) | ||
44 | + | ||
44 | redirect_to team_path(@team) | 45 | redirect_to team_path(@team) |
45 | else | 46 | else |
46 | render action: :new | 47 | render action: :new |
app/helpers/application_helper.rb
@@ -73,8 +73,8 @@ module ApplicationHelper | @@ -73,8 +73,8 @@ module ApplicationHelper | ||
73 | 73 | ||
74 | def search_autocomplete_source | 74 | def search_autocomplete_source |
75 | projects = current_user.authorized_projects.map { |p| { label: "project: #{p.name_with_namespace}", url: project_path(p) } } | 75 | projects = current_user.authorized_projects.map { |p| { label: "project: #{p.name_with_namespace}", url: project_path(p) } } |
76 | - groups = current_user.authorized_groups.map { |group| { label: "group: #{group.name}", url: group_path(group) } } | ||
77 | - teams = current_user.authorized_teams.map { |team| { label: "team: #{team.name}", url: team_path(team) } } | 76 | + groups = current_user.authorized_groups.map { |group| { label: "group: #{simple_sanitize(group.name)}", url: group_path(group) } } |
77 | + teams = current_user.authorized_teams.map { |team| { label: "team: #{simple_sanitize(team.name)}", url: team_path(team) } } | ||
78 | 78 | ||
79 | default_nav = [ | 79 | default_nav = [ |
80 | { label: "My Profile", url: profile_path }, | 80 | { label: "My Profile", url: profile_path }, |
@@ -159,8 +159,13 @@ module ApplicationHelper | @@ -159,8 +159,13 @@ module ApplicationHelper | ||
159 | alt: "Sign in with #{provider.to_s.titleize}") | 159 | alt: "Sign in with #{provider.to_s.titleize}") |
160 | end | 160 | end |
161 | 161 | ||
162 | + def simple_sanitize str | ||
163 | + sanitize(str, tags: %w(a span)) | ||
164 | + end | ||
165 | + | ||
162 | def image_url(source) | 166 | def image_url(source) |
163 | root_url + path_to_image(source) | 167 | root_url + path_to_image(source) |
164 | end | 168 | end |
169 | + | ||
165 | alias_method :url_to_image, :image_url | 170 | alias_method :url_to_image, :image_url |
166 | end | 171 | end |
app/helpers/dashboard_helper.rb
app/helpers/issues_helper.rb
@@ -6,7 +6,7 @@ module IssuesHelper | @@ -6,7 +6,7 @@ module IssuesHelper | ||
6 | 6 | ||
7 | def issue_css_classes issue | 7 | def issue_css_classes issue |
8 | classes = "issue" | 8 | classes = "issue" |
9 | - classes << " closed" if issue.closed | 9 | + classes << " closed" if issue.closed? |
10 | classes << " today" if issue.today? | 10 | classes << " today" if issue.today? |
11 | classes | 11 | classes |
12 | end | 12 | end |
app/helpers/merge_requests_helper.rb
@@ -12,7 +12,7 @@ module MergeRequestsHelper | @@ -12,7 +12,7 @@ module MergeRequestsHelper | ||
12 | 12 | ||
13 | def mr_css_classes mr | 13 | def mr_css_classes mr |
14 | classes = "merge_request" | 14 | classes = "merge_request" |
15 | - classes << " closed" if mr.closed | 15 | + classes << " closed" if mr.closed? |
16 | classes << " merged" if mr.merged? | 16 | classes << " merged" if mr.merged? |
17 | classes | 17 | classes |
18 | end | 18 | end |
app/helpers/namespaces_helper.rb
@@ -10,8 +10,8 @@ module NamespacesHelper | @@ -10,8 +10,8 @@ module NamespacesHelper | ||
10 | 10 | ||
11 | 11 | ||
12 | global_opts = ["Global", [['/', Namespace.global_id]] ] | 12 | global_opts = ["Global", [['/', Namespace.global_id]] ] |
13 | - group_opts = ["Groups", groups.map {|g| [g.human_name, g.id]} ] | ||
14 | - users_opts = [ "Users", users.map {|u| [u.human_name, u.id]} ] | 13 | + group_opts = ["Groups", groups.sort_by(&:human_name).map {|g| [g.human_name, g.id]} ] |
14 | + users_opts = [ "Users", users.sort_by(&:human_name).map {|u| [u.human_name, u.id]} ] | ||
15 | 15 | ||
16 | options = [] | 16 | options = [] |
17 | options << global_opts if current_user.admin | 17 | options << global_opts if current_user.admin |
app/helpers/projects_helper.rb
1 | module ProjectsHelper | 1 | module ProjectsHelper |
2 | - def grouper_project_members(project) | ||
3 | - @project.users_projects.sort_by(&:project_access).reverse.group_by(&:project_access) | ||
4 | - end | ||
5 | - | ||
6 | - def grouper_project_teams(project) | ||
7 | - @project.user_team_project_relationships.sort_by(&:greatest_access).reverse.group_by(&:greatest_access) | ||
8 | - end | ||
9 | - | ||
10 | def remove_from_project_team_message(project, user) | 2 | def remove_from_project_team_message(project, user) |
11 | "You are going to remove #{user.name} from #{project.name} project team. Are you sure?" | 3 | "You are going to remove #{user.name} from #{project.name} project team. Are you sure?" |
12 | end | 4 | end |
@@ -56,7 +48,7 @@ module ProjectsHelper | @@ -56,7 +48,7 @@ module ProjectsHelper | ||
56 | def project_title project | 48 | def project_title project |
57 | if project.group | 49 | if project.group |
58 | content_tag :span do | 50 | content_tag :span do |
59 | - link_to(project.group.name, group_path(project.group)) + " / " + project.name | 51 | + link_to(simple_sanitize(project.group.name), group_path(project.group)) + " / " + project.name |
60 | end | 52 | end |
61 | else | 53 | else |
62 | project.name | 54 | project.name |
app/models/ability.rb
@@ -123,7 +123,7 @@ class Ability | @@ -123,7 +123,7 @@ class Ability | ||
123 | def user_team_abilities user, team | 123 | def user_team_abilities user, team |
124 | rules = [] | 124 | rules = [] |
125 | 125 | ||
126 | - # Only group owner and administrators can manage group | 126 | + # Only group owner and administrators can manage team |
127 | if team.owner == user || team.admin?(user) || user.admin? | 127 | if team.owner == user || team.admin?(user) || user.admin? |
128 | rules << [ :manage_user_team ] | 128 | rules << [ :manage_user_team ] |
129 | end | 129 | end |
app/models/concerns/issuable.rb
@@ -17,10 +17,9 @@ module Issuable | @@ -17,10 +17,9 @@ module Issuable | ||
17 | validates :project, presence: true | 17 | validates :project, presence: true |
18 | validates :author, presence: true | 18 | validates :author, presence: true |
19 | validates :title, presence: true, length: { within: 0..255 } | 19 | validates :title, presence: true, length: { within: 0..255 } |
20 | - validates :closed, inclusion: { in: [true, false] } | ||
21 | 20 | ||
22 | - scope :opened, -> { where(closed: false) } | ||
23 | - scope :closed, -> { where(closed: true) } | 21 | + scope :opened, -> { with_state(:opened) } |
22 | + scope :closed, -> { with_state(:closed) } | ||
24 | scope :of_group, ->(group) { where(project_id: group.project_ids) } | 23 | scope :of_group, ->(group) { where(project_id: group.project_ids) } |
25 | scope :of_user_team, ->(team) { where(project_id: team.project_ids, assignee_id: team.member_ids) } | 24 | scope :of_user_team, ->(team) { where(project_id: team.project_ids, assignee_id: team.member_ids) } |
26 | scope :assigned, ->(u) { where(assignee_id: u.id)} | 25 | scope :assigned, ->(u) { where(assignee_id: u.id)} |
@@ -62,14 +61,6 @@ module Issuable | @@ -62,14 +61,6 @@ module Issuable | ||
62 | assignee_id_changed? | 61 | assignee_id_changed? |
63 | end | 62 | end |
64 | 63 | ||
65 | - def is_being_closed? | ||
66 | - closed_changed? && closed | ||
67 | - end | ||
68 | - | ||
69 | - def is_being_reopened? | ||
70 | - closed_changed? && !closed | ||
71 | - end | ||
72 | - | ||
73 | # | 64 | # |
74 | # Votes | 65 | # Votes |
75 | # | 66 | # |
app/models/event.rb
@@ -130,10 +130,6 @@ class Event < ActiveRecord::Base | @@ -130,10 +130,6 @@ class Event < ActiveRecord::Base | ||
130 | target if target_type == "MergeRequest" | 130 | target if target_type == "MergeRequest" |
131 | end | 131 | end |
132 | 132 | ||
133 | - def author | ||
134 | - @author ||= User.find(author_id) | ||
135 | - end | ||
136 | - | ||
137 | def action_name | 133 | def action_name |
138 | if closed? | 134 | if closed? |
139 | "closed" | 135 | "closed" |
app/models/issue.rb
@@ -9,7 +9,7 @@ | @@ -9,7 +9,7 @@ | ||
9 | # project_id :integer | 9 | # project_id :integer |
10 | # created_at :datetime not null | 10 | # created_at :datetime not null |
11 | # updated_at :datetime not null | 11 | # updated_at :datetime not null |
12 | -# closed :boolean default(FALSE), not null | 12 | +# state :string default(FALSE), not null |
13 | # position :integer default(0) | 13 | # position :integer default(0) |
14 | # branch_name :string(255) | 14 | # branch_name :string(255) |
15 | # description :text | 15 | # description :text |
@@ -19,12 +19,35 @@ | @@ -19,12 +19,35 @@ | ||
19 | class Issue < ActiveRecord::Base | 19 | class Issue < ActiveRecord::Base |
20 | include Issuable | 20 | include Issuable |
21 | 21 | ||
22 | - attr_accessible :title, :assignee_id, :closed, :position, :description, | ||
23 | - :milestone_id, :label_list, :author_id_of_changes | 22 | + attr_accessible :title, :assignee_id, :position, :description, |
23 | + :milestone_id, :label_list, :author_id_of_changes, | ||
24 | + :state_event | ||
24 | 25 | ||
25 | acts_as_taggable_on :labels | 26 | acts_as_taggable_on :labels |
26 | 27 | ||
27 | - def self.open_for(user) | ||
28 | - opened.assigned(user) | 28 | + class << self |
29 | + def cared(user) | ||
30 | + where('assignee_id = :user', user: user.id) | ||
31 | + end | ||
32 | + | ||
33 | + def open_for(user) | ||
34 | + opened.assigned(user) | ||
35 | + end | ||
36 | + end | ||
37 | + | ||
38 | + state_machine :state, initial: :opened do | ||
39 | + event :close do | ||
40 | + transition [:reopened, :opened] => :closed | ||
41 | + end | ||
42 | + | ||
43 | + event :reopen do | ||
44 | + transition closed: :reopened | ||
45 | + end | ||
46 | + | ||
47 | + state :opened | ||
48 | + | ||
49 | + state :reopened | ||
50 | + | ||
51 | + state :closed | ||
29 | end | 52 | end |
30 | end | 53 | end |
app/models/key.rb
@@ -35,7 +35,7 @@ class Key < ActiveRecord::Base | @@ -35,7 +35,7 @@ class Key < ActiveRecord::Base | ||
35 | 35 | ||
36 | def fingerprintable_key | 36 | def fingerprintable_key |
37 | return true unless key # Don't test if there is no key. | 37 | return true unless key # Don't test if there is no key. |
38 | - # `ssh-keygen -lf /dev/stdin <<< "#{key}"` errors with: redirection unexpected | 38 | + |
39 | file = Tempfile.new('key_file') | 39 | file = Tempfile.new('key_file') |
40 | begin | 40 | begin |
41 | file.puts key | 41 | file.puts key |
@@ -45,7 +45,7 @@ class Key < ActiveRecord::Base | @@ -45,7 +45,7 @@ class Key < ActiveRecord::Base | ||
45 | file.close | 45 | file.close |
46 | file.unlink # deletes the temp file | 46 | file.unlink # deletes the temp file |
47 | end | 47 | end |
48 | - errors.add(:key, "can't be fingerprinted") if fingerprint_output.match("failed") | 48 | + errors.add(:key, "can't be fingerprinted") if $?.exitstatus != 0 |
49 | end | 49 | end |
50 | 50 | ||
51 | def set_identifier | 51 | def set_identifier |
app/models/merge_request.rb
@@ -9,15 +9,14 @@ | @@ -9,15 +9,14 @@ | ||
9 | # author_id :integer | 9 | # author_id :integer |
10 | # assignee_id :integer | 10 | # assignee_id :integer |
11 | # title :string(255) | 11 | # title :string(255) |
12 | -# closed :boolean default(FALSE), not null | 12 | +# state :string(255) not null |
13 | # created_at :datetime not null | 13 | # created_at :datetime not null |
14 | # updated_at :datetime not null | 14 | # updated_at :datetime not null |
15 | # st_commits :text(2147483647) | 15 | # st_commits :text(2147483647) |
16 | # st_diffs :text(2147483647) | 16 | # st_diffs :text(2147483647) |
17 | -# merged :boolean default(FALSE), not null | ||
18 | -# state :integer default(1), not null | ||
19 | -# milestone_id :integer | 17 | +# merge_status :integer default(1), not null |
20 | # | 18 | # |
19 | +# milestone_id :integer | ||
21 | 20 | ||
22 | require Rails.root.join("app/models/commit") | 21 | require Rails.root.join("app/models/commit") |
23 | require Rails.root.join("lib/static_model") | 22 | require Rails.root.join("lib/static_model") |
@@ -25,11 +24,33 @@ require Rails.root.join("lib/static_model") | @@ -25,11 +24,33 @@ require Rails.root.join("lib/static_model") | ||
25 | class MergeRequest < ActiveRecord::Base | 24 | class MergeRequest < ActiveRecord::Base |
26 | include Issuable | 25 | include Issuable |
27 | 26 | ||
28 | - attr_accessible :title, :assignee_id, :closed, :target_branch, :source_branch, :milestone_id, | ||
29 | - :author_id_of_changes | 27 | + attr_accessible :title, :assignee_id, :target_branch, :source_branch, :milestone_id, |
28 | + :author_id_of_changes, :state_event | ||
30 | 29 | ||
31 | attr_accessor :should_remove_source_branch | 30 | attr_accessor :should_remove_source_branch |
32 | 31 | ||
32 | + state_machine :state, initial: :opened do | ||
33 | + event :close do | ||
34 | + transition [:reopened, :opened] => :closed | ||
35 | + end | ||
36 | + | ||
37 | + event :merge do | ||
38 | + transition [:reopened, :opened] => :merged | ||
39 | + end | ||
40 | + | ||
41 | + event :reopen do | ||
42 | + transition closed: :reopened | ||
43 | + end | ||
44 | + | ||
45 | + state :opened | ||
46 | + | ||
47 | + state :reopened | ||
48 | + | ||
49 | + state :closed | ||
50 | + | ||
51 | + state :merged | ||
52 | + end | ||
53 | + | ||
33 | BROKEN_DIFF = "--broken-diff" | 54 | BROKEN_DIFF = "--broken-diff" |
34 | 55 | ||
35 | UNCHECKED = 1 | 56 | UNCHECKED = 1 |
@@ -43,21 +64,33 @@ class MergeRequest < ActiveRecord::Base | @@ -43,21 +64,33 @@ class MergeRequest < ActiveRecord::Base | ||
43 | validates :target_branch, presence: true | 64 | validates :target_branch, presence: true |
44 | validate :validate_branches | 65 | validate :validate_branches |
45 | 66 | ||
46 | - def self.find_all_by_branch(branch_name) | ||
47 | - where("source_branch LIKE :branch OR target_branch LIKE :branch", branch: branch_name) | ||
48 | - end | 67 | + scope :merged, -> { with_state(:merged) } |
49 | 68 | ||
50 | - def self.find_all_by_milestone(milestone) | ||
51 | - where("milestone_id = :milestone_id", milestone_id: milestone) | 69 | + class << self |
70 | + def find_all_by_branch(branch_name) | ||
71 | + where("source_branch LIKE :branch OR target_branch LIKE :branch", branch: branch_name) | ||
72 | + end | ||
73 | + | ||
74 | + def cared(user) | ||
75 | + where('assignee_id = :user OR author_id = :user', user: user.id) | ||
76 | + end | ||
77 | + | ||
78 | + def find_all_by_branch(branch_name) | ||
79 | + where("source_branch LIKE :branch OR target_branch LIKE :branch", branch: branch_name) | ||
80 | + end | ||
81 | + | ||
82 | + def find_all_by_milestone(milestone) | ||
83 | + where("milestone_id = :milestone_id", milestone_id: milestone) | ||
84 | + end | ||
52 | end | 85 | end |
53 | 86 | ||
54 | - def human_state | ||
55 | - states = { | 87 | + def human_merge_status |
88 | + merge_statuses = { | ||
56 | CAN_BE_MERGED => "can_be_merged", | 89 | CAN_BE_MERGED => "can_be_merged", |
57 | CANNOT_BE_MERGED => "cannot_be_merged", | 90 | CANNOT_BE_MERGED => "cannot_be_merged", |
58 | UNCHECKED => "unchecked" | 91 | UNCHECKED => "unchecked" |
59 | } | 92 | } |
60 | - states[self.state] | 93 | + merge_statuses[self.merge_status] |
61 | end | 94 | end |
62 | 95 | ||
63 | def validate_branches | 96 | def validate_branches |
@@ -72,20 +105,20 @@ class MergeRequest < ActiveRecord::Base | @@ -72,20 +105,20 @@ class MergeRequest < ActiveRecord::Base | ||
72 | end | 105 | end |
73 | 106 | ||
74 | def unchecked? | 107 | def unchecked? |
75 | - state == UNCHECKED | 108 | + merge_status == UNCHECKED |
76 | end | 109 | end |
77 | 110 | ||
78 | def mark_as_unchecked | 111 | def mark_as_unchecked |
79 | - self.state = UNCHECKED | 112 | + self.merge_status = UNCHECKED |
80 | self.save | 113 | self.save |
81 | end | 114 | end |
82 | 115 | ||
83 | def can_be_merged? | 116 | def can_be_merged? |
84 | - state == CAN_BE_MERGED | 117 | + merge_status == CAN_BE_MERGED |
85 | end | 118 | end |
86 | 119 | ||
87 | def check_if_can_be_merged | 120 | def check_if_can_be_merged |
88 | - self.state = if Gitlab::Satellite::MergeAction.new(self.author, self).can_be_merged? | 121 | + self.merge_status = if Gitlab::Satellite::MergeAction.new(self.author, self).can_be_merged? |
89 | CAN_BE_MERGED | 122 | CAN_BE_MERGED |
90 | else | 123 | else |
91 | CANNOT_BE_MERGED | 124 | CANNOT_BE_MERGED |
@@ -98,7 +131,7 @@ class MergeRequest < ActiveRecord::Base | @@ -98,7 +131,7 @@ class MergeRequest < ActiveRecord::Base | ||
98 | end | 131 | end |
99 | 132 | ||
100 | def reloaded_diffs | 133 | def reloaded_diffs |
101 | - if open? && unmerged_diffs.any? | 134 | + if opened? && unmerged_diffs.any? |
102 | self.st_diffs = unmerged_diffs | 135 | self.st_diffs = unmerged_diffs |
103 | self.save | 136 | self.save |
104 | end | 137 | end |
@@ -128,10 +161,6 @@ class MergeRequest < ActiveRecord::Base | @@ -128,10 +161,6 @@ class MergeRequest < ActiveRecord::Base | ||
128 | commits.first | 161 | commits.first |
129 | end | 162 | end |
130 | 163 | ||
131 | - def merged? | ||
132 | - merged && merge_event | ||
133 | - end | ||
134 | - | ||
135 | def merge_event | 164 | def merge_event |
136 | self.project.events.where(target_id: self.id, target_type: "MergeRequest", action: Event::MERGED).last | 165 | self.project.events.where(target_id: self.id, target_type: "MergeRequest", action: Event::MERGED).last |
137 | end | 166 | end |
@@ -146,26 +175,16 @@ class MergeRequest < ActiveRecord::Base | @@ -146,26 +175,16 @@ class MergeRequest < ActiveRecord::Base | ||
146 | 175 | ||
147 | def probably_merged? | 176 | def probably_merged? |
148 | unmerged_commits.empty? && | 177 | unmerged_commits.empty? && |
149 | - commits.any? && open? | ||
150 | - end | ||
151 | - | ||
152 | - def open? | ||
153 | - !closed | ||
154 | - end | ||
155 | - | ||
156 | - def mark_as_merged! | ||
157 | - self.merged = true | ||
158 | - self.closed = true | ||
159 | - save | 178 | + commits.any? && opened? |
160 | end | 179 | end |
161 | 180 | ||
162 | def mark_as_unmergable | 181 | def mark_as_unmergable |
163 | - self.state = CANNOT_BE_MERGED | 182 | + self.merge_status = CANNOT_BE_MERGED |
164 | self.save | 183 | self.save |
165 | end | 184 | end |
166 | 185 | ||
167 | def reloaded_commits | 186 | def reloaded_commits |
168 | - if open? && unmerged_commits.any? | 187 | + if opened? && unmerged_commits.any? |
169 | self.st_commits = unmerged_commits | 188 | self.st_commits = unmerged_commits |
170 | save | 189 | save |
171 | end | 190 | end |
@@ -181,7 +200,8 @@ class MergeRequest < ActiveRecord::Base | @@ -181,7 +200,8 @@ class MergeRequest < ActiveRecord::Base | ||
181 | end | 200 | end |
182 | 201 | ||
183 | def merge!(user_id) | 202 | def merge!(user_id) |
184 | - self.mark_as_merged! | 203 | + self.merge |
204 | + | ||
185 | Event.create( | 205 | Event.create( |
186 | project: self.project, | 206 | project: self.project, |
187 | action: Event::MERGED, | 207 | action: Event::MERGED, |
app/models/milestone.rb
@@ -13,19 +13,32 @@ | @@ -13,19 +13,32 @@ | ||
13 | # | 13 | # |
14 | 14 | ||
15 | class Milestone < ActiveRecord::Base | 15 | class Milestone < ActiveRecord::Base |
16 | - attr_accessible :title, :description, :due_date, :closed, :author_id_of_changes | 16 | + attr_accessible :title, :description, :due_date, :state_event, :author_id_of_changes |
17 | attr_accessor :author_id_of_changes | 17 | attr_accessor :author_id_of_changes |
18 | 18 | ||
19 | belongs_to :project | 19 | belongs_to :project |
20 | has_many :issues | 20 | has_many :issues |
21 | has_many :merge_requests | 21 | has_many :merge_requests |
22 | 22 | ||
23 | - scope :active, -> { where(closed: false) } | ||
24 | - scope :closed, -> { where(closed: true) } | 23 | + scope :active, -> { with_state(:active) } |
24 | + scope :closed, -> { with_state(:closed) } | ||
25 | 25 | ||
26 | validates :title, presence: true | 26 | validates :title, presence: true |
27 | validates :project, presence: true | 27 | validates :project, presence: true |
28 | - validates :closed, inclusion: { in: [true, false] } | 28 | + |
29 | + state_machine :state, initial: :active do | ||
30 | + event :close do | ||
31 | + transition active: :closed | ||
32 | + end | ||
33 | + | ||
34 | + event :activate do | ||
35 | + transition closed: :active | ||
36 | + end | ||
37 | + | ||
38 | + state :closed | ||
39 | + | ||
40 | + state :active | ||
41 | + end | ||
29 | 42 | ||
30 | def expired? | 43 | def expired? |
31 | if due_date | 44 | if due_date |
@@ -68,17 +81,13 @@ class Milestone < ActiveRecord::Base | @@ -68,17 +81,13 @@ class Milestone < ActiveRecord::Base | ||
68 | end | 81 | end |
69 | 82 | ||
70 | def can_be_closed? | 83 | def can_be_closed? |
71 | - open? && issues.opened.count.zero? | 84 | + active? && issues.opened.count.zero? |
72 | end | 85 | end |
73 | 86 | ||
74 | def is_empty? | 87 | def is_empty? |
75 | total_items_count.zero? | 88 | total_items_count.zero? |
76 | end | 89 | end |
77 | 90 | ||
78 | - def open? | ||
79 | - !closed | ||
80 | - end | ||
81 | - | ||
82 | def author_id | 91 | def author_id |
83 | author_id_of_changes | 92 | author_id_of_changes |
84 | end | 93 | end |
app/models/namespace.rb
@@ -17,11 +17,15 @@ class Namespace < ActiveRecord::Base | @@ -17,11 +17,15 @@ class Namespace < ActiveRecord::Base | ||
17 | has_many :projects, dependent: :destroy | 17 | has_many :projects, dependent: :destroy |
18 | belongs_to :owner, class_name: "User" | 18 | belongs_to :owner, class_name: "User" |
19 | 19 | ||
20 | - validates :name, presence: true, uniqueness: true | 20 | + validates :owner, presence: true |
21 | + validates :name, presence: true, uniqueness: true, | ||
22 | + length: { within: 0..255 }, | ||
23 | + format: { with: Gitlab::Regex.name_regex, | ||
24 | + message: "only letters, digits, spaces & '_' '-' '.' allowed." } | ||
25 | + | ||
21 | validates :path, uniqueness: true, presence: true, length: { within: 1..255 }, | 26 | validates :path, uniqueness: true, presence: true, length: { within: 1..255 }, |
22 | format: { with: Gitlab::Regex.path_regex, | 27 | format: { with: Gitlab::Regex.path_regex, |
23 | message: "only letters, digits & '_' '-' '.' allowed. Letter should be first" } | 28 | message: "only letters, digits & '_' '-' '.' allowed. Letter should be first" } |
24 | - validates :owner, presence: true | ||
25 | 29 | ||
26 | delegate :name, to: :owner, allow_nil: true, prefix: true | 30 | delegate :name, to: :owner, allow_nil: true, prefix: true |
27 | 31 |
app/models/project.rb
@@ -43,7 +43,7 @@ class Project < ActiveRecord::Base | @@ -43,7 +43,7 @@ class Project < ActiveRecord::Base | ||
43 | 43 | ||
44 | has_many :events, dependent: :destroy | 44 | has_many :events, dependent: :destroy |
45 | has_many :merge_requests, dependent: :destroy | 45 | has_many :merge_requests, dependent: :destroy |
46 | - has_many :issues, dependent: :destroy, order: "closed, created_at DESC" | 46 | + has_many :issues, dependent: :destroy, order: "state, created_at DESC" |
47 | has_many :milestones, dependent: :destroy | 47 | has_many :milestones, dependent: :destroy |
48 | has_many :users_projects, dependent: :destroy | 48 | has_many :users_projects, dependent: :destroy |
49 | has_many :notes, dependent: :destroy | 49 | has_many :notes, dependent: :destroy |
@@ -146,7 +146,7 @@ class Project < ActiveRecord::Base | @@ -146,7 +146,7 @@ class Project < ActiveRecord::Base | ||
146 | end | 146 | end |
147 | 147 | ||
148 | def saved? | 148 | def saved? |
149 | - id && valid? | 149 | + id && persisted? |
150 | end | 150 | end |
151 | 151 | ||
152 | def import? | 152 | def import? |
app/models/repository.rb
@@ -132,16 +132,16 @@ class Repository | @@ -132,16 +132,16 @@ class Repository | ||
132 | return nil unless commit | 132 | return nil unless commit |
133 | 133 | ||
134 | # Build file path | 134 | # Build file path |
135 | - file_name = self.path_with_namespace + "-" + commit.id.to_s + ".tar.gz" | 135 | + file_name = self.path_with_namespace.gsub("/","_") + "-" + commit.id.to_s + ".tar.gz" |
136 | storage_path = Rails.root.join("tmp", "repositories") | 136 | storage_path = Rails.root.join("tmp", "repositories") |
137 | - file_path = File.join(storage_path, file_name) | 137 | + file_path = File.join(storage_path, self.path_with_namespace, file_name) |
138 | 138 | ||
139 | # Put files into a directory before archiving | 139 | # Put files into a directory before archiving |
140 | prefix = self.path_with_namespace + "/" | 140 | prefix = self.path_with_namespace + "/" |
141 | 141 | ||
142 | # Create file if not exists | 142 | # Create file if not exists |
143 | unless File.exists?(file_path) | 143 | unless File.exists?(file_path) |
144 | - FileUtils.mkdir_p storage_path | 144 | + FileUtils.mkdir_p File.dirname(file_path) |
145 | file = self.repo.archive_to_file(ref, prefix, file_path) | 145 | file = self.repo.archive_to_file(ref, prefix, file_path) |
146 | end | 146 | end |
147 | 147 |
app/models/user.rb
@@ -234,8 +234,12 @@ class User < ActiveRecord::Base | @@ -234,8 +234,12 @@ class User < ActiveRecord::Base | ||
234 | keys.count == 0 | 234 | keys.count == 0 |
235 | end | 235 | end |
236 | 236 | ||
237 | + def can_change_username? | ||
238 | + Gitlab.config.gitlab.username_changing_enabled | ||
239 | + end | ||
240 | + | ||
237 | def can_create_project? | 241 | def can_create_project? |
238 | - projects_limit > personal_projects.count | 242 | + projects_limit > owned_projects.count |
239 | end | 243 | end |
240 | 244 | ||
241 | def can_create_group? | 245 | def can_create_group? |
@@ -263,7 +267,7 @@ class User < ActiveRecord::Base | @@ -263,7 +267,7 @@ class User < ActiveRecord::Base | ||
263 | end | 267 | end |
264 | 268 | ||
265 | def cared_merge_requests | 269 | def cared_merge_requests |
266 | - MergeRequest.where("author_id = :id or assignee_id = :id", id: self.id) | 270 | + MergeRequest.cared(self) |
267 | end | 271 | end |
268 | 272 | ||
269 | # Remove user from all projects and | 273 | # Remove user from all projects and |
app/models/user_team.rb
@@ -21,8 +21,11 @@ class UserTeam < ActiveRecord::Base | @@ -21,8 +21,11 @@ class UserTeam < ActiveRecord::Base | ||
21 | has_many :projects, through: :user_team_project_relationships | 21 | has_many :projects, through: :user_team_project_relationships |
22 | has_many :members, through: :user_team_user_relationships, source: :user | 22 | has_many :members, through: :user_team_user_relationships, source: :user |
23 | 23 | ||
24 | - validates :name, presence: true, uniqueness: true | ||
25 | validates :owner, presence: true | 24 | validates :owner, presence: true |
25 | + validates :name, presence: true, uniqueness: true, | ||
26 | + length: { within: 0..255 }, | ||
27 | + format: { with: Gitlab::Regex.name_regex, | ||
28 | + message: "only letters, digits, spaces & '_' '-' '.' allowed." } | ||
26 | validates :path, uniqueness: true, presence: true, length: { within: 1..255 }, | 29 | validates :path, uniqueness: true, presence: true, length: { within: 1..255 }, |
27 | format: { with: Gitlab::Regex.path_regex, | 30 | format: { with: Gitlab::Regex.path_regex, |
28 | message: "only letters, digits & '_' '-' '.' allowed. Letter should be first" } | 31 | message: "only letters, digits & '_' '-' '.' allowed. Letter should be first" } |
app/models/user_team_project_relationship.rb
@@ -26,6 +26,10 @@ class UserTeamProjectRelationship < ActiveRecord::Base | @@ -26,6 +26,10 @@ class UserTeamProjectRelationship < ActiveRecord::Base | ||
26 | user_team.name | 26 | user_team.name |
27 | end | 27 | end |
28 | 28 | ||
29 | + def human_max_access | ||
30 | + UserTeam.access_roles.key(greatest_access) | ||
31 | + end | ||
32 | + | ||
29 | private | 33 | private |
30 | 34 | ||
31 | def check_greatest_access | 35 | def check_greatest_access |
app/observers/activity_observer.rb
@@ -20,15 +20,23 @@ class ActivityObserver < ActiveRecord::Observer | @@ -20,15 +20,23 @@ class ActivityObserver < ActiveRecord::Observer | ||
20 | end | 20 | end |
21 | end | 21 | end |
22 | 22 | ||
23 | - def after_save(record) | ||
24 | - if record.changed.include?("closed") && record.author_id_of_changes | 23 | + def after_close(record, transition) |
25 | Event.create( | 24 | Event.create( |
26 | project: record.project, | 25 | project: record.project, |
27 | target_id: record.id, | 26 | target_id: record.id, |
28 | target_type: record.class.name, | 27 | target_type: record.class.name, |
29 | - action: (record.closed ? Event::CLOSED : Event::REOPENED), | 28 | + action: Event::CLOSED, |
29 | + author_id: record.author_id_of_changes | ||
30 | + ) | ||
31 | + end | ||
32 | + | ||
33 | + def after_reopen(record, transition) | ||
34 | + Event.create( | ||
35 | + project: record.project, | ||
36 | + target_id: record.id, | ||
37 | + target_type: record.class.name, | ||
38 | + action: Event::REOPENED, | ||
30 | author_id: record.author_id_of_changes | 39 | author_id: record.author_id_of_changes |
31 | ) | 40 | ) |
32 | - end | ||
33 | end | 41 | end |
34 | end | 42 | end |
app/observers/issue_observer.rb
@@ -7,22 +7,31 @@ class IssueObserver < ActiveRecord::Observer | @@ -7,22 +7,31 @@ class IssueObserver < ActiveRecord::Observer | ||
7 | end | 7 | end |
8 | end | 8 | end |
9 | 9 | ||
10 | - def after_update(issue) | 10 | + def after_close(issue, transition) |
11 | send_reassigned_email(issue) if issue.is_being_reassigned? | 11 | send_reassigned_email(issue) if issue.is_being_reassigned? |
12 | 12 | ||
13 | - status = nil | ||
14 | - status = 'closed' if issue.is_being_closed? | ||
15 | - status = 'reopened' if issue.is_being_reopened? | ||
16 | - if status | ||
17 | - Note.create_status_change_note(issue, current_user, status) | ||
18 | - [issue.author, issue.assignee].compact.each do |recipient| | ||
19 | - Notify.delay.issue_status_changed_email(recipient.id, issue.id, status, current_user.id) | ||
20 | - end | ||
21 | - end | 13 | + create_note(issue) |
14 | + end | ||
15 | + | ||
16 | + def after_reopen(issue, transition) | ||
17 | + send_reassigned_email(issue) if issue.is_being_reassigned? | ||
18 | + | ||
19 | + create_note(issue) | ||
20 | + end | ||
21 | + | ||
22 | + def after_update(issue) | ||
23 | + send_reassigned_email(issue) if issue.is_being_reassigned? | ||
22 | end | 24 | end |
23 | 25 | ||
24 | protected | 26 | protected |
25 | 27 | ||
28 | + def create_note(issue) | ||
29 | + Note.create_status_change_note(issue, current_user, issue.state) | ||
30 | + [issue.author, issue.assignee].compact.each do |recipient| | ||
31 | + Notify.delay.issue_status_changed_email(recipient.id, issue.id, issue.state, current_user.id) | ||
32 | + end | ||
33 | + end | ||
34 | + | ||
26 | def send_reassigned_email(issue) | 35 | def send_reassigned_email(issue) |
27 | recipient_ids = [issue.assignee_id, issue.assignee_id_was].keep_if {|id| id && id != current_user.id } | 36 | recipient_ids = [issue.assignee_id, issue.assignee_id_was].keep_if {|id| id && id != current_user.id } |
28 | 37 |
app/observers/merge_request_observer.rb
@@ -7,15 +7,20 @@ class MergeRequestObserver < ActiveRecord::Observer | @@ -7,15 +7,20 @@ class MergeRequestObserver < ActiveRecord::Observer | ||
7 | end | 7 | end |
8 | end | 8 | end |
9 | 9 | ||
10 | - def after_update(merge_request) | 10 | + def after_close(merge_request, transition) |
11 | send_reassigned_email(merge_request) if merge_request.is_being_reassigned? | 11 | send_reassigned_email(merge_request) if merge_request.is_being_reassigned? |
12 | 12 | ||
13 | - status = nil | ||
14 | - status = 'closed' if merge_request.is_being_closed? | ||
15 | - status = 'reopened' if merge_request.is_being_reopened? | ||
16 | - if status | ||
17 | - Note.create_status_change_note(merge_request, current_user, status) | ||
18 | - end | 13 | + Note.create_status_change_note(merge_request, current_user, merge_request.state) |
14 | + end | ||
15 | + | ||
16 | + def after_reopen(merge_request, transition) | ||
17 | + send_reassigned_email(merge_request) if merge_request.is_being_reassigned? | ||
18 | + | ||
19 | + Note.create_status_change_note(merge_request, current_user, merge_request.state) | ||
20 | + end | ||
21 | + | ||
22 | + def after_update(merge_request) | ||
23 | + send_reassigned_email(merge_request) if merge_request.is_being_reassigned? | ||
19 | end | 24 | end |
20 | 25 | ||
21 | protected | 26 | protected |
app/uploaders/attachment_uploader.rb
@@ -19,4 +19,12 @@ class AttachmentUploader < CarrierWave::Uploader::Base | @@ -19,4 +19,12 @@ class AttachmentUploader < CarrierWave::Uploader::Base | ||
19 | rescue | 19 | rescue |
20 | false | 20 | false |
21 | end | 21 | end |
22 | + | ||
23 | + def secure_url | ||
24 | + if self.class.storage == CarrierWave::Storage::File | ||
25 | + "/files/#{model.class.to_s.underscore}/#{model.id}/#{file.filename}" | ||
26 | + else | ||
27 | + url | ||
28 | + end | ||
29 | + end | ||
22 | end | 30 | end |
app/views/admin/groups/index.html.haml
@@ -28,7 +28,7 @@ | @@ -28,7 +28,7 @@ | ||
28 | %td= group.path | 28 | %td= group.path |
29 | %td= group.projects.count | 29 | %td= group.projects.count |
30 | %td | 30 | %td |
31 | - = link_to group.owner_name, admin_user_path(group.owner_id) | 31 | + = link_to group.owner_name, admin_user_path(group.owner) |
32 | %td.bgred | 32 | %td.bgred |
33 | = link_to 'Rename', edit_admin_group_path(group), id: "edit_#{dom_id(group)}", class: "btn btn-small" | 33 | = link_to 'Rename', edit_admin_group_path(group), id: "edit_#{dom_id(group)}", class: "btn btn-small" |
34 | = link_to 'Destroy', [:admin, group], confirm: "REMOVE #{group.name}? Are you sure?", method: :delete, class: "btn btn-small btn-remove" | 34 | = link_to 'Destroy', [:admin, group], confirm: "REMOVE #{group.name}? Are you sure?", method: :delete, class: "btn btn-small btn-remove" |
app/views/admin/teams/index.html.haml
@@ -30,7 +30,7 @@ | @@ -30,7 +30,7 @@ | ||
30 | %td= team.projects.count | 30 | %td= team.projects.count |
31 | %td= team.members.count | 31 | %td= team.members.count |
32 | %td | 32 | %td |
33 | - = link_to team.owner.name, admin_user_path(team.owner_id) | 33 | + = link_to team.owner.name, admin_user_path(team.owner) |
34 | %td.bgred | 34 | %td.bgred |
35 | = link_to 'Rename', edit_admin_team_path(team), id: "edit_#{dom_id(team)}", class: "btn btn-small" | 35 | = link_to 'Rename', edit_admin_team_path(team), id: "edit_#{dom_id(team)}", class: "btn btn-small" |
36 | = link_to 'Destroy', admin_team_path(team), confirm: "REMOVE #{team.name}? Are you sure?", method: :delete, class: "btn btn-small btn-remove" | 36 | = link_to 'Destroy', admin_team_path(team), confirm: "REMOVE #{team.name}? Are you sure?", method: :delete, class: "btn btn-small btn-remove" |
app/views/commits/_commit.html.haml
@@ -6,9 +6,9 @@ | @@ -6,9 +6,9 @@ | ||
6 | = link_to commit.short_id(8), project_commit_path(@project, commit), class: "commit_short_id" | 6 | = link_to commit.short_id(8), project_commit_path(@project, commit), class: "commit_short_id" |
7 | = commit.author_link avatar: true, size: 24 | 7 | = commit.author_link avatar: true, size: 24 |
8 | | 8 | |
9 | - = link_to_gfm truncate(commit.title, length: 50), project_commit_path(@project, commit.id), class: "row_title" | 9 | + = link_to_gfm truncate(commit.title, length: 70), project_commit_path(@project, commit.id), class: "row_title" |
10 | 10 | ||
11 | - %span.committed_ago | 11 | + %time.committed_ago{ datetime: commit.committed_date, title: commit.committed_date.stamp("Aug 21, 2011 9:23pm") } |
12 | = time_ago_in_words(commit.committed_date) | 12 | = time_ago_in_words(commit.committed_date) |
13 | ago | 13 | ago |
14 | | 14 | |
app/views/events/event/_note.html.haml
@@ -26,7 +26,7 @@ | @@ -26,7 +26,7 @@ | ||
26 | = markdown truncate(event.target.note, length: 70) | 26 | = markdown truncate(event.target.note, length: 70) |
27 | - note = event.target | 27 | - note = event.target |
28 | - if note.attachment.url | 28 | - if note.attachment.url |
29 | - = link_to note.attachment.url, target: "_blank", class: 'note-file-attach' do | 29 | + = link_to note.attachment.secure_url, target: "_blank", class: 'note-file-attach' do |
30 | - if note.attachment.image? | 30 | - if note.attachment.image? |
31 | = image_tag note.attachment.url, class: 'note-image-attach' | 31 | = image_tag note.attachment.url, class: 'note-image-attach' |
32 | - else | 32 | - else |
app/views/groups/_filter.html.haml
@@ -26,6 +26,8 @@ | @@ -26,6 +26,8 @@ | ||
26 | = link_to group_filter_path(entity, project_id: project.id) do | 26 | = link_to group_filter_path(entity, project_id: project.id) do |
27 | = project.name_with_namespace | 27 | = project.name_with_namespace |
28 | %small.pull-right= entities_per_project(project, entity) | 28 | %small.pull-right= entities_per_project(project, entity) |
29 | + - if @projects.blank? | ||
30 | + %p.nothing_here_message This group has no projects yet | ||
29 | 31 | ||
30 | %fieldset | 32 | %fieldset |
31 | %hr | 33 | %hr |
app/views/groups/_people_filter.html.haml
@@ -7,6 +7,8 @@ | @@ -7,6 +7,8 @@ | ||
7 | = link_to people_group_path(@group, project_id: project.id) do | 7 | = link_to people_group_path(@group, project_id: project.id) do |
8 | = project.name_with_namespace | 8 | = project.name_with_namespace |
9 | %small.pull-right= project.users.count | 9 | %small.pull-right= project.users.count |
10 | + - if @projects.blank? | ||
11 | + %p.nothing_here_message This group has no projects yet | ||
10 | 12 | ||
11 | %fieldset | 13 | %fieldset |
12 | %hr | 14 | %hr |
app/views/groups/edit.html.haml
@@ -30,6 +30,8 @@ | @@ -30,6 +30,8 @@ | ||
30 | = link_to 'Team', project_team_index_path(project), id: "edit_#{dom_id(project)}", class: "btn btn-small" | 30 | = link_to 'Team', project_team_index_path(project), id: "edit_#{dom_id(project)}", class: "btn btn-small" |
31 | = link_to 'Edit', edit_project_path(project), id: "edit_#{dom_id(project)}", class: "btn btn-small" | 31 | = link_to 'Edit', edit_project_path(project), id: "edit_#{dom_id(project)}", class: "btn btn-small" |
32 | = link_to 'Remove', project, confirm: "REMOVE #{project.name}? Are you sure?", method: :delete, class: "btn btn-small btn-remove" | 32 | = link_to 'Remove', project, confirm: "REMOVE #{project.name}? Are you sure?", method: :delete, class: "btn btn-small btn-remove" |
33 | + - if @group.projects.blank? | ||
34 | + %p.nothing_here_message This group has no projects yet | ||
33 | 35 | ||
34 | .span5 | 36 | .span5 |
35 | .ui-box | 37 | .ui-box |
app/views/help/index.html.haml
app/views/issues/_show.html.haml
@@ -8,10 +8,10 @@ | @@ -8,10 +8,10 @@ | ||
8 | %i.icon-comment | 8 | %i.icon-comment |
9 | = issue.notes.count | 9 | = issue.notes.count |
10 | - if can? current_user, :modify_issue, issue | 10 | - if can? current_user, :modify_issue, issue |
11 | - - if issue.closed | ||
12 | - = link_to 'Reopen', project_issue_path(issue.project, issue, issue: {closed: false }, status_only: true), method: :put, class: "btn btn-small grouped reopen_issue", remote: true | 11 | + - if issue.closed? |
12 | + = link_to 'Reopen', project_issue_path(issue.project, issue, issue: {state_event: :reopen }, status_only: true), method: :put, class: "btn btn-small grouped reopen_issue", remote: true | ||
13 | - else | 13 | - else |
14 | - = link_to 'Close', project_issue_path(issue.project, issue, issue: {closed: true }, status_only: true), method: :put, class: "btn btn-small grouped close_issue", remote: true | 14 | + = link_to 'Close', project_issue_path(issue.project, issue, issue: {state_event: :close }, status_only: true), method: :put, class: "btn btn-small grouped close_issue", remote: true |
15 | = link_to edit_project_issue_path(issue.project, issue), class: "btn btn-small edit-issue-link grouped" do | 15 | = link_to edit_project_issue_path(issue.project, issue), class: "btn btn-small edit-issue-link grouped" do |
16 | %i.icon-edit | 16 | %i.icon-edit |
17 | Edit | 17 | Edit |
app/views/issues/show.html.haml
@@ -7,10 +7,10 @@ | @@ -7,10 +7,10 @@ | ||
7 | 7 | ||
8 | %span.pull-right | 8 | %span.pull-right |
9 | - if can?(current_user, :admin_project, @project) || @issue.author == current_user | 9 | - if can?(current_user, :admin_project, @project) || @issue.author == current_user |
10 | - - if @issue.closed | ||
11 | - = link_to 'Reopen', project_issue_path(@project, @issue, issue: {closed: false }, status_only: true), method: :put, class: "btn grouped reopen_issue" | 10 | + - if @issue.closed? |
11 | + = link_to 'Reopen', project_issue_path(@project, @issue, issue: {state_event: :reopen }, status_only: true), method: :put, class: "btn grouped reopen_issue" | ||
12 | - else | 12 | - else |
13 | - = link_to 'Close', project_issue_path(@project, @issue, issue: {closed: true }, status_only: true), method: :put, class: "btn grouped close_issue", title: "Close Issue" | 13 | + = link_to 'Close', project_issue_path(@project, @issue, issue: {state_event: :close }, status_only: true), method: :put, class: "btn grouped close_issue", title: "Close Issue" |
14 | - if can?(current_user, :admin_project, @project) || @issue.author == current_user | 14 | - if can?(current_user, :admin_project, @project) || @issue.author == current_user |
15 | = link_to edit_project_issue_path(@project, @issue), class: "btn grouped" do | 15 | = link_to edit_project_issue_path(@project, @issue), class: "btn grouped" do |
16 | %i.icon-edit | 16 | %i.icon-edit |
@@ -27,7 +27,7 @@ | @@ -27,7 +27,7 @@ | ||
27 | .ui-box.ui-box-show | 27 | .ui-box.ui-box-show |
28 | .ui-box-head | 28 | .ui-box-head |
29 | %h4.box-title | 29 | %h4.box-title |
30 | - - if @issue.closed | 30 | + - if @issue.closed? |
31 | .error.status_info Closed | 31 | .error.status_info Closed |
32 | = gfm escape_once(@issue.title) | 32 | = gfm escape_once(@issue.title) |
33 | 33 |
app/views/merge_requests/_show.html.haml
@@ -29,10 +29,10 @@ | @@ -29,10 +29,10 @@ | ||
29 | $(function(){ | 29 | $(function(){ |
30 | merge_request = new MergeRequest({ | 30 | merge_request = new MergeRequest({ |
31 | url_to_automerge_check: "#{automerge_check_project_merge_request_path(@project, @merge_request)}", | 31 | url_to_automerge_check: "#{automerge_check_project_merge_request_path(@project, @merge_request)}", |
32 | - check_enable: #{@merge_request.state == MergeRequest::UNCHECKED ? "true" : "false"}, | 32 | + check_enable: #{@merge_request.merge_status == MergeRequest::UNCHECKED ? "true" : "false"}, |
33 | url_to_ci_check: "#{ci_status_project_merge_request_path(@project, @merge_request)}", | 33 | url_to_ci_check: "#{ci_status_project_merge_request_path(@project, @merge_request)}", |
34 | ci_enable: #{@project.gitlab_ci? ? "true" : "false"}, | 34 | ci_enable: #{@project.gitlab_ci? ? "true" : "false"}, |
35 | - current_state: "#{@merge_request.human_state}", | 35 | + current_status: "#{@merge_request.human_merge_status}", |
36 | action: "#{controller.action_name}" | 36 | action: "#{controller.action_name}" |
37 | }); | 37 | }); |
38 | }); | 38 | }); |
app/views/merge_requests/show/_mr_accept.html.haml
@@ -3,7 +3,7 @@ | @@ -3,7 +3,7 @@ | ||
3 | %strong Only masters can accept MR | 3 | %strong Only masters can accept MR |
4 | 4 | ||
5 | 5 | ||
6 | -- if @merge_request.open? && @commits.any? && can?(current_user, :accept_mr, @project) | 6 | +- if @merge_request.opened? && @commits.any? && can?(current_user, :accept_mr, @project) |
7 | .automerge_widget.can_be_merged{style: "display:none"} | 7 | .automerge_widget.can_be_merged{style: "display:none"} |
8 | .alert.alert-success | 8 | .alert.alert-success |
9 | %span | 9 | %span |
app/views/merge_requests/show/_mr_box.html.haml
1 | .ui-box.ui-box-show | 1 | .ui-box.ui-box-show |
2 | .ui-box-head | 2 | .ui-box-head |
3 | %h4.box-title | 3 | %h4.box-title |
4 | - - if @merge_request.merged | 4 | + - if @merge_request.merged? |
5 | .error.status_info | 5 | .error.status_info |
6 | %i.icon-ok | 6 | %i.icon-ok |
7 | Merged | 7 | Merged |
8 | - - elsif @merge_request.closed | 8 | + - elsif @merge_request.closed? |
9 | .error.status_info Closed | 9 | .error.status_info Closed |
10 | = gfm escape_once(@merge_request.title) | 10 | = gfm escape_once(@merge_request.title) |
11 | 11 | ||
@@ -21,14 +21,14 @@ | @@ -21,14 +21,14 @@ | ||
21 | %strong= link_to_gfm truncate(milestone.title, length: 20), project_milestone_path(milestone.project, milestone) | 21 | %strong= link_to_gfm truncate(milestone.title, length: 20), project_milestone_path(milestone.project, milestone) |
22 | 22 | ||
23 | 23 | ||
24 | - - if @merge_request.closed | 24 | + - if @merge_request.closed? |
25 | .ui-box-bottom | 25 | .ui-box-bottom |
26 | - - if @merge_request.merged? | ||
27 | - %span | ||
28 | - Merged by #{link_to_member(@project, @merge_request.merge_event.author)} | ||
29 | - %small #{time_ago_in_words(@merge_request.merge_event.created_at)} ago. | ||
30 | - - elsif @merge_request.closed_event | ||
31 | - %span | ||
32 | - Closed by #{link_to_member(@project, @merge_request.closed_event.author)} | ||
33 | - %small #{time_ago_in_words(@merge_request.closed_event.created_at)} ago. | 26 | + %span |
27 | + Closed by #{link_to_member(@project, @merge_request.closed_event.author)} | ||
28 | + %small #{time_ago_in_words(@merge_request.closed_event.created_at)} ago. | ||
29 | + - if @merge_request.merged? | ||
30 | + .ui-box-bottom | ||
31 | + %span | ||
32 | + Merged by #{link_to_member(@project, @merge_request.merge_event.author)} | ||
33 | + %small #{time_ago_in_words(@merge_request.merge_event.created_at)} ago. | ||
34 | 34 |
app/views/merge_requests/show/_mr_ci.html.haml
app/views/merge_requests/show/_mr_title.html.haml
@@ -7,7 +7,7 @@ | @@ -7,7 +7,7 @@ | ||
7 | 7 | ||
8 | %span.pull-right | 8 | %span.pull-right |
9 | - if can?(current_user, :modify_merge_request, @merge_request) | 9 | - if can?(current_user, :modify_merge_request, @merge_request) |
10 | - - if @merge_request.open? | 10 | + - if @merge_request.opened? |
11 | .left.btn-group | 11 | .left.btn-group |
12 | %a.btn.grouped.dropdown-toggle{ data: {toggle: :dropdown} } | 12 | %a.btn.grouped.dropdown-toggle{ data: {toggle: :dropdown} } |
13 | %i.icon-download-alt | 13 | %i.icon-download-alt |
@@ -17,7 +17,7 @@ | @@ -17,7 +17,7 @@ | ||
17 | %li= link_to "Email Patches", project_merge_request_path(@project, @merge_request, format: :patch) | 17 | %li= link_to "Email Patches", project_merge_request_path(@project, @merge_request, format: :patch) |
18 | %li= link_to "Plain Diff", project_merge_request_path(@project, @merge_request, format: :diff) | 18 | %li= link_to "Plain Diff", project_merge_request_path(@project, @merge_request, format: :diff) |
19 | 19 | ||
20 | - = link_to 'Close', project_merge_request_path(@project, @merge_request, merge_request: {closed: true }, status_only: true), method: :put, class: "btn grouped btn-close", title: "Close merge request" | 20 | + = link_to 'Close', project_merge_request_path(@project, @merge_request, merge_request: {state_event: :close }), method: :put, class: "btn grouped btn-close", title: "Close merge request" |
21 | 21 | ||
22 | = link_to edit_project_merge_request_path(@project, @merge_request), class: "btn grouped" do | 22 | = link_to edit_project_merge_request_path(@project, @merge_request), class: "btn grouped" do |
23 | %i.icon-edit | 23 | %i.icon-edit |
app/views/milestones/_milestone.html.haml
1 | -%li{class: "milestone milestone-#{milestone.closed ? 'closed' : 'open'}", id: dom_id(milestone) } | 1 | +%li{class: "milestone milestone-#{milestone.closed? ? 'closed' : 'open'}", id: dom_id(milestone) } |
2 | .pull-right | 2 | .pull-right |
3 | - - if can?(current_user, :admin_milestone, milestone.project) and milestone.open? | 3 | + - if can?(current_user, :admin_milestone, milestone.project) and milestone.active? |
4 | = link_to edit_project_milestone_path(milestone.project, milestone), class: "btn btn-small edit-milestone-link grouped" do | 4 | = link_to edit_project_milestone_path(milestone.project, milestone), class: "btn btn-small edit-milestone-link grouped" do |
5 | %i.icon-edit | 5 | %i.icon-edit |
6 | Edit | 6 | Edit |
7 | %h4 | 7 | %h4 |
8 | = link_to_gfm truncate(milestone.title, length: 100), project_milestone_path(milestone.project, milestone) | 8 | = link_to_gfm truncate(milestone.title, length: 100), project_milestone_path(milestone.project, milestone) |
9 | - - if milestone.expired? and not milestone.closed | 9 | + - if milestone.expired? and not milestone.closed? |
10 | %span.cred (Expired) | 10 | %span.cred (Expired) |
11 | %small | 11 | %small |
12 | = milestone.expires_at | 12 | = milestone.expires_at |
app/views/milestones/show.html.haml
@@ -9,7 +9,7 @@ | @@ -9,7 +9,7 @@ | ||
9 | ← To milestones list | 9 | ← To milestones list |
10 | .span6 | 10 | .span6 |
11 | .pull-right | 11 | .pull-right |
12 | - - unless @milestone.closed | 12 | + - unless @milestone.closed? |
13 | = link_to new_project_issue_path(@project, issue: { milestone_id: @milestone.id }), class: "btn btn-small grouped", title: "New Issue" do | 13 | = link_to new_project_issue_path(@project, issue: { milestone_id: @milestone.id }), class: "btn btn-small grouped", title: "New Issue" do |
14 | %i.icon-plus | 14 | %i.icon-plus |
15 | New Issue | 15 | New Issue |
@@ -25,12 +25,12 @@ | @@ -25,12 +25,12 @@ | ||
25 | %hr | 25 | %hr |
26 | %p | 26 | %p |
27 | %span All issues for this milestone are closed. You may close milestone now. | 27 | %span All issues for this milestone are closed. You may close milestone now. |
28 | - = link_to 'Close Milestone', project_milestone_path(@project, @milestone, milestone: {closed: true }), method: :put, class: "btn btn-small btn-remove" | 28 | + = link_to 'Close Milestone', project_milestone_path(@project, @milestone, milestone: {state_event: :close }), method: :put, class: "btn btn-small btn-remove" |
29 | 29 | ||
30 | .ui-box.ui-box-show | 30 | .ui-box.ui-box-show |
31 | .ui-box-head | 31 | .ui-box-head |
32 | %h4.box-title | 32 | %h4.box-title |
33 | - - if @milestone.closed | 33 | + - if @milestone.closed? |
34 | .error.status_info Closed | 34 | .error.status_info Closed |
35 | - elsif @milestone.expired? | 35 | - elsif @milestone.expired? |
36 | .error.status_info Expired | 36 | .error.status_info Expired |
@@ -63,7 +63,7 @@ | @@ -63,7 +63,7 @@ | ||
63 | %li=link_to('All Issues', '#') | 63 | %li=link_to('All Issues', '#') |
64 | %ul.well-list | 64 | %ul.well-list |
65 | - @issues.each do |issue| | 65 | - @issues.each do |issue| |
66 | - %li{data: {closed: issue.closed}} | 66 | + %li{data: {closed: issue.closed?}} |
67 | = link_to [@project, issue] do | 67 | = link_to [@project, issue] do |
68 | %span.badge.badge-info ##{issue.id} | 68 | %span.badge.badge-info ##{issue.id} |
69 | – | 69 | – |
@@ -77,7 +77,7 @@ | @@ -77,7 +77,7 @@ | ||
77 | %li=link_to('All Merge Requests', '#') | 77 | %li=link_to('All Merge Requests', '#') |
78 | %ul.well-list | 78 | %ul.well-list |
79 | - @merge_requests.each do |merge_request| | 79 | - @merge_requests.each do |merge_request| |
80 | - %li{data: {closed: merge_request.closed}} | 80 | + %li{data: {closed: merge_request.closed?}} |
81 | = link_to [@project, merge_request] do | 81 | = link_to [@project, merge_request] do |
82 | %span.badge.badge-info ##{merge_request.id} | 82 | %span.badge.badge-info ##{merge_request.id} |
83 | – | 83 | – |
app/views/notes/_note.html.haml
@@ -31,7 +31,7 @@ | @@ -31,7 +31,7 @@ | ||
31 | - if note.attachment.image? | 31 | - if note.attachment.image? |
32 | = image_tag note.attachment.url, class: 'note-image-attach' | 32 | = image_tag note.attachment.url, class: 'note-image-attach' |
33 | .attachment.pull-right | 33 | .attachment.pull-right |
34 | - = link_to note.attachment.url, target: "_blank" do | 34 | + = link_to note.attachment.secure_url, target: "_blank" do |
35 | %i.icon-paper-clip | 35 | %i.icon-paper-clip |
36 | = note.attachment_identifier | 36 | = note.attachment_identifier |
37 | .clear | 37 | .clear |
app/views/profiles/account.html.haml
@@ -53,29 +53,30 @@ | @@ -53,29 +53,30 @@ | ||
53 | 53 | ||
54 | 54 | ||
55 | 55 | ||
56 | -%fieldset.update-username | ||
57 | - %legend | ||
58 | - Username | ||
59 | - %small.cred.pull-right | ||
60 | - Changing your username can have unintended side effects! | ||
61 | - = form_for @user, url: update_username_profile_path, method: :put, remote: true do |f| | ||
62 | - .padded | ||
63 | - = f.label :username | ||
64 | - .input | ||
65 | - = f.text_field :username, required: true | ||
66 | - | ||
67 | - %span.loading-gif.hide= image_tag "ajax_loader.gif" | ||
68 | - %span.update-success.cgreen.hide | ||
69 | - %i.icon-ok | ||
70 | - Saved | ||
71 | - %span.update-failed.cred.hide | ||
72 | - %i.icon-remove | ||
73 | - Failed | ||
74 | - %ul.cred | ||
75 | - %li It will change web url for personal projects. | ||
76 | - %li It will change the git path to repositories for personal projects. | ||
77 | - .input | ||
78 | - = f.submit 'Save username', class: "btn btn-save" | 56 | +- if current_user.can_change_username? |
57 | + %fieldset.update-username | ||
58 | + %legend | ||
59 | + Username | ||
60 | + %small.cred.pull-right | ||
61 | + Changing your username can have unintended side effects! | ||
62 | + = form_for @user, url: update_username_profile_path, method: :put, remote: true do |f| | ||
63 | + .padded | ||
64 | + = f.label :username | ||
65 | + .input | ||
66 | + = f.text_field :username, required: true | ||
67 | + | ||
68 | + %span.loading-gif.hide= image_tag "ajax_loader.gif" | ||
69 | + %span.update-success.cgreen.hide | ||
70 | + %i.icon-ok | ||
71 | + Saved | ||
72 | + %span.update-failed.cred.hide | ||
73 | + %i.icon-remove | ||
74 | + Failed | ||
75 | + %ul.cred | ||
76 | + %li It will change web url for personal projects. | ||
77 | + %li It will change the git path to repositories for personal projects. | ||
78 | + .input | ||
79 | + = f.submit 'Save username', class: "btn btn-save" | ||
79 | 80 | ||
80 | - if Gitlab.config.gitlab.signup_enabled | 81 | - if Gitlab.config.gitlab.signup_enabled |
81 | %fieldset.remove-account | 82 | %fieldset.remove-account |
@@ -83,4 +84,4 @@ | @@ -83,4 +84,4 @@ | ||
83 | Remove account | 84 | Remove account |
84 | %small.cred.pull-right | 85 | %small.cred.pull-right |
85 | Before removing the account you must remove all projects! | 86 | Before removing the account you must remove all projects! |
86 | - = link_to 'Delete account', user_registration_path, confirm: "REMOVE #{current_user.name}? Are you sure?", method: :delete, class: "btn btn-remove delete-key btn-small pull-right" | ||
87 | \ No newline at end of file | 87 | \ No newline at end of file |
88 | + = link_to 'Delete account', user_registration_path, confirm: "REMOVE #{current_user.name}? Are you sure?", method: :delete, class: "btn btn-remove delete-key btn-small pull-right" |
app/views/profiles/show.html.haml
@@ -77,7 +77,7 @@ | @@ -77,7 +77,7 @@ | ||
77 | %legend | 77 | %legend |
78 | Personal projects: | 78 | Personal projects: |
79 | %small.pull-right | 79 | %small.pull-right |
80 | - %span= current_user.personal_projects.count | 80 | + %span= current_user.owned_projects.count |
81 | of | 81 | of |
82 | %span= current_user.projects_limit | 82 | %span= current_user.projects_limit |
83 | .padded | 83 | .padded |
app/views/projects/_new_form.html.haml
@@ -28,7 +28,7 @@ | @@ -28,7 +28,7 @@ | ||
28 | .input | 28 | .input |
29 | = f.text_field :import_url, class: 'xlarge', placeholder: 'https://github.com/randx/six.git' | 29 | = f.text_field :import_url, class: 'xlarge', placeholder: 'https://github.com/randx/six.git' |
30 | .light | 30 | .light |
31 | - URL should be clonable | 31 | + URL must be clonable |
32 | 32 | ||
33 | %p.padded | 33 | %p.padded |
34 | New projects are private by default. You choose who can see the project and commit to repository. | 34 | New projects are private by default. You choose who can see the project and commit to repository. |
app/views/projects/files.html.haml
@@ -9,7 +9,7 @@ | @@ -9,7 +9,7 @@ | ||
9 | - @notes.each do |note| | 9 | - @notes.each do |note| |
10 | %tr | 10 | %tr |
11 | %td | 11 | %td |
12 | - %a{href: note.attachment.url} | 12 | + = link_to note.attachment.secure_url, target: "_blank" do |
13 | = image_tag gravatar_icon(note.author_email), class: "avatar s24" | 13 | = image_tag gravatar_icon(note.author_email), class: "avatar s24" |
14 | = note.attachment_identifier | 14 | = note.attachment_identifier |
15 | %td | 15 | %td |
@@ -0,0 +1,10 @@ | @@ -0,0 +1,10 @@ | ||
1 | +%li{id: dom_id(team), class: "user_team_row team_#{team.id}"} | ||
2 | + .pull-right | ||
3 | + - if can?(current_user, :admin_team_member, @project) | ||
4 | + = link_to resign_project_team_path(@project, team), method: :delete, confirm: "Are you shure?", class: "btn btn-remove btn-tiny" do | ||
5 | + %i.icon-minus.icon-white | ||
6 | + | ||
7 | + %strong= link_to team.name, team_path(team), title: team.name, class: "dark" | ||
8 | + %br | ||
9 | + %small.cgray Members: #{team.members.count} | ||
10 | + %small.cgray Max access: #{team_relation.human_max_access} |
app/views/team_members/_show.html.haml
@@ -1,28 +0,0 @@ | @@ -1,28 +0,0 @@ | ||
1 | -- user = member.user | ||
2 | -- allow_admin = can? current_user, :admin_project, @project | ||
3 | -%li{id: dom_id(user), class: "team_member_row user_#{user.id}"} | ||
4 | - .row | ||
5 | - .span6 | ||
6 | - = link_to project_team_member_path(@project, user), title: user.name, class: "dark" do | ||
7 | - = image_tag gravatar_icon(user.email, 40), class: "avatar s32" | ||
8 | - = link_to project_team_member_path(@project, user), title: user.name, class: "dark" do | ||
9 | - %strong= truncate(user.name, lenght: 40) | ||
10 | - %br | ||
11 | - %small.cgray= user.email | ||
12 | - | ||
13 | - .span5.pull-right | ||
14 | - - if allow_admin | ||
15 | - .left | ||
16 | - = form_for(member, as: :team_member, url: project_team_member_path(@project, member.user)) do |f| | ||
17 | - = f.select :project_access, options_for_select(UsersProject.access_roles, member.project_access), {}, class: "medium project-access-select span2" | ||
18 | - .pull-right | ||
19 | - - if current_user == user | ||
20 | - %span.btn.disabled This is you! | ||
21 | - - if @project.namespace_owner == user | ||
22 | - %span.btn.disabled Owner | ||
23 | - - elsif user.blocked | ||
24 | - %span.btn.disabled.blocked Blocked | ||
25 | - - elsif allow_admin | ||
26 | - = link_to project_team_member_path(@project, user), confirm: remove_from_project_team_message(@project, user), method: :delete, class: "btn-tiny btn btn-remove" do | ||
27 | - %i.icon-minus.icon-white | ||
28 | - |
app/views/team_members/_show_team.html.haml
@@ -1,15 +0,0 @@ | @@ -1,15 +0,0 @@ | ||
1 | -- team = team_rel.user_team | ||
2 | -- allow_admin = can? current_user, :admin_team_member, @project | ||
3 | -%li{id: dom_id(team), class: "user_team_row team_#{team.id}"} | ||
4 | - .row | ||
5 | - .span6 | ||
6 | - %strong= link_to team.name, team_path(team), title: team.name, class: "dark" | ||
7 | - %br | ||
8 | - %small.cgray Members: #{team.members.count} | ||
9 | - | ||
10 | - .span5.pull-right | ||
11 | - .pull-right | ||
12 | - - if allow_admin | ||
13 | - .left | ||
14 | - = link_to resign_project_team_path(@project, team), method: :delete, confirm: "Are you shure?", class: "btn btn-remove small" do | ||
15 | - %i.icon-minus.icon-white |
app/views/team_members/_team.html.haml
1 | -- grouper_project_members(@project).each do |access, members| | 1 | +- team.each do |access, members| |
2 | .ui-box | 2 | .ui-box |
3 | %h5.title | 3 | %h5.title |
4 | = Project.access_options.key(access).pluralize | 4 | = Project.access_options.key(access).pluralize |
5 | %small= members.size | 5 | %small= members.size |
6 | %ul.well-list | 6 | %ul.well-list |
7 | - - members.sort_by(&:user_name).each do |up| | ||
8 | - = render(partial: 'team_members/show', locals: {member: up}) | ||
9 | - | ||
10 | - | ||
11 | -:javascript | ||
12 | - $(function(){ | ||
13 | - $('.repo-access-select, .project-access-select').live("change", function() { | ||
14 | - $(this.form).submit(); | ||
15 | - }); | ||
16 | - }) | 7 | + - members.sort_by(&:user_name).each do |team_member| |
8 | + = render 'team_members/team_member', member: team_member |
@@ -0,0 +1,28 @@ | @@ -0,0 +1,28 @@ | ||
1 | +- user = member.user | ||
2 | +- allow_admin = can? current_user, :admin_project, @project | ||
3 | +%li{id: dom_id(user), class: "team_member_row user_#{user.id}"} | ||
4 | + .row | ||
5 | + .span4 | ||
6 | + = link_to project_team_member_path(@project, user), title: user.name, class: "dark" do | ||
7 | + = image_tag gravatar_icon(user.email, 40), class: "avatar s32" | ||
8 | + = link_to project_team_member_path(@project, user), title: user.name, class: "dark" do | ||
9 | + %strong= truncate(user.name, lenght: 40) | ||
10 | + %br | ||
11 | + %small.cgray= user.email | ||
12 | + | ||
13 | + .span4.pull-right | ||
14 | + - if allow_admin | ||
15 | + .left | ||
16 | + = form_for(member, as: :team_member, url: project_team_member_path(@project, member.user)) do |f| | ||
17 | + = f.select :project_access, options_for_select(UsersProject.access_roles, member.project_access), {}, class: "medium project-access-select span2 trigger-submit" | ||
18 | + .pull-right | ||
19 | + - if current_user == user | ||
20 | + %span.label This is you! | ||
21 | + - if @project.namespace_owner == user | ||
22 | + %span.label Owner | ||
23 | + - elsif user.blocked | ||
24 | + %span.label Blocked | ||
25 | + - elsif allow_admin | ||
26 | + = link_to project_team_member_path(@project, user), confirm: remove_from_project_team_message(@project, user), method: :delete, class: "btn-tiny btn btn-remove" do | ||
27 | + %i.icon-minus.icon-white | ||
28 | + |
app/views/team_members/_teams.html.haml
@@ -1,16 +0,0 @@ | @@ -1,16 +0,0 @@ | ||
1 | -- grouper_project_teams(@project).each do |access, teams| | ||
2 | - .ui-box | ||
3 | - %h5.title | ||
4 | - = UserTeam.access_roles.key(access).pluralize | ||
5 | - %small= teams.size | ||
6 | - %ul.well-list | ||
7 | - - teams.sort_by(&:team_name).each do |tofr| | ||
8 | - = render(partial: 'team_members/show_team', locals: {team_rel: tofr}) | ||
9 | - | ||
10 | - | ||
11 | -:javascript | ||
12 | - $(function(){ | ||
13 | - $('.repo-access-select, .project-access-select').live("change", function() { | ||
14 | - $(this.form).submit(); | ||
15 | - }); | ||
16 | - }) |
app/views/team_members/index.html.haml
@@ -18,16 +18,39 @@ | @@ -18,16 +18,39 @@ | ||
18 | %hr | 18 | %hr |
19 | 19 | ||
20 | .clearfix | 20 | .clearfix |
21 | -%div.team-table | ||
22 | - = render partial: "team_members/team", locals: {project: @project} | 21 | +.row |
22 | + .span3 | ||
23 | + %ul.nav.nav-pills.nav-stacked | ||
24 | + %li{class: ("active" if !params[:type])} | ||
25 | + = link_to project_team_members_path(type: nil) do | ||
26 | + All | ||
27 | + %li{class: ("active" if params[:type] == 'masters')} | ||
28 | + = link_to project_team_members_path(type: 'masters') do | ||
29 | + Masters | ||
30 | + %span.pull-right= @project.users_projects.masters.count | ||
31 | + %li{class: ("active" if params[:type] == 'developers')} | ||
32 | + = link_to project_team_members_path(type: 'developers') do | ||
33 | + Developers | ||
34 | + %span.pull-right= @project.users_projects.developers.count | ||
35 | + %li{class: ("active" if params[:type] == 'reporters')} | ||
36 | + = link_to project_team_members_path(type: 'reporters') do | ||
37 | + Reporters | ||
38 | + %span.pull-right= @project.users_projects.reporters.count | ||
39 | + %li{class: ("active" if params[:type] == 'guests')} | ||
40 | + = link_to project_team_members_path(type: 'guests') do | ||
41 | + Guests | ||
42 | + %span.pull-right= @project.users_projects.guests.count | ||
23 | 43 | ||
44 | + - if @assigned_teams.present? | ||
45 | + %h5 | ||
46 | + Assigned teams | ||
47 | + (#{@project.user_teams.count}) | ||
48 | + %div | ||
49 | + = render "team_members/assigned_teams", assigned_teams: @assigned_teams | ||
50 | + | ||
51 | + .span9 | ||
52 | + %div.team-table | ||
53 | + = render "team_members/team", team: @team | ||
24 | 54 | ||
25 | -%h3.page_title | ||
26 | - Assigned teams | ||
27 | - (#{@project.user_teams.count}) | ||
28 | 55 | ||
29 | -%hr | ||
30 | 56 | ||
31 | -.clearfix | ||
32 | -%div.team-table | ||
33 | - = render partial: "team_members/teams", locals: {project: @project} |
app/views/teams/edit.html.haml
1 | %h3.page_title= "Edit Team #{@team.name}" | 1 | %h3.page_title= "Edit Team #{@team.name}" |
2 | %hr | 2 | %hr |
3 | -= form_for @team, url: team_path(@team) do |f| | ||
4 | - - if @team.errors.any? | ||
5 | - .alert.alert-error | ||
6 | - %span= @team.errors.full_messages.first | ||
7 | - .clearfix | ||
8 | - = f.label :name do | ||
9 | - Team name is | ||
10 | - .input | ||
11 | - = f.text_field :name, placeholder: "Ex. OpenSource", class: "xxlarge left" | 3 | +.row |
4 | + .span7 | ||
5 | + = form_for @team, url: team_path(@team) do |f| | ||
6 | + - if @team.errors.any? | ||
7 | + .alert.alert-error | ||
8 | + %span= @team.errors.full_messages.first | ||
9 | + .clearfix | ||
10 | + = f.label :name do | ||
11 | + Team name is | ||
12 | + .input | ||
13 | + = f.text_field :name, placeholder: "Ex. OpenSource", class: "xlarge left" | ||
14 | + | ||
15 | + .clearfix | ||
16 | + = f.label :path do | ||
17 | + Team path is | ||
18 | + .input | ||
19 | + = f.text_field :path, placeholder: "opensource", class: "xlarge left" | ||
20 | + .form-actions | ||
21 | + = f.submit 'Save team changes', class: "btn btn-save" | ||
22 | + .span5 | ||
23 | + .ui-box | ||
24 | + %h5.title Remove team | ||
25 | + .padded.bgred | ||
26 | + %p | ||
27 | + Removed team can not be restored! | ||
28 | + = link_to 'Remove team', team_path(@team), method: :delete, confirm: "You are sure?", class: "btn btn-remove btn-small" | ||
12 | 29 | ||
13 | - .clearfix | ||
14 | - = f.label :path do | ||
15 | - Team path is | ||
16 | - .input | ||
17 | - = f.text_field :path, placeholder: "opensource", class: "xxlarge left" | ||
18 | - .form-actions | ||
19 | - = f.submit 'Save team changes', class: "btn btn-primary" | ||
20 | - = link_to 'Delete team', team_path(@team), method: :delete, confirm: "You are shure?", class: "btn btn-remove pull-right" |
app/views/teams/members/_show.html.haml
@@ -10,22 +10,21 @@ | @@ -10,22 +10,21 @@ | ||
10 | %br | 10 | %br |
11 | %small.cgray= user.email | 11 | %small.cgray= user.email |
12 | 12 | ||
13 | - .span6.pull-right | 13 | + .span4 |
14 | - if allow_admin | 14 | - if allow_admin |
15 | - .left.span2 | ||
16 | - = form_for(member, as: :team_member, url: team_member_path(@team, user)) do |f| | ||
17 | - = f.select :permission, options_for_select(UsersProject.access_roles, @team.default_projects_access(user)), {}, class: "medium project-access-select span2" | ||
18 | - .left.span2 | ||
19 | - %span | ||
20 | - = check_box_tag :group_admin, true, @team.admin?(user) | ||
21 | - Admin access | ||
22 | - .pull-right | ||
23 | - - if current_user == user | ||
24 | - %span.btn.disabled This is you! | ||
25 | - - if @team.owner == user | ||
26 | - %span.btn.disabled.btn-success Owner | ||
27 | - - elsif user.blocked | ||
28 | - %span.btn.disabled.blocked Blocked | ||
29 | - - elsif allow_admin | ||
30 | - = link_to team_member_path(@team, user), confirm: remove_from_user_team_message(@team, user), method: :delete, class: "btn-tiny btn btn-remove" do | ||
31 | - %i.icon-minus.icon-white | 15 | + = form_for(member, as: :team_member, url: team_member_path(@team, user)) do |f| |
16 | + = f.select :permission, options_for_select(UsersProject.access_roles, @team.default_projects_access(user)), {}, class: "medium trigger-submit" | ||
17 | + %br | ||
18 | + = label_tag do | ||
19 | + = f.check_box :group_admin, class: 'trigger-submit' | ||
20 | + %span Admin access | ||
21 | + .pull-right | ||
22 | + - if current_user == user | ||
23 | + %span.btn.disabled This is you! | ||
24 | + - if @team.owner == user | ||
25 | + %span.btn.disabled Owner | ||
26 | + - elsif user.blocked | ||
27 | + %span.btn.disabled.blocked Blocked | ||
28 | + - elsif allow_admin | ||
29 | + = link_to team_member_path(@team, user), confirm: remove_from_user_team_message(@team, user), method: :delete, class: "btn-tiny btn btn-remove" do | ||
30 | + %i.icon-minus.icon-white |
app/views/teams/new.html.haml
@@ -17,3 +17,17 @@ | @@ -17,3 +17,17 @@ | ||
17 | %li All created teams are public (users can view who enter into team and which project are assigned for this team) | 17 | %li All created teams are public (users can view who enter into team and which project are assigned for this team) |
18 | %li People within a team see only projects they have access to | 18 | %li People within a team see only projects they have access to |
19 | %li You will be able to assign existing projects for team | 19 | %li You will be able to assign existing projects for team |
20 | + %hr | ||
21 | + | ||
22 | + - if current_user.can_create_group? | ||
23 | + .clearfix | ||
24 | + .input.light | ||
25 | + Need a group for several dependent projects? | ||
26 | + = link_to new_group_path, class: "btn btn-tiny" do | ||
27 | + Create a group | ||
28 | + - if current_user.can_create_project? | ||
29 | + .clearfix | ||
30 | + .input.light | ||
31 | + Want to create a project? | ||
32 | + = link_to new_project_path, class: "btn btn-tiny" do | ||
33 | + Create a project |
app/workers/post_receive.rb
@@ -21,14 +21,18 @@ class PostReceive | @@ -21,14 +21,18 @@ class PostReceive | ||
21 | return false | 21 | return false |
22 | end | 22 | end |
23 | 23 | ||
24 | - # Ignore push from non-gitlab users | ||
25 | - user = if identifier.nil? | ||
26 | - raise identifier.inspect | 24 | + user = if identifier.blank? |
25 | + # Local push from gitlab | ||
27 | email = project.repository.commit(newrev).author.email rescue nil | 26 | email = project.repository.commit(newrev).author.email rescue nil |
28 | User.find_by_email(email) if email | 27 | User.find_by_email(email) if email |
29 | - elsif /^[A-Z0-9._%a-z\-]+@(?:[A-Z0-9a-z\-]+\.)+[A-Za-z]{2,4}$/.match(identifier) | ||
30 | - User.find_by_email(identifier) | ||
31 | - elsif identifier =~ /key/ | 28 | + |
29 | + elsif identifier =~ /\Auser-\d+\Z/ | ||
30 | + # git push over http | ||
31 | + user_id = identifier.gsub("user-", "") | ||
32 | + User.find_by_id(user_id) | ||
33 | + | ||
34 | + elsif identifier =~ /\Akey-\d+\Z/ | ||
35 | + # git push over ssh | ||
32 | key_id = identifier.gsub("key-", "") | 36 | key_id = identifier.gsub("key-", "") |
33 | Key.find_by_id(key_id).try(:user) | 37 | Key.find_by_id(key_id).try(:user) |
34 | end | 38 | end |
config/gitlab.yml.example
@@ -7,121 +7,132 @@ | @@ -7,121 +7,132 @@ | ||
7 | # 2. Replace gitlab -> host with your domain | 7 | # 2. Replace gitlab -> host with your domain |
8 | # 3. Replace gitlab -> email_from | 8 | # 3. Replace gitlab -> email_from |
9 | 9 | ||
10 | -# | ||
11 | -# 1. GitLab app settings | ||
12 | -# ========================== | ||
13 | - | ||
14 | -## GitLab settings | ||
15 | -gitlab: | ||
16 | - ## Web server settings | ||
17 | - host: localhost | ||
18 | - port: 80 | ||
19 | - https: false | ||
20 | - # Uncomment and customize to run in non-root path | ||
21 | - # Note that ENV['RAILS_RELATIVE_URL_ROOT'] in config/unicorn.rb may need to be changed | ||
22 | - # relative_url_root: /gitlab | ||
23 | - | ||
24 | - # Uncomment and customize if you can't use the default user to run GitLab (default: 'git') | ||
25 | - # user: git | ||
26 | - | ||
27 | - ## Email settings | ||
28 | - # Email address used in the "From" field in mails sent by GitLab | ||
29 | - email_from: gitlab@localhost | ||
30 | - | ||
31 | - # Email address of your support contact (default: same as email_from) | ||
32 | - support_email: support@localhost | ||
33 | - | ||
34 | - ## Project settings | ||
35 | - default_projects_limit: 10 | ||
36 | - # signup_enabled: true # default: false - Account passwords are not sent via the email if signup is enabled. | ||
37 | - | ||
38 | -## Gravatar | ||
39 | -gravatar: | ||
40 | - enabled: true # Use user avatar images from Gravatar.com (default: true) | ||
41 | - # plain_url: "http://..." # default: http://www.gravatar.com/avatar/%{hash}?s=%{size}&d=mm | ||
42 | - # ssl_url: "https://..." # default: https://secure.gravatar.com/avatar/%{hash}?s=%{size}&d=mm | ||
43 | - | ||
44 | - | ||
45 | - | ||
46 | -# | ||
47 | -# 2. Auth settings | ||
48 | -# ========================== | ||
49 | - | ||
50 | -## LDAP settings | ||
51 | -ldap: | ||
52 | - enabled: false | ||
53 | - host: '_your_ldap_server' | ||
54 | - base: '_the_base_where_you_search_for_users' | ||
55 | - port: 636 | ||
56 | - uid: 'sAMAccountName' | ||
57 | - method: 'ssl' # "ssl" or "plain" | ||
58 | - bind_dn: '_the_full_dn_of_the_user_you_will_bind_with' | ||
59 | - password: '_the_password_of_the_bind_user' | ||
60 | - | ||
61 | -## Omniauth settings | ||
62 | -omniauth: | ||
63 | - # Enable ability for users | ||
64 | - # Allow logging in via Twitter, Google, etc. using Omniauth providers | ||
65 | - enabled: false | ||
66 | - | 10 | +production: &base |
11 | + # | ||
12 | + # 1. GitLab app settings | ||
13 | + # ========================== | ||
14 | + | ||
15 | + ## GitLab settings | ||
16 | + gitlab: | ||
17 | + ## Web server settings | ||
18 | + host: localhost | ||
19 | + port: 80 | ||
20 | + https: false | ||
21 | + # Uncomment and customize to run in non-root path | ||
22 | + # Note that ENV['RAILS_RELATIVE_URL_ROOT'] in config/unicorn.rb may need to be changed | ||
23 | + # relative_url_root: /gitlab | ||
24 | + | ||
25 | + # Uncomment and customize if you can't use the default user to run GitLab (default: 'git') | ||
26 | + # user: git | ||
27 | + | ||
28 | + ## Email settings | ||
29 | + # Email address used in the "From" field in mails sent by GitLab | ||
30 | + email_from: gitlab@localhost | ||
31 | + | ||
32 | + # Email address of your support contact (default: same as email_from) | ||
33 | + support_email: support@localhost | ||
34 | + | ||
35 | + ## Project settings | ||
36 | + default_projects_limit: 10 | ||
37 | + # signup_enabled: true # default: false - Account passwords are not sent via the email if signup is enabled. | ||
38 | + # username_changing_enabled: false # default: true - User can change her username/namespace | ||
39 | + | ||
40 | + ## Gravatar | ||
41 | + gravatar: | ||
42 | + enabled: true # Use user avatar images from Gravatar.com (default: true) | ||
43 | + # plain_url: "http://..." # default: http://www.gravatar.com/avatar/%{hash}?s=%{size}&d=mm | ||
44 | + # ssl_url: "https://..." # default: https://secure.gravatar.com/avatar/%{hash}?s=%{size}&d=mm | ||
45 | + | ||
46 | + | ||
47 | + | ||
48 | + # | ||
49 | + # 2. Auth settings | ||
50 | + # ========================== | ||
51 | + | ||
52 | + ## LDAP settings | ||
53 | + ldap: | ||
54 | + enabled: false | ||
55 | + host: '_your_ldap_server' | ||
56 | + base: '_the_base_where_you_search_for_users' | ||
57 | + port: 636 | ||
58 | + uid: 'sAMAccountName' | ||
59 | + method: 'ssl' # "ssl" or "plain" | ||
60 | + bind_dn: '_the_full_dn_of_the_user_you_will_bind_with' | ||
61 | + password: '_the_password_of_the_bind_user' | ||
62 | + | ||
63 | + ## Omniauth settings | ||
64 | + omniauth: | ||
65 | + # Enable ability for users | ||
66 | + # Allow logging in via Twitter, Google, etc. using Omniauth providers | ||
67 | + enabled: false | ||
68 | + | ||
69 | + # CAUTION! | ||
70 | + # This allows users to login without having a user account first (default: false) | ||
71 | + # User accounts will be created automatically when authentication was successful. | ||
72 | + allow_single_sign_on: false | ||
73 | + # Locks down those users until they have been cleared by the admin (default: true) | ||
74 | + block_auto_created_users: true | ||
75 | + | ||
76 | + ## Auth providers | ||
77 | + # Uncomment the lines and fill in the data of the auth provider you want to use | ||
78 | + # If your favorite auth provider is not listed you can user others: | ||
79 | + # see https://github.com/gitlabhq/gitlabhq/wiki/Using-Custom-Omniauth-Providers | ||
80 | + # The 'app_id' and 'app_secret' parameters are always passed as the first two | ||
81 | + # arguments, followed by optional 'args' which can be either a hash or an array. | ||
82 | + providers: | ||
83 | + # - { name: 'google_oauth2', app_id: 'YOUR APP ID', | ||
84 | + # app_secret: 'YOUR APP SECRET', | ||
85 | + # args: { access_type: 'offline', approval_prompt: '' } } | ||
86 | + # - { name: 'twitter', app_id: 'YOUR APP ID', | ||
87 | + # app_secret: 'YOUR APP SECRET'} | ||
88 | + # - { name: 'github', app_id: 'YOUR APP ID', | ||
89 | + # app_secret: 'YOUR APP SECRET' } | ||
90 | + | ||
91 | + | ||
92 | + | ||
93 | + # | ||
94 | + # 3. Advanced settings | ||
95 | + # ========================== | ||
96 | + | ||
97 | + # GitLab Satellites | ||
98 | + satellites: | ||
99 | + # Relative paths are relative to Rails.root (default: tmp/repo_satellites/) | ||
100 | + path: /home/git/gitlab-satellites/ | ||
101 | + | ||
102 | + ## Backup settings | ||
103 | + backup: | ||
104 | + path: "tmp/backups" # Relative paths are relative to Rails.root (default: tmp/backups/) | ||
105 | + # keep_time: 604800 # default: 0 (forever) (in seconds) | ||
106 | + | ||
107 | + ## GitLab Shell settings | ||
108 | + gitlab_shell: | ||
109 | + # REPOS_PATH MUST NOT BE A SYMLINK!!! | ||
110 | + repos_path: /home/git/repositories/ | ||
111 | + hooks_path: /home/git/gitlab-shell/hooks/ | ||
112 | + | ||
113 | + # Git over HTTP | ||
114 | + upload_pack: true | ||
115 | + receive_pack: true | ||
116 | + | ||
117 | + # If you use non-standart ssh port you need to specify it | ||
118 | + # ssh_port: 22 | ||
119 | + | ||
120 | + ## Git settings | ||
67 | # CAUTION! | 121 | # CAUTION! |
68 | - # This allows users to login without having a user account first (default: false) | ||
69 | - # User accounts will be created automatically when authentication was successful. | ||
70 | - allow_single_sign_on: false | ||
71 | - # Locks down those users until they have been cleared by the admin (default: true) | ||
72 | - block_auto_created_users: true | ||
73 | - | ||
74 | - ## Auth providers | ||
75 | - # Uncomment the lines and fill in the data of the auth provider you want to use | ||
76 | - # If your favorite auth provider is not listed you can user others: | ||
77 | - # see https://github.com/gitlabhq/gitlabhq/wiki/Using-Custom-Omniauth-Providers | ||
78 | - # The 'app_id' and 'app_secret' parameters are always passed as the first two | ||
79 | - # arguments, followed by optional 'args' which can be either a hash or an array. | ||
80 | - providers: | ||
81 | - # - { name: 'google_oauth2', app_id: 'YOUR APP ID', | ||
82 | - # app_secret: 'YOUR APP SECRET', | ||
83 | - # args: { access_type: 'offline', approval_prompt: '' } } | ||
84 | - # - { name: 'twitter', app_id: 'YOUR APP ID', | ||
85 | - # app_secret: 'YOUR APP SECRET'} | ||
86 | - # - { name: 'github', app_id: 'YOUR APP ID', | ||
87 | - # app_secret: 'YOUR APP SECRET' } | ||
88 | - | ||
89 | - | ||
90 | - | ||
91 | -# | ||
92 | -# 3. Advanced settings | ||
93 | -# ========================== | ||
94 | - | ||
95 | -# GitLab Satellites | ||
96 | -satellites: | ||
97 | - # Relative paths are relative to Rails.root (default: tmp/repo_satellites/) | ||
98 | - path: /home/git/gitlab-satellites/ | ||
99 | - | ||
100 | -## Backup settings | ||
101 | -backup: | ||
102 | - path: "tmp/backups" # Relative paths are relative to Rails.root (default: tmp/backups/) | ||
103 | - # keep_time: 604800 # default: 0 (forever) (in seconds) | ||
104 | - | ||
105 | -## GitLab Shell settings | ||
106 | -gitlab_shell: | ||
107 | - # REPOS_PATH MUST NOT BE A SYMLINK!!! | ||
108 | - repos_path: /home/git/repositories/ | ||
109 | - hooks_path: /home/git/gitlab-shell/hooks/ | ||
110 | - | ||
111 | - # Git over HTTP | ||
112 | - upload_pack: true | ||
113 | - receive_pack: true | ||
114 | - | ||
115 | - # If you use non-standart ssh port you need to specify it | ||
116 | - # ssh_port: 22 | ||
117 | - | ||
118 | -## Git settings | ||
119 | -# CAUTION! | ||
120 | -# Use the default values unless you really know what you are doing | ||
121 | -git: | ||
122 | - bin_path: /usr/bin/git | ||
123 | - # Max size of git object like commit, in bytes | ||
124 | - # This value can be increased if you have a very large commits | ||
125 | - max_size: 5242880 # 5.megabytes | ||
126 | - # Git timeout to read commit, in seconds | ||
127 | - timeout: 10 | 122 | + # Use the default values unless you really know what you are doing |
123 | + git: | ||
124 | + bin_path: /usr/bin/git | ||
125 | + # Max size of git object like commit, in bytes | ||
126 | + # This value can be increased if you have a very large commits | ||
127 | + max_size: 5242880 # 5.megabytes | ||
128 | + # Git timeout to read commit, in seconds | ||
129 | + timeout: 10 | ||
130 | + | ||
131 | +development: | ||
132 | + <<: *base | ||
133 | + | ||
134 | +test: | ||
135 | + <<: *base | ||
136 | + | ||
137 | +staging: | ||
138 | + <<: *base |
config/initializers/1_settings.rb
1 | class Settings < Settingslogic | 1 | class Settings < Settingslogic |
2 | source "#{Rails.root}/config/gitlab.yml" | 2 | source "#{Rails.root}/config/gitlab.yml" |
3 | + namespace Rails.env | ||
3 | 4 | ||
4 | class << self | 5 | class << self |
5 | def gitlab_on_non_standard_port? | 6 | def gitlab_on_non_standard_port? |
@@ -56,6 +57,7 @@ Settings.gitlab['support_email'] ||= Settings.gitlab.email_from | @@ -56,6 +57,7 @@ Settings.gitlab['support_email'] ||= Settings.gitlab.email_from | ||
56 | Settings.gitlab['url'] ||= Settings.send(:build_gitlab_url) | 57 | Settings.gitlab['url'] ||= Settings.send(:build_gitlab_url) |
57 | Settings.gitlab['user'] ||= 'git' | 58 | Settings.gitlab['user'] ||= 'git' |
58 | Settings.gitlab['signup_enabled'] ||= false | 59 | Settings.gitlab['signup_enabled'] ||= false |
60 | +Settings.gitlab['username_changing_enabled'] = true if Settings.gitlab['username_changing_enabled'].nil? | ||
59 | 61 | ||
60 | # | 62 | # |
61 | # Gravatar | 63 | # Gravatar |
config/initializers/2_app.rb
1 | module Gitlab | 1 | module Gitlab |
2 | - Version = File.read(Rails.root.join("VERSION")) | ||
3 | - Revision = `git log --pretty=format:'%h' -n 1` | 2 | + VERSION = File.read(Rails.root.join("VERSION")).strip |
3 | + REVISION = `git log --pretty=format:'%h' -n 1` | ||
4 | 4 | ||
5 | def self.config | 5 | def self.config |
6 | Settings | 6 | Settings |
config/routes.rb
@@ -47,6 +47,11 @@ Gitlab::Application.routes.draw do | @@ -47,6 +47,11 @@ Gitlab::Application.routes.draw do | ||
47 | end | 47 | end |
48 | 48 | ||
49 | # | 49 | # |
50 | + # Attachments serving | ||
51 | + # | ||
52 | + get 'files/:type/:id/:filename' => 'files#download', constraints: { id: /\d+/, type: /[a-z]+/, filename: /[a-zA-Z.0-9_\-\+]+/ } | ||
53 | + | ||
54 | + # | ||
50 | # Admin Area | 55 | # Admin Area |
51 | # | 56 | # |
52 | namespace :admin do | 57 | namespace :admin do |
db/fixtures/development/02_source_code.rb
db/fixtures/development/09_issues.rb
@@ -16,7 +16,7 @@ Gitlab::Seeder.quiet do | @@ -16,7 +16,7 @@ Gitlab::Seeder.quiet do | ||
16 | project_id: project.id, | 16 | project_id: project.id, |
17 | author_id: user_id, | 17 | author_id: user_id, |
18 | assignee_id: user_id, | 18 | assignee_id: user_id, |
19 | - closed: [true, false].sample, | 19 | + state: ['opened', 'closed'].sample, |
20 | milestone: project.milestones.sample, | 20 | milestone: project.milestones.sample, |
21 | title: Faker::Lorem.sentence(6) | 21 | title: Faker::Lorem.sentence(6) |
22 | }]) | 22 | }]) |
db/fixtures/development/10_merge_requests.rb
@@ -17,7 +17,7 @@ Gitlab::Seeder.quiet do | @@ -17,7 +17,7 @@ Gitlab::Seeder.quiet do | ||
17 | project_id: project.id, | 17 | project_id: project.id, |
18 | author_id: user_id, | 18 | author_id: user_id, |
19 | assignee_id: user_id, | 19 | assignee_id: user_id, |
20 | - closed: [true, false].sample, | 20 | + state: ['opened', 'closed'].sample, |
21 | milestone: project.milestones.sample, | 21 | milestone: project.milestones.sample, |
22 | title: Faker::Lorem.sentence(6) | 22 | title: Faker::Lorem.sentence(6) |
23 | }]) | 23 | }]) |
db/migrate/20130214154045_rename_state_to_merge_status_in_milestone.rb
0 → 100644
db/migrate/20130218141258_convert_closed_to_state_in_issue.rb
0 → 100644
@@ -0,0 +1,14 @@ | @@ -0,0 +1,14 @@ | ||
1 | +class ConvertClosedToStateInIssue < ActiveRecord::Migration | ||
2 | + def up | ||
3 | + Issue.transaction do | ||
4 | + Issue.where(closed: true).update_all("state = 'closed'") | ||
5 | + Issue.where(closed: false).update_all("state = 'opened'") | ||
6 | + end | ||
7 | + end | ||
8 | + | ||
9 | + def down | ||
10 | + Issue.transaction do | ||
11 | + Issue.where(state: :closed).update_all("closed = 1") | ||
12 | + end | ||
13 | + end | ||
14 | +end |
db/migrate/20130218141327_convert_closed_to_state_in_merge_request.rb
0 → 100644
@@ -0,0 +1,16 @@ | @@ -0,0 +1,16 @@ | ||
1 | +class ConvertClosedToStateInMergeRequest < ActiveRecord::Migration | ||
2 | + def up | ||
3 | + MergeRequest.transaction do | ||
4 | + MergeRequest.where("closed = 1 AND merged = 1").update_all("state = 'merged'") | ||
5 | + MergeRequest.where("closed = 1 AND merged = 0").update_all("state = 'closed'") | ||
6 | + MergeRequest.where("closed = 0").update_all("state = 'opened'") | ||
7 | + end | ||
8 | + end | ||
9 | + | ||
10 | + def down | ||
11 | + MergeRequest.transaction do | ||
12 | + MergeRequest.where(state: :closed).update_all("closed = 1") | ||
13 | + MergeRequest.where(state: :merged).update_all("closed = 1, merged = 1") | ||
14 | + end | ||
15 | + end | ||
16 | +end |
db/migrate/20130218141344_convert_closed_to_state_in_milestone.rb
0 → 100644
@@ -0,0 +1,14 @@ | @@ -0,0 +1,14 @@ | ||
1 | +class ConvertClosedToStateInMilestone < ActiveRecord::Migration | ||
2 | + def up | ||
3 | + Milestone.transaction do | ||
4 | + Milestone.where(closed: false).update_all("state = 'opened'") | ||
5 | + Milestone.where(closed: false).update_all("state = 'active'") | ||
6 | + end | ||
7 | + end | ||
8 | + | ||
9 | + def down | ||
10 | + Milestone.transaction do | ||
11 | + Milestone.where(state: :closed).update_all("closed = 1") | ||
12 | + end | ||
13 | + end | ||
14 | +end |
db/migrate/20130218141444_remove_merged_from_merge_request.rb
0 → 100644
db/migrate/20130218141536_remove_closed_from_merge_request.rb
0 → 100644
db/migrate/20130218141554_remove_closed_from_milestone.rb
0 → 100644
db/schema.rb
@@ -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 => 20130131070232) do | 14 | +ActiveRecord::Schema.define(:version => 20130218141554) 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" |
@@ -37,18 +37,17 @@ ActiveRecord::Schema.define(:version => 20130131070232) do | @@ -37,18 +37,17 @@ ActiveRecord::Schema.define(:version => 20130131070232) do | ||
37 | t.integer "assignee_id" | 37 | t.integer "assignee_id" |
38 | t.integer "author_id" | 38 | t.integer "author_id" |
39 | t.integer "project_id" | 39 | t.integer "project_id" |
40 | - t.datetime "created_at", :null => false | ||
41 | - t.datetime "updated_at", :null => false | ||
42 | - t.boolean "closed", :default => false, :null => false | 40 | + t.datetime "created_at", :null => false |
41 | + t.datetime "updated_at", :null => false | ||
43 | t.integer "position", :default => 0 | 42 | t.integer "position", :default => 0 |
44 | t.string "branch_name" | 43 | t.string "branch_name" |
45 | t.text "description" | 44 | t.text "description" |
46 | t.integer "milestone_id" | 45 | t.integer "milestone_id" |
46 | + t.string "state" | ||
47 | end | 47 | end |
48 | 48 | ||
49 | add_index "issues", ["assignee_id"], :name => "index_issues_on_assignee_id" | 49 | add_index "issues", ["assignee_id"], :name => "index_issues_on_assignee_id" |
50 | add_index "issues", ["author_id"], :name => "index_issues_on_author_id" | 50 | add_index "issues", ["author_id"], :name => "index_issues_on_author_id" |
51 | - add_index "issues", ["closed"], :name => "index_issues_on_closed" | ||
52 | add_index "issues", ["created_at"], :name => "index_issues_on_created_at" | 51 | add_index "issues", ["created_at"], :name => "index_issues_on_created_at" |
53 | add_index "issues", ["milestone_id"], :name => "index_issues_on_milestone_id" | 52 | add_index "issues", ["milestone_id"], :name => "index_issues_on_milestone_id" |
54 | add_index "issues", ["project_id"], :name => "index_issues_on_project_id" | 53 | add_index "issues", ["project_id"], :name => "index_issues_on_project_id" |
@@ -69,25 +68,23 @@ ActiveRecord::Schema.define(:version => 20130131070232) do | @@ -69,25 +68,23 @@ ActiveRecord::Schema.define(:version => 20130131070232) do | ||
69 | add_index "keys", ["user_id"], :name => "index_keys_on_user_id" | 68 | add_index "keys", ["user_id"], :name => "index_keys_on_user_id" |
70 | 69 | ||
71 | create_table "merge_requests", :force => true do |t| | 70 | create_table "merge_requests", :force => true do |t| |
72 | - t.string "target_branch", :null => false | ||
73 | - t.string "source_branch", :null => false | ||
74 | - t.integer "project_id", :null => false | 71 | + t.string "target_branch", :null => false |
72 | + t.string "source_branch", :null => false | ||
73 | + t.integer "project_id", :null => false | ||
75 | t.integer "author_id" | 74 | t.integer "author_id" |
76 | t.integer "assignee_id" | 75 | t.integer "assignee_id" |
77 | t.string "title" | 76 | t.string "title" |
78 | - t.boolean "closed", :default => false, :null => false | ||
79 | - t.datetime "created_at", :null => false | ||
80 | - t.datetime "updated_at", :null => false | 77 | + t.datetime "created_at", :null => false |
78 | + t.datetime "updated_at", :null => false | ||
81 | t.text "st_commits", :limit => 2147483647 | 79 | t.text "st_commits", :limit => 2147483647 |
82 | t.text "st_diffs", :limit => 2147483647 | 80 | t.text "st_diffs", :limit => 2147483647 |
83 | - t.boolean "merged", :default => false, :null => false | ||
84 | - t.integer "state", :default => 1, :null => false | 81 | + t.integer "merge_status", :default => 1, :null => false |
85 | t.integer "milestone_id" | 82 | t.integer "milestone_id" |
83 | + t.string "state" | ||
86 | end | 84 | end |
87 | 85 | ||
88 | add_index "merge_requests", ["assignee_id"], :name => "index_merge_requests_on_assignee_id" | 86 | add_index "merge_requests", ["assignee_id"], :name => "index_merge_requests_on_assignee_id" |
89 | add_index "merge_requests", ["author_id"], :name => "index_merge_requests_on_author_id" | 87 | add_index "merge_requests", ["author_id"], :name => "index_merge_requests_on_author_id" |
90 | - add_index "merge_requests", ["closed"], :name => "index_merge_requests_on_closed" | ||
91 | add_index "merge_requests", ["created_at"], :name => "index_merge_requests_on_created_at" | 88 | add_index "merge_requests", ["created_at"], :name => "index_merge_requests_on_created_at" |
92 | add_index "merge_requests", ["milestone_id"], :name => "index_merge_requests_on_milestone_id" | 89 | add_index "merge_requests", ["milestone_id"], :name => "index_merge_requests_on_milestone_id" |
93 | add_index "merge_requests", ["project_id"], :name => "index_merge_requests_on_project_id" | 90 | add_index "merge_requests", ["project_id"], :name => "index_merge_requests_on_project_id" |
@@ -96,13 +93,13 @@ ActiveRecord::Schema.define(:version => 20130131070232) do | @@ -96,13 +93,13 @@ ActiveRecord::Schema.define(:version => 20130131070232) do | ||
96 | add_index "merge_requests", ["title"], :name => "index_merge_requests_on_title" | 93 | add_index "merge_requests", ["title"], :name => "index_merge_requests_on_title" |
97 | 94 | ||
98 | create_table "milestones", :force => true do |t| | 95 | create_table "milestones", :force => true do |t| |
99 | - t.string "title", :null => false | ||
100 | - t.integer "project_id", :null => false | 96 | + t.string "title", :null => false |
97 | + t.integer "project_id", :null => false | ||
101 | t.text "description" | 98 | t.text "description" |
102 | t.date "due_date" | 99 | t.date "due_date" |
103 | - t.boolean "closed", :default => false, :null => false | ||
104 | - t.datetime "created_at", :null => false | ||
105 | - t.datetime "updated_at", :null => false | 100 | + t.datetime "created_at", :null => false |
101 | + t.datetime "updated_at", :null => false | ||
102 | + t.string "state" | ||
106 | end | 103 | end |
107 | 104 | ||
108 | add_index "milestones", ["due_date"], :name => "index_milestones_on_due_date" | 105 | add_index "milestones", ["due_date"], :name => "index_milestones_on_due_date" |
doc/api/milestones.md
@@ -34,7 +34,6 @@ POST /projects/:id/milestones | @@ -34,7 +34,6 @@ POST /projects/:id/milestones | ||
34 | Parameters: | 34 | Parameters: |
35 | 35 | ||
36 | + `id` (required) - The ID of a project | 36 | + `id` (required) - The ID of a project |
37 | -+ `milestone_id` (required) - The ID of a project milestone | ||
38 | + `title` (required) - The title of an milestone | 37 | + `title` (required) - The title of an milestone |
39 | + `description` (optional) - The description of the milestone | 38 | + `description` (optional) - The description of the milestone |
40 | + `due_date` (optional) - The due date of the milestone | 39 | + `due_date` (optional) - The due date of the milestone |
doc/api/projects.md
@@ -23,7 +23,7 @@ GET /projects | @@ -23,7 +23,7 @@ GET /projects | ||
23 | "blocked": false, | 23 | "blocked": false, |
24 | "created_at": "2012-05-23T08:00:58Z" | 24 | "created_at": "2012-05-23T08:00:58Z" |
25 | }, | 25 | }, |
26 | - "private": true, | 26 | + "public": true, |
27 | "path": "rails", | 27 | "path": "rails", |
28 | "path_with_namespace": "rails/rails", | 28 | "path_with_namespace": "rails/rails", |
29 | "issues_enabled": false, | 29 | "issues_enabled": false, |
@@ -45,7 +45,7 @@ GET /projects | @@ -45,7 +45,7 @@ GET /projects | ||
45 | "blocked": false, | 45 | "blocked": false, |
46 | "created_at": "2012-05-23T08:00:58Z" | 46 | "created_at": "2012-05-23T08:00:58Z" |
47 | }, | 47 | }, |
48 | - "private": true, | 48 | + "public": true, |
49 | "path": "gitlab", | 49 | "path": "gitlab", |
50 | "path_with_namespace": "randx/gitlab", | 50 | "path_with_namespace": "randx/gitlab", |
51 | "issues_enabled": true, | 51 | "issues_enabled": true, |
@@ -89,7 +89,7 @@ Parameters: | @@ -89,7 +89,7 @@ Parameters: | ||
89 | "blocked": false, | 89 | "blocked": false, |
90 | "created_at": "2012-05-23T08:00:58Z" | 90 | "created_at": "2012-05-23T08:00:58Z" |
91 | }, | 91 | }, |
92 | - "private": true, | 92 | + "public": true, |
93 | "path": "gitlab", | 93 | "path": "gitlab", |
94 | "path_with_namespace": "randx/gitlab", | 94 | "path_with_namespace": "randx/gitlab", |
95 | "issues_enabled": true, | 95 | "issues_enabled": true, |
doc/install/databases.md
@@ -27,7 +27,7 @@ GitLab supports the following databases: | @@ -27,7 +27,7 @@ GitLab supports the following databases: | ||
27 | mysql> \q | 27 | mysql> \q |
28 | 28 | ||
29 | # Try connecting to the new database with the new user | 29 | # Try connecting to the new database with the new user |
30 | - sudo -u gitlab -H mysql -u gitlab -p -D gitlabhq_production | 30 | + sudo -u git -H mysql -u gitlab -p -D gitlabhq_production |
31 | 31 | ||
32 | ## PostgreSQL | 32 | ## PostgreSQL |
33 | 33 | ||
@@ -47,5 +47,5 @@ GitLab supports the following databases: | @@ -47,5 +47,5 @@ GitLab supports the following databases: | ||
47 | template1=# \q | 47 | template1=# \q |
48 | 48 | ||
49 | # Try connecting to the new database with the new user | 49 | # Try connecting to the new database with the new user |
50 | - sudo -u gitlab -H psql -d gitlabhq_production | 50 | + sudo -u git -H psql -d gitlabhq_production |
51 | 51 |
doc/install/installation.md
1 | This installation guide was created for Debian/Ubuntu and tested on it. | 1 | This installation guide was created for Debian/Ubuntu and tested on it. |
2 | 2 | ||
3 | -Please read `doc/install/requirements.md` for hardware and platform requirements. | 3 | +Please read [`doc/install/requirements.md`](./requirements.md) for hardware and platform requirements. |
4 | 4 | ||
5 | 5 | ||
6 | **Important Note:** | 6 | **Important Note:** |
@@ -8,12 +8,13 @@ The following steps have been known to work. | @@ -8,12 +8,13 @@ The following steps have been known to work. | ||
8 | If you deviate from this guide, do it with caution and make sure you don't | 8 | If you deviate from this guide, do it with caution and make sure you don't |
9 | violate any assumptions GitLab makes about its environment. | 9 | violate any assumptions GitLab makes about its environment. |
10 | For things like AWS installation scripts, init scripts or config files for | 10 | For things like AWS installation scripts, init scripts or config files for |
11 | -alternative web server have a look at the "Advanced Setup Tips" section. | 11 | +alternative web server have a look at the [`Advanced Setup |
12 | +Tips`](./installation.md#advanced-setup-tips) section. | ||
12 | 13 | ||
13 | 14 | ||
14 | **Important Note:** | 15 | **Important Note:** |
15 | If you find a bug/error in this guide please submit an issue or pull request | 16 | If you find a bug/error in this guide please submit an issue or pull request |
16 | -following the contribution guide (see `CONTRIBUTING.md`). | 17 | +following the [`contribution guide`](../../CONTRIBUTING.md). |
17 | 18 | ||
18 | - - - | 19 | - - - |
19 | 20 | ||
@@ -24,7 +25,7 @@ The GitLab installation consists of setting up the following components: | @@ -24,7 +25,7 @@ The GitLab installation consists of setting up the following components: | ||
24 | 1. Packages / Dependencies | 25 | 1. Packages / Dependencies |
25 | 2. Ruby | 26 | 2. Ruby |
26 | 3. System Users | 27 | 3. System Users |
27 | -4. Gitolite | 28 | +4. GitLab shell |
28 | 5. Database | 29 | 5. Database |
29 | 6. GitLab | 30 | 6. GitLab |
30 | 7. Nginx | 31 | 7. Nginx |
@@ -32,16 +33,13 @@ The GitLab installation consists of setting up the following components: | @@ -32,16 +33,13 @@ The GitLab installation consists of setting up the following components: | ||
32 | 33 | ||
33 | # 1. Packages / Dependencies | 34 | # 1. Packages / Dependencies |
34 | 35 | ||
35 | -`sudo` is not installed on Debian by default. If you don't have it you'll need | ||
36 | -to install it first. | 36 | +`sudo` is not installed on Debian by default. Make sure your system is |
37 | +up-to-date and install it. | ||
37 | 38 | ||
38 | # run as root | 39 | # run as root |
39 | - apt-get update && apt-get upgrade && apt-get install sudo | ||
40 | - | ||
41 | -Make sure your system is up-to-date: | ||
42 | - | ||
43 | - sudo apt-get update | ||
44 | - sudo apt-get upgrade | 40 | + apt-get update |
41 | + apt-get upgrade | ||
42 | + apt-get install sudo | ||
45 | 43 | ||
46 | **Note:** | 44 | **Note:** |
47 | Vim is an editor that is used here whenever there are files that need to be | 45 | Vim is an editor that is used here whenever there are files that need to be |
@@ -96,25 +94,24 @@ Create a `git` user for Gitlab: | @@ -96,25 +94,24 @@ Create a `git` user for Gitlab: | ||
96 | 94 | ||
97 | # 4. GitLab shell | 95 | # 4. GitLab shell |
98 | 96 | ||
99 | - # login as git | 97 | + # Login as git |
100 | sudo su git | 98 | sudo su git |
101 | 99 | ||
102 | - # go to home directory | 100 | + # Go to home directory |
103 | cd /home/git | 101 | cd /home/git |
104 | 102 | ||
105 | - # clone gitlab shell | 103 | + # Clone gitlab shell |
106 | git clone https://github.com/gitlabhq/gitlab-shell.git | 104 | git clone https://github.com/gitlabhq/gitlab-shell.git |
107 | 105 | ||
108 | - # setup | 106 | + # Setup |
109 | cd gitlab-shell | 107 | cd gitlab-shell |
110 | cp config.yml.example config.yml | 108 | cp config.yml.example config.yml |
111 | ./bin/install | 109 | ./bin/install |
112 | 110 | ||
113 | 111 | ||
114 | - | ||
115 | # 5. Database | 112 | # 5. Database |
116 | 113 | ||
117 | -To setup the MySQL/PostgreSQL database and dependencies please see [`doc/install/databases.md`](./databases.md) . | 114 | +To setup the MySQL/PostgreSQL database and dependencies please see [`doc/install/databases.md`](./databases.md). |
118 | 115 | ||
119 | 116 | ||
120 | # 6. GitLab | 117 | # 6. GitLab |
@@ -154,9 +151,13 @@ do so with caution! | @@ -154,9 +151,13 @@ do so with caution! | ||
154 | sudo chmod -R u+rwX log/ | 151 | sudo chmod -R u+rwX log/ |
155 | sudo chmod -R u+rwX tmp/ | 152 | sudo chmod -R u+rwX tmp/ |
156 | 153 | ||
157 | - # Make directory for satellites | 154 | + # Create directory for satellites |
158 | sudo -u git -H mkdir /home/git/gitlab-satellites | 155 | sudo -u git -H mkdir /home/git/gitlab-satellites |
159 | 156 | ||
157 | + # Create directory for pids and make sure GitLab can write to it | ||
158 | + sudo -u git -H mkdir tmp/pids/ | ||
159 | + sudo chmod -R u+rwX tmp/pids/ | ||
160 | + | ||
160 | # Copy the example Unicorn config | 161 | # Copy the example Unicorn config |
161 | sudo -u git -H cp config/unicorn.rb.example config/unicorn.rb | 162 | sudo -u git -H cp config/unicorn.rb.example config/unicorn.rb |
162 | 163 | ||
@@ -187,7 +188,9 @@ Make sure to update username/password in config/database.yml. | @@ -187,7 +188,9 @@ Make sure to update username/password in config/database.yml. | ||
187 | 188 | ||
188 | 189 | ||
189 | ## Initialise Database and Activate Advanced Features | 190 | ## Initialise Database and Activate Advanced Features |
190 | - | 191 | + |
192 | + sudo -u git -H bundle exec rake db:setup RAILS_ENV=production | ||
193 | + sudo -u git -H bundle exec rake db:seed_fu RAILS_ENV=production | ||
191 | sudo -u git -H bundle exec rake gitlab:setup RAILS_ENV=production | 194 | sudo -u git -H bundle exec rake gitlab:setup RAILS_ENV=production |
192 | 195 | ||
193 | 196 | ||
@@ -205,7 +208,7 @@ Make GitLab start on boot: | @@ -205,7 +208,7 @@ Make GitLab start on boot: | ||
205 | 208 | ||
206 | ## Check Application Status | 209 | ## Check Application Status |
207 | 210 | ||
208 | -Check if GitLab and its environment is configured correctly: | 211 | +Check if GitLab and its environment are configured correctly: |
209 | 212 | ||
210 | sudo -u git -H bundle exec rake gitlab:env:info RAILS_ENV=production | 213 | sudo -u git -H bundle exec rake gitlab:env:info RAILS_ENV=production |
211 | 214 | ||
@@ -227,7 +230,7 @@ However there are still a few steps left. | @@ -227,7 +230,7 @@ However there are still a few steps left. | ||
227 | 230 | ||
228 | **Note:** | 231 | **Note:** |
229 | If you can't or don't want to use Nginx as your web server, have a look at the | 232 | If you can't or don't want to use Nginx as your web server, have a look at the |
230 | -"Advanced Setup Tips" section. | 233 | +[`Advanced Setup Tips`](./installation.md#advanced-setup-tips) section. |
231 | 234 | ||
232 | ## Installation | 235 | ## Installation |
233 | sudo apt-get install nginx | 236 | sudo apt-get install nginx |
@@ -244,11 +247,11 @@ Make sure to edit the config file to match your setup: | @@ -244,11 +247,11 @@ Make sure to edit the config file to match your setup: | ||
244 | # Change **YOUR_SERVER_IP** and **YOUR_SERVER_FQDN** | 247 | # Change **YOUR_SERVER_IP** and **YOUR_SERVER_FQDN** |
245 | # to the IP address and fully-qualified domain name | 248 | # to the IP address and fully-qualified domain name |
246 | # of your host serving GitLab | 249 | # of your host serving GitLab |
247 | - sudo vim /etc/nginx/sites-enabled/gitlab | 250 | + sudo vim /etc/nginx/sites-available/gitlab |
248 | 251 | ||
249 | ## Restart | 252 | ## Restart |
250 | 253 | ||
251 | - sudo /etc/init.d/nginx restart | 254 | + sudo service nginx restart |
252 | 255 | ||
253 | 256 | ||
254 | # Done! | 257 | # Done! |
@@ -282,7 +285,7 @@ a different host, you can configure its connection string via the | @@ -282,7 +285,7 @@ a different host, you can configure its connection string via the | ||
282 | 285 | ||
283 | ## Custom SSH Connection | 286 | ## Custom SSH Connection |
284 | 287 | ||
285 | -If you are running SSH on a non-standard port, you must change the gitlab user'S SSH config. | 288 | +If you are running SSH on a non-standard port, you must change the gitlab user's SSH config. |
286 | 289 | ||
287 | # Add to /home/git/.ssh/config | 290 | # Add to /home/git/.ssh/config |
288 | host localhost # Give your setup a name (here: override localhost) | 291 | host localhost # Give your setup a name (here: override localhost) |