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 | 2 | .rbx/ |
3 | 3 | db/*.sqlite3 |
4 | 4 | db/*.sqlite3-journal |
5 | -log/*.log | |
5 | +log/*.log* | |
6 | 6 | tmp/ |
7 | 7 | .sass-cache/ |
8 | 8 | coverage/* |
... | ... | @@ -20,6 +20,7 @@ config/database.yml |
20 | 20 | config/initializers/omniauth.rb |
21 | 21 | config/unicorn.rb |
22 | 22 | config/resque.yml |
23 | +config/aws.yml | |
23 | 24 | db/data.yml |
24 | 25 | .idea |
25 | 26 | .DS_Store | ... | ... |
Gemfile
Gemfile.lock
... | ... | @@ -425,6 +425,7 @@ GEM |
425 | 425 | rack (~> 1.0) |
426 | 426 | tilt (~> 1.1, != 1.3.0) |
427 | 427 | stamp (0.3.0) |
428 | + state_machine (1.1.2) | |
428 | 429 | temple (0.5.5) |
429 | 430 | test_after_commit (0.0.1) |
430 | 431 | therubyracer (0.10.2) |
... | ... | @@ -536,6 +537,7 @@ DEPENDENCIES |
536 | 537 | slim |
537 | 538 | spinach-rails |
538 | 539 | stamp |
540 | + state_machine | |
539 | 541 | test_after_commit |
540 | 542 | therubyracer |
541 | 543 | thin | ... | ... |
app/assets/javascripts/main.js.coffee
... | ... | @@ -49,6 +49,10 @@ $ -> |
49 | 49 | # Bottom tooltip |
50 | 50 | $('.has_bottom_tooltip').tooltip(placement: 'bottom') |
51 | 51 | |
52 | + # Form submitter | |
53 | + $('.trigger-submit').on 'change', -> | |
54 | + $(@).parents('form').submit() | |
55 | + | |
52 | 56 | # Flash |
53 | 57 | if (flash = $("#flash-container")).length > 0 |
54 | 58 | flash.click -> $(@).slideUp("slow") | ... | ... |
app/assets/javascripts/merge_requests.js.coffee
... | ... | @@ -27,7 +27,7 @@ class MergeRequest |
27 | 27 | this.$el.find(selector) |
28 | 28 | |
29 | 29 | initMergeWidget: -> |
30 | - this.showState( @opts.current_state ) | |
30 | + this.showState( @opts.current_status ) | |
31 | 31 | |
32 | 32 | if this.$('.automerge_widget').length and @opts.check_enable |
33 | 33 | $.get @opts.url_to_automerge_check, (data) => | ... | ... |
app/assets/stylesheets/gitlab_bootstrap/mixins.scss
app/assets/stylesheets/sections/commits.scss
... | ... | @@ -29,7 +29,7 @@ |
29 | 29 | a{ |
30 | 30 | color: $style_color; |
31 | 31 | } |
32 | - | |
32 | + | |
33 | 33 | > span { |
34 | 34 | font-family: $monospace_font; |
35 | 35 | font-size: 14px; |
... | ... | @@ -124,7 +124,7 @@ |
124 | 124 | .wrap{ |
125 | 125 | display: inline-block; |
126 | 126 | } |
127 | - | |
127 | + | |
128 | 128 | .frame { |
129 | 129 | display: inline-block; |
130 | 130 | background-color: #fff; |
... | ... | @@ -149,7 +149,7 @@ |
149 | 149 | |
150 | 150 | .view.swipe{ |
151 | 151 | position: relative; |
152 | - | |
152 | + | |
153 | 153 | .swipe-frame{ |
154 | 154 | display: block; |
155 | 155 | margin: auto; |
... | ... | @@ -228,7 +228,7 @@ |
228 | 228 | bottom: 0px; |
229 | 229 | left: 50%; |
230 | 230 | margin-left: -150px; |
231 | - | |
231 | + | |
232 | 232 | .drag-track{ |
233 | 233 | display: block; |
234 | 234 | position: absolute; |
... | ... | @@ -237,7 +237,7 @@ |
237 | 237 | width: 276px; |
238 | 238 | background: url('onion_skin_sprites.gif') -4px -20px repeat-x; |
239 | 239 | } |
240 | - | |
240 | + | |
241 | 241 | .dragger { |
242 | 242 | display: block; |
243 | 243 | position: absolute; |
... | ... | @@ -248,7 +248,7 @@ |
248 | 248 | background: url('onion_skin_sprites.gif') 0px -34px repeat-x; |
249 | 249 | cursor: pointer; |
250 | 250 | } |
251 | - | |
251 | + | |
252 | 252 | .transparent { |
253 | 253 | display: block; |
254 | 254 | position: absolute; |
... | ... | @@ -258,7 +258,7 @@ |
258 | 258 | width: 10px; |
259 | 259 | background: url('onion_skin_sprites.gif') -2px 0px no-repeat; |
260 | 260 | } |
261 | - | |
261 | + | |
262 | 262 | .opaque { |
263 | 263 | display: block; |
264 | 264 | position: absolute; |
... | ... | @@ -275,19 +275,19 @@ |
275 | 275 | |
276 | 276 | padding: 10px; |
277 | 277 | text-align: center; |
278 | - | |
278 | + | |
279 | 279 | background-image: -webkit-gradient(linear, 0 0, 0 30, color-stop(0.066, #eee), to(#dfdfdf)); |
280 | 280 | background-image: -webkit-linear-gradient(#eee 6.6%, #dfdfdf); |
281 | 281 | background-image: -moz-linear-gradient(#eee 6.6%, #dfdfdf); |
282 | 282 | background-image: -o-linear-gradient(#eee 6.6%, #dfdfdf); |
283 | - | |
283 | + | |
284 | 284 | ul, li{ |
285 | 285 | list-style: none; |
286 | 286 | margin: 0; |
287 | 287 | padding: 0; |
288 | 288 | display: inline-block; |
289 | 289 | } |
290 | - | |
290 | + | |
291 | 291 | li{ |
292 | 292 | color: grey; |
293 | 293 | border-left: 1px solid #c1c1c1; |
... | ... | @@ -322,12 +322,12 @@ |
322 | 322 | } |
323 | 323 | .commit-author, .commit-committer{ |
324 | 324 | display: block; |
325 | - color: #999; | |
326 | - font-weight: normal; | |
325 | + color: #999; | |
326 | + font-weight: normal; | |
327 | 327 | font-style: italic; |
328 | 328 | } |
329 | 329 | .commit-author strong, .commit-committer strong{ |
330 | - font-weight: bold; | |
330 | + font-weight: bold; | |
331 | 331 | font-style: normal; |
332 | 332 | } |
333 | 333 | |
... | ... | @@ -337,7 +337,6 @@ |
337 | 337 | */ |
338 | 338 | .commit { |
339 | 339 | .browse_code_link_holder { |
340 | - @extend .span2; | |
341 | 340 | float: right; |
342 | 341 | } |
343 | 342 | ... | ... |
app/assets/stylesheets/sections/header.scss
... | ... | @@ -5,15 +5,16 @@ |
5 | 5 | header { |
6 | 6 | &.navbar-gitlab { |
7 | 7 | .navbar-inner { |
8 | - height: 45px; | |
9 | - padding: 5px; | |
8 | + height: 40px; | |
9 | + padding: 3px; | |
10 | 10 | background: #F1F1F1; |
11 | + filter: none; | |
11 | 12 | |
12 | 13 | .nav > li > a { |
13 | 14 | color: $style_color; |
14 | 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 | 20 | /** NAV block with links and profile **/ |
... | ... | @@ -25,7 +26,6 @@ header { |
25 | 26 | } |
26 | 27 | |
27 | 28 | z-index: 10; |
28 | - /*height: 60px;*/ | |
29 | 29 | |
30 | 30 | /** |
31 | 31 | * |
... | ... | @@ -34,7 +34,7 @@ header { |
34 | 34 | */ |
35 | 35 | .app_logo { |
36 | 36 | float: left; |
37 | - margin-right: 15px; | |
37 | + margin-right: 9px; | |
38 | 38 | position: relative; |
39 | 39 | top: -5px; |
40 | 40 | padding-top: 5px; |
... | ... | @@ -42,10 +42,10 @@ header { |
42 | 42 | a { |
43 | 43 | float: left; |
44 | 44 | padding: 0px; |
45 | - margin: 0 10px; | |
45 | + margin: 0 6px; | |
46 | 46 | |
47 | 47 | h1 { |
48 | - background: url('logo_dark.png') no-repeat 0px 2px; | |
48 | + background: url('logo_dark.png') no-repeat center 1px; | |
49 | 49 | float: left; |
50 | 50 | height: 40px; |
51 | 51 | width: 40px; |
... | ... | @@ -79,7 +79,6 @@ header { |
79 | 79 | .search { |
80 | 80 | margin-right: 45px; |
81 | 81 | margin-left: 10px; |
82 | - margin-top: 2px; | |
83 | 82 | |
84 | 83 | .search-input { |
85 | 84 | @extend .span2; |
... | ... | @@ -105,7 +104,7 @@ header { |
105 | 104 | .account-box { |
106 | 105 | position: absolute; |
107 | 106 | right: 0; |
108 | - top: 6px; | |
107 | + top: 4px; | |
109 | 108 | z-index: 10000; |
110 | 109 | width: 128px; |
111 | 110 | font-size: 11px; |
... | ... | @@ -228,6 +227,7 @@ header { |
228 | 227 | .search-input { |
229 | 228 | background-color: #D2D5DA; |
230 | 229 | background-color: rgba(255, 255, 255, 0.5); |
230 | + border: 1px solid #AAA; | |
231 | 231 | |
232 | 232 | &:focus { |
233 | 233 | background-color: white; |
... | ... | @@ -240,13 +240,16 @@ header { |
240 | 240 | .app_logo { |
241 | 241 | a { |
242 | 242 | h1 { |
243 | - background: url('logo_white.png') no-repeat center center; | |
243 | + background: url('logo_white.png') no-repeat center 1px; | |
244 | 244 | color: #fff; |
245 | 245 | text-shadow: 0 1px 1px #111; |
246 | 246 | } |
247 | 247 | } |
248 | 248 | } |
249 | 249 | .project_name { |
250 | + a { | |
251 | + color: #FFF; | |
252 | + } | |
250 | 253 | color: #fff; |
251 | 254 | text-shadow: 0 1px 1px #111; |
252 | 255 | } |
... | ... | @@ -261,11 +264,11 @@ header { |
261 | 264 | |
262 | 265 | .separator { |
263 | 266 | float: left; |
264 | - height: 60px; | |
267 | + height: 46px; | |
265 | 268 | width: 1px; |
266 | 269 | background: white; |
267 | 270 | border-left: 1px solid #DDD; |
268 | - margin-top: -10px; | |
271 | + margin-top: -3px; | |
269 | 272 | margin-left: 10px; |
270 | 273 | margin-right: 10px; |
271 | 274 | } | ... | ... |
app/assets/stylesheets/sections/projects.scss
app/assets/stylesheets/themes/ui_mars.scss
... | ... | @@ -8,66 +8,27 @@ |
8 | 8 | * |
9 | 9 | */ |
10 | 10 | .ui_mars { |
11 | - | |
12 | 11 | /* |
13 | 12 | * Application Header |
14 | 13 | * |
15 | 14 | */ |
16 | 15 | header { |
17 | - | |
16 | + @extend .header-dark; | |
18 | 17 | &.navbar-gitlab { |
19 | 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 | 14 | end |
15 | 15 | |
16 | 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 | 19 | # Filter by specific assignee_id (or lack thereof)? |
20 | 20 | if params[:assignee_id].present? | ... | ... |
app/contexts/projects/create_context.rb
... | ... | @@ -38,6 +38,8 @@ module Projects |
38 | 38 | if @project.valid? && @project.import_url.present? |
39 | 39 | shell = Gitlab::Shell.new |
40 | 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 | 43 | true |
42 | 44 | else |
43 | 45 | @project.errors.add(:import_url, 'cannot clone repo') | ... | ... |
app/controllers/dashboard_controller.rb
... | ... | @@ -5,7 +5,7 @@ class DashboardController < ApplicationController |
5 | 5 | before_filter :event_filter, only: :show |
6 | 6 | |
7 | 7 | def show |
8 | - @groups = current_user.authorized_groups | |
8 | + @groups = current_user.authorized_groups.sort_by(&:human_name) | |
9 | 9 | @has_authorized_projects = @projects.count > 0 |
10 | 10 | @teams = current_user.authorized_teams |
11 | 11 | @projects_count = @projects.count | ... | ... |
... | ... | @@ -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 | 73 | if @merge_request.unchecked? |
74 | 74 | @merge_request.check_if_can_be_merged |
75 | 75 | end |
76 | - render json: {state: @merge_request.human_state} | |
76 | + render json: {merge_status: @merge_request.human_merge_status} | |
77 | 77 | rescue Gitlab::SatelliteNotExistError |
78 | - render json: {state: :no_satellite} | |
78 | + render json: {merge_status: :no_satellite} | |
79 | 79 | end |
80 | 80 | |
81 | 81 | def automerge |
82 | 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 | 84 | @merge_request.should_remove_source_branch = params[:should_remove_source_branch] |
85 | 85 | @merge_request.automerge!(current_user) |
86 | 86 | @status = true | ... | ... |
app/controllers/milestones_controller.rb
... | ... | @@ -12,7 +12,7 @@ class MilestonesController < ProjectResourceController |
12 | 12 | |
13 | 13 | def index |
14 | 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 | 16 | when 'closed'; @project.milestones.closed.order("due_date DESC") |
17 | 17 | else @project.milestones.active.order("due_date ASC") |
18 | 18 | end | ... | ... |
app/controllers/profiles_controller.rb
... | ... | @@ -51,7 +51,9 @@ class ProfilesController < ApplicationController |
51 | 51 | end |
52 | 52 | |
53 | 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 | 58 | respond_to do |format| |
57 | 59 | format.js | ... | ... |
app/controllers/team_members_controller.rb
... | ... | @@ -4,7 +4,11 @@ class TeamMembersController < ProjectResourceController |
4 | 4 | before_filter :authorize_admin_project!, except: [:index, :show] |
5 | 5 | |
6 | 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 | 12 | end |
9 | 13 | |
10 | 14 | def show | ... | ... |
app/controllers/teams/members_controller.rb
... | ... | @@ -27,7 +27,13 @@ class Teams::MembersController < Teams::ApplicationController |
27 | 27 | end |
28 | 28 | |
29 | 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 | 37 | if user_team.update_membership(team_member, options) |
32 | 38 | redirect_to team_members_path(user_team), notice: "Membership for #{team_member.name} was successfully updated in Team of users." |
33 | 39 | else |
... | ... | @@ -45,5 +51,4 @@ class Teams::MembersController < Teams::ApplicationController |
45 | 51 | def team_member |
46 | 52 | @member ||= user_team.members.find_by_username(params[:id]) |
47 | 53 | end |
48 | - | |
49 | 54 | end | ... | ... |
app/controllers/teams_controller.rb
... | ... | @@ -9,13 +9,11 @@ class TeamsController < ApplicationController |
9 | 9 | layout 'user_team', except: [:new, :create] |
10 | 10 | |
11 | 11 | def show |
12 | - user_team | |
13 | 12 | projects |
14 | 13 | @events = Event.in_projects(user_team.project_ids).limit(20).offset(params[:offset] || 0) |
15 | 14 | end |
16 | 15 | |
17 | 16 | def edit |
18 | - user_team | |
19 | 17 | end |
20 | 18 | |
21 | 19 | def update |
... | ... | @@ -41,6 +39,9 @@ class TeamsController < ApplicationController |
41 | 39 | @team.path = @team.name.dup.parameterize if @team.name |
42 | 40 | |
43 | 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 | 45 | redirect_to team_path(@team) |
45 | 46 | else |
46 | 47 | render action: :new | ... | ... |
app/helpers/application_helper.rb
... | ... | @@ -73,8 +73,8 @@ module ApplicationHelper |
73 | 73 | |
74 | 74 | def search_autocomplete_source |
75 | 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 | 79 | default_nav = [ |
80 | 80 | { label: "My Profile", url: profile_path }, |
... | ... | @@ -159,8 +159,13 @@ module ApplicationHelper |
159 | 159 | alt: "Sign in with #{provider.to_s.titleize}") |
160 | 160 | end |
161 | 161 | |
162 | + def simple_sanitize str | |
163 | + sanitize(str, tags: %w(a span)) | |
164 | + end | |
165 | + | |
162 | 166 | def image_url(source) |
163 | 167 | root_url + path_to_image(source) |
164 | 168 | end |
169 | + | |
165 | 170 | alias_method :url_to_image, :image_url |
166 | 171 | end | ... | ... |
app/helpers/dashboard_helper.rb
app/helpers/issues_helper.rb
app/helpers/merge_requests_helper.rb
app/helpers/namespaces_helper.rb
... | ... | @@ -10,8 +10,8 @@ module NamespacesHelper |
10 | 10 | |
11 | 11 | |
12 | 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 | 16 | options = [] |
17 | 17 | options << global_opts if current_user.admin | ... | ... |
app/helpers/projects_helper.rb
1 | 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 | 2 | def remove_from_project_team_message(project, user) |
11 | 3 | "You are going to remove #{user.name} from #{project.name} project team. Are you sure?" |
12 | 4 | end |
... | ... | @@ -56,7 +48,7 @@ module ProjectsHelper |
56 | 48 | def project_title project |
57 | 49 | if project.group |
58 | 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 | 52 | end |
61 | 53 | else |
62 | 54 | project.name | ... | ... |
app/models/ability.rb
... | ... | @@ -123,7 +123,7 @@ class Ability |
123 | 123 | def user_team_abilities user, team |
124 | 124 | rules = [] |
125 | 125 | |
126 | - # Only group owner and administrators can manage group | |
126 | + # Only group owner and administrators can manage team | |
127 | 127 | if team.owner == user || team.admin?(user) || user.admin? |
128 | 128 | rules << [ :manage_user_team ] |
129 | 129 | end | ... | ... |
app/models/concerns/issuable.rb
... | ... | @@ -17,10 +17,9 @@ module Issuable |
17 | 17 | validates :project, presence: true |
18 | 18 | validates :author, presence: true |
19 | 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 | 23 | scope :of_group, ->(group) { where(project_id: group.project_ids) } |
25 | 24 | scope :of_user_team, ->(team) { where(project_id: team.project_ids, assignee_id: team.member_ids) } |
26 | 25 | scope :assigned, ->(u) { where(assignee_id: u.id)} |
... | ... | @@ -62,14 +61,6 @@ module Issuable |
62 | 61 | assignee_id_changed? |
63 | 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 | 65 | # Votes |
75 | 66 | # | ... | ... |
app/models/event.rb
app/models/issue.rb
... | ... | @@ -9,7 +9,7 @@ |
9 | 9 | # project_id :integer |
10 | 10 | # created_at :datetime not null |
11 | 11 | # updated_at :datetime not null |
12 | -# closed :boolean default(FALSE), not null | |
12 | +# state :string default(FALSE), not null | |
13 | 13 | # position :integer default(0) |
14 | 14 | # branch_name :string(255) |
15 | 15 | # description :text |
... | ... | @@ -19,12 +19,35 @@ |
19 | 19 | class Issue < ActiveRecord::Base |
20 | 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 | 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 | 52 | end |
30 | 53 | end | ... | ... |
app/models/key.rb
... | ... | @@ -35,7 +35,7 @@ class Key < ActiveRecord::Base |
35 | 35 | |
36 | 36 | def fingerprintable_key |
37 | 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 | 39 | file = Tempfile.new('key_file') |
40 | 40 | begin |
41 | 41 | file.puts key |
... | ... | @@ -45,7 +45,7 @@ class Key < ActiveRecord::Base |
45 | 45 | file.close |
46 | 46 | file.unlink # deletes the temp file |
47 | 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 | 49 | end |
50 | 50 | |
51 | 51 | def set_identifier | ... | ... |
app/models/merge_request.rb
... | ... | @@ -9,15 +9,14 @@ |
9 | 9 | # author_id :integer |
10 | 10 | # assignee_id :integer |
11 | 11 | # title :string(255) |
12 | -# closed :boolean default(FALSE), not null | |
12 | +# state :string(255) not null | |
13 | 13 | # created_at :datetime not null |
14 | 14 | # updated_at :datetime not null |
15 | 15 | # st_commits :text(2147483647) |
16 | 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 | 21 | require Rails.root.join("app/models/commit") |
23 | 22 | require Rails.root.join("lib/static_model") |
... | ... | @@ -25,11 +24,33 @@ require Rails.root.join("lib/static_model") |
25 | 24 | class MergeRequest < ActiveRecord::Base |
26 | 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 | 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 | 54 | BROKEN_DIFF = "--broken-diff" |
34 | 55 | |
35 | 56 | UNCHECKED = 1 |
... | ... | @@ -43,21 +64,33 @@ class MergeRequest < ActiveRecord::Base |
43 | 64 | validates :target_branch, presence: true |
44 | 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 | 85 | end |
53 | 86 | |
54 | - def human_state | |
55 | - states = { | |
87 | + def human_merge_status | |
88 | + merge_statuses = { | |
56 | 89 | CAN_BE_MERGED => "can_be_merged", |
57 | 90 | CANNOT_BE_MERGED => "cannot_be_merged", |
58 | 91 | UNCHECKED => "unchecked" |
59 | 92 | } |
60 | - states[self.state] | |
93 | + merge_statuses[self.merge_status] | |
61 | 94 | end |
62 | 95 | |
63 | 96 | def validate_branches |
... | ... | @@ -72,20 +105,20 @@ class MergeRequest < ActiveRecord::Base |
72 | 105 | end |
73 | 106 | |
74 | 107 | def unchecked? |
75 | - state == UNCHECKED | |
108 | + merge_status == UNCHECKED | |
76 | 109 | end |
77 | 110 | |
78 | 111 | def mark_as_unchecked |
79 | - self.state = UNCHECKED | |
112 | + self.merge_status = UNCHECKED | |
80 | 113 | self.save |
81 | 114 | end |
82 | 115 | |
83 | 116 | def can_be_merged? |
84 | - state == CAN_BE_MERGED | |
117 | + merge_status == CAN_BE_MERGED | |
85 | 118 | end |
86 | 119 | |
87 | 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 | 122 | CAN_BE_MERGED |
90 | 123 | else |
91 | 124 | CANNOT_BE_MERGED |
... | ... | @@ -98,7 +131,7 @@ class MergeRequest < ActiveRecord::Base |
98 | 131 | end |
99 | 132 | |
100 | 133 | def reloaded_diffs |
101 | - if open? && unmerged_diffs.any? | |
134 | + if opened? && unmerged_diffs.any? | |
102 | 135 | self.st_diffs = unmerged_diffs |
103 | 136 | self.save |
104 | 137 | end |
... | ... | @@ -128,10 +161,6 @@ class MergeRequest < ActiveRecord::Base |
128 | 161 | commits.first |
129 | 162 | end |
130 | 163 | |
131 | - def merged? | |
132 | - merged && merge_event | |
133 | - end | |
134 | - | |
135 | 164 | def merge_event |
136 | 165 | self.project.events.where(target_id: self.id, target_type: "MergeRequest", action: Event::MERGED).last |
137 | 166 | end |
... | ... | @@ -146,26 +175,16 @@ class MergeRequest < ActiveRecord::Base |
146 | 175 | |
147 | 176 | def probably_merged? |
148 | 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 | 179 | end |
161 | 180 | |
162 | 181 | def mark_as_unmergable |
163 | - self.state = CANNOT_BE_MERGED | |
182 | + self.merge_status = CANNOT_BE_MERGED | |
164 | 183 | self.save |
165 | 184 | end |
166 | 185 | |
167 | 186 | def reloaded_commits |
168 | - if open? && unmerged_commits.any? | |
187 | + if opened? && unmerged_commits.any? | |
169 | 188 | self.st_commits = unmerged_commits |
170 | 189 | save |
171 | 190 | end |
... | ... | @@ -181,7 +200,8 @@ class MergeRequest < ActiveRecord::Base |
181 | 200 | end |
182 | 201 | |
183 | 202 | def merge!(user_id) |
184 | - self.mark_as_merged! | |
203 | + self.merge | |
204 | + | |
185 | 205 | Event.create( |
186 | 206 | project: self.project, |
187 | 207 | action: Event::MERGED, | ... | ... |
app/models/milestone.rb
... | ... | @@ -13,19 +13,32 @@ |
13 | 13 | # |
14 | 14 | |
15 | 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 | 17 | attr_accessor :author_id_of_changes |
18 | 18 | |
19 | 19 | belongs_to :project |
20 | 20 | has_many :issues |
21 | 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 | 26 | validates :title, presence: true |
27 | 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 | 43 | def expired? |
31 | 44 | if due_date |
... | ... | @@ -68,17 +81,13 @@ class Milestone < ActiveRecord::Base |
68 | 81 | end |
69 | 82 | |
70 | 83 | def can_be_closed? |
71 | - open? && issues.opened.count.zero? | |
84 | + active? && issues.opened.count.zero? | |
72 | 85 | end |
73 | 86 | |
74 | 87 | def is_empty? |
75 | 88 | total_items_count.zero? |
76 | 89 | end |
77 | 90 | |
78 | - def open? | |
79 | - !closed | |
80 | - end | |
81 | - | |
82 | 91 | def author_id |
83 | 92 | author_id_of_changes |
84 | 93 | end | ... | ... |
app/models/namespace.rb
... | ... | @@ -17,11 +17,15 @@ class Namespace < ActiveRecord::Base |
17 | 17 | has_many :projects, dependent: :destroy |
18 | 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 | 26 | validates :path, uniqueness: true, presence: true, length: { within: 1..255 }, |
22 | 27 | format: { with: Gitlab::Regex.path_regex, |
23 | 28 | message: "only letters, digits & '_' '-' '.' allowed. Letter should be first" } |
24 | - validates :owner, presence: true | |
25 | 29 | |
26 | 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 | 43 | |
44 | 44 | has_many :events, dependent: :destroy |
45 | 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 | 47 | has_many :milestones, dependent: :destroy |
48 | 48 | has_many :users_projects, dependent: :destroy |
49 | 49 | has_many :notes, dependent: :destroy |
... | ... | @@ -146,7 +146,7 @@ class Project < ActiveRecord::Base |
146 | 146 | end |
147 | 147 | |
148 | 148 | def saved? |
149 | - id && valid? | |
149 | + id && persisted? | |
150 | 150 | end |
151 | 151 | |
152 | 152 | def import? | ... | ... |
app/models/repository.rb
... | ... | @@ -132,16 +132,16 @@ class Repository |
132 | 132 | return nil unless commit |
133 | 133 | |
134 | 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 | 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 | 139 | # Put files into a directory before archiving |
140 | 140 | prefix = self.path_with_namespace + "/" |
141 | 141 | |
142 | 142 | # Create file if not exists |
143 | 143 | unless File.exists?(file_path) |
144 | - FileUtils.mkdir_p storage_path | |
144 | + FileUtils.mkdir_p File.dirname(file_path) | |
145 | 145 | file = self.repo.archive_to_file(ref, prefix, file_path) |
146 | 146 | end |
147 | 147 | ... | ... |
app/models/user.rb
... | ... | @@ -234,8 +234,12 @@ class User < ActiveRecord::Base |
234 | 234 | keys.count == 0 |
235 | 235 | end |
236 | 236 | |
237 | + def can_change_username? | |
238 | + Gitlab.config.gitlab.username_changing_enabled | |
239 | + end | |
240 | + | |
237 | 241 | def can_create_project? |
238 | - projects_limit > personal_projects.count | |
242 | + projects_limit > owned_projects.count | |
239 | 243 | end |
240 | 244 | |
241 | 245 | def can_create_group? |
... | ... | @@ -263,7 +267,7 @@ class User < ActiveRecord::Base |
263 | 267 | end |
264 | 268 | |
265 | 269 | def cared_merge_requests |
266 | - MergeRequest.where("author_id = :id or assignee_id = :id", id: self.id) | |
270 | + MergeRequest.cared(self) | |
267 | 271 | end |
268 | 272 | |
269 | 273 | # Remove user from all projects and | ... | ... |
app/models/user_team.rb
... | ... | @@ -21,8 +21,11 @@ class UserTeam < ActiveRecord::Base |
21 | 21 | has_many :projects, through: :user_team_project_relationships |
22 | 22 | has_many :members, through: :user_team_user_relationships, source: :user |
23 | 23 | |
24 | - validates :name, presence: true, uniqueness: true | |
25 | 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 | 29 | validates :path, uniqueness: true, presence: true, length: { within: 1..255 }, |
27 | 30 | format: { with: Gitlab::Regex.path_regex, |
28 | 31 | message: "only letters, digits & '_' '-' '.' allowed. Letter should be first" } | ... | ... |
app/models/user_team_project_relationship.rb
app/observers/activity_observer.rb
... | ... | @@ -20,15 +20,23 @@ class ActivityObserver < ActiveRecord::Observer |
20 | 20 | end |
21 | 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 | 24 | Event.create( |
26 | 25 | project: record.project, |
27 | 26 | target_id: record.id, |
28 | 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 | 39 | author_id: record.author_id_of_changes |
31 | 40 | ) |
32 | - end | |
33 | 41 | end |
34 | 42 | end | ... | ... |
app/observers/issue_observer.rb
... | ... | @@ -7,22 +7,31 @@ class IssueObserver < ActiveRecord::Observer |
7 | 7 | end |
8 | 8 | end |
9 | 9 | |
10 | - def after_update(issue) | |
10 | + def after_close(issue, transition) | |
11 | 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 | 24 | end |
23 | 25 | |
24 | 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 | 35 | def send_reassigned_email(issue) |
27 | 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 | 7 | end |
8 | 8 | end |
9 | 9 | |
10 | - def after_update(merge_request) | |
10 | + def after_close(merge_request, transition) | |
11 | 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 | 24 | end |
20 | 25 | |
21 | 26 | protected | ... | ... |
app/uploaders/attachment_uploader.rb
... | ... | @@ -19,4 +19,12 @@ class AttachmentUploader < CarrierWave::Uploader::Base |
19 | 19 | rescue |
20 | 20 | false |
21 | 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 | 30 | end | ... | ... |
app/views/admin/groups/index.html.haml
... | ... | @@ -28,7 +28,7 @@ |
28 | 28 | %td= group.path |
29 | 29 | %td= group.projects.count |
30 | 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 | 32 | %td.bgred |
33 | 33 | = link_to 'Rename', edit_admin_group_path(group), id: "edit_#{dom_id(group)}", class: "btn btn-small" |
34 | 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 | 30 | %td= team.projects.count |
31 | 31 | %td= team.members.count |
32 | 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 | 34 | %td.bgred |
35 | 35 | = link_to 'Rename', edit_admin_team_path(team), id: "edit_#{dom_id(team)}", class: "btn btn-small" |
36 | 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 | 6 | = link_to commit.short_id(8), project_commit_path(@project, commit), class: "commit_short_id" |
7 | 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 | 12 | = time_ago_in_words(commit.committed_date) |
13 | 13 | ago |
14 | 14 | | ... | ... |
app/views/events/event/_note.html.haml
... | ... | @@ -26,7 +26,7 @@ |
26 | 26 | = markdown truncate(event.target.note, length: 70) |
27 | 27 | - note = event.target |
28 | 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 | 30 | - if note.attachment.image? |
31 | 31 | = image_tag note.attachment.url, class: 'note-image-attach' |
32 | 32 | - else | ... | ... |
app/views/groups/_filter.html.haml
... | ... | @@ -26,6 +26,8 @@ |
26 | 26 | = link_to group_filter_path(entity, project_id: project.id) do |
27 | 27 | = project.name_with_namespace |
28 | 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 | 32 | %fieldset |
31 | 33 | %hr | ... | ... |
app/views/groups/_people_filter.html.haml
app/views/groups/edit.html.haml
... | ... | @@ -30,6 +30,8 @@ |
30 | 30 | = link_to 'Team', project_team_index_path(project), id: "edit_#{dom_id(project)}", class: "btn btn-small" |
31 | 31 | = link_to 'Edit', edit_project_path(project), id: "edit_#{dom_id(project)}", class: "btn btn-small" |
32 | 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 | 36 | .span5 |
35 | 37 | .ui-box | ... | ... |
app/views/help/index.html.haml
app/views/issues/_show.html.haml
... | ... | @@ -8,10 +8,10 @@ |
8 | 8 | %i.icon-comment |
9 | 9 | = issue.notes.count |
10 | 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 | 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 | 15 | = link_to edit_project_issue_path(issue.project, issue), class: "btn btn-small edit-issue-link grouped" do |
16 | 16 | %i.icon-edit |
17 | 17 | Edit | ... | ... |
app/views/issues/show.html.haml
... | ... | @@ -7,10 +7,10 @@ |
7 | 7 | |
8 | 8 | %span.pull-right |
9 | 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 | 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 | 14 | - if can?(current_user, :admin_project, @project) || @issue.author == current_user |
15 | 15 | = link_to edit_project_issue_path(@project, @issue), class: "btn grouped" do |
16 | 16 | %i.icon-edit |
... | ... | @@ -27,7 +27,7 @@ |
27 | 27 | .ui-box.ui-box-show |
28 | 28 | .ui-box-head |
29 | 29 | %h4.box-title |
30 | - - if @issue.closed | |
30 | + - if @issue.closed? | |
31 | 31 | .error.status_info Closed |
32 | 32 | = gfm escape_once(@issue.title) |
33 | 33 | ... | ... |
app/views/merge_requests/_show.html.haml
... | ... | @@ -29,10 +29,10 @@ |
29 | 29 | $(function(){ |
30 | 30 | merge_request = new MergeRequest({ |
31 | 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 | 33 | url_to_ci_check: "#{ci_status_project_merge_request_path(@project, @merge_request)}", |
34 | 34 | ci_enable: #{@project.gitlab_ci? ? "true" : "false"}, |
35 | - current_state: "#{@merge_request.human_state}", | |
35 | + current_status: "#{@merge_request.human_merge_status}", | |
36 | 36 | action: "#{controller.action_name}" |
37 | 37 | }); |
38 | 38 | }); | ... | ... |
app/views/merge_requests/show/_mr_accept.html.haml
... | ... | @@ -3,7 +3,7 @@ |
3 | 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 | 7 | .automerge_widget.can_be_merged{style: "display:none"} |
8 | 8 | .alert.alert-success |
9 | 9 | %span | ... | ... |
app/views/merge_requests/show/_mr_box.html.haml
1 | 1 | .ui-box.ui-box-show |
2 | 2 | .ui-box-head |
3 | 3 | %h4.box-title |
4 | - - if @merge_request.merged | |
4 | + - if @merge_request.merged? | |
5 | 5 | .error.status_info |
6 | 6 | %i.icon-ok |
7 | 7 | Merged |
8 | - - elsif @merge_request.closed | |
8 | + - elsif @merge_request.closed? | |
9 | 9 | .error.status_info Closed |
10 | 10 | = gfm escape_once(@merge_request.title) |
11 | 11 | |
... | ... | @@ -21,14 +21,14 @@ |
21 | 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 | 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 | |
8 | 8 | %span.pull-right |
9 | 9 | - if can?(current_user, :modify_merge_request, @merge_request) |
10 | - - if @merge_request.open? | |
10 | + - if @merge_request.opened? | |
11 | 11 | .left.btn-group |
12 | 12 | %a.btn.grouped.dropdown-toggle{ data: {toggle: :dropdown} } |
13 | 13 | %i.icon-download-alt |
... | ... | @@ -17,7 +17,7 @@ |
17 | 17 | %li= link_to "Email Patches", project_merge_request_path(@project, @merge_request, format: :patch) |
18 | 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 | 22 | = link_to edit_project_merge_request_path(@project, @merge_request), class: "btn grouped" do |
23 | 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 | 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 | 4 | = link_to edit_project_milestone_path(milestone.project, milestone), class: "btn btn-small edit-milestone-link grouped" do |
5 | 5 | %i.icon-edit |
6 | 6 | Edit |
7 | 7 | %h4 |
8 | 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 | 10 | %span.cred (Expired) |
11 | 11 | %small |
12 | 12 | = milestone.expires_at | ... | ... |
app/views/milestones/show.html.haml
... | ... | @@ -9,7 +9,7 @@ |
9 | 9 | ← To milestones list |
10 | 10 | .span6 |
11 | 11 | .pull-right |
12 | - - unless @milestone.closed | |
12 | + - unless @milestone.closed? | |
13 | 13 | = link_to new_project_issue_path(@project, issue: { milestone_id: @milestone.id }), class: "btn btn-small grouped", title: "New Issue" do |
14 | 14 | %i.icon-plus |
15 | 15 | New Issue |
... | ... | @@ -25,12 +25,12 @@ |
25 | 25 | %hr |
26 | 26 | %p |
27 | 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 | 30 | .ui-box.ui-box-show |
31 | 31 | .ui-box-head |
32 | 32 | %h4.box-title |
33 | - - if @milestone.closed | |
33 | + - if @milestone.closed? | |
34 | 34 | .error.status_info Closed |
35 | 35 | - elsif @milestone.expired? |
36 | 36 | .error.status_info Expired |
... | ... | @@ -63,7 +63,7 @@ |
63 | 63 | %li=link_to('All Issues', '#') |
64 | 64 | %ul.well-list |
65 | 65 | - @issues.each do |issue| |
66 | - %li{data: {closed: issue.closed}} | |
66 | + %li{data: {closed: issue.closed?}} | |
67 | 67 | = link_to [@project, issue] do |
68 | 68 | %span.badge.badge-info ##{issue.id} |
69 | 69 | – |
... | ... | @@ -77,7 +77,7 @@ |
77 | 77 | %li=link_to('All Merge Requests', '#') |
78 | 78 | %ul.well-list |
79 | 79 | - @merge_requests.each do |merge_request| |
80 | - %li{data: {closed: merge_request.closed}} | |
80 | + %li{data: {closed: merge_request.closed?}} | |
81 | 81 | = link_to [@project, merge_request] do |
82 | 82 | %span.badge.badge-info ##{merge_request.id} |
83 | 83 | – | ... | ... |
app/views/notes/_note.html.haml
... | ... | @@ -31,7 +31,7 @@ |
31 | 31 | - if note.attachment.image? |
32 | 32 | = image_tag note.attachment.url, class: 'note-image-attach' |
33 | 33 | .attachment.pull-right |
34 | - = link_to note.attachment.url, target: "_blank" do | |
34 | + = link_to note.attachment.secure_url, target: "_blank" do | |
35 | 35 | %i.icon-paper-clip |
36 | 36 | = note.attachment_identifier |
37 | 37 | .clear | ... | ... |
app/views/profiles/account.html.haml
... | ... | @@ -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 | 81 | - if Gitlab.config.gitlab.signup_enabled |
81 | 82 | %fieldset.remove-account |
... | ... | @@ -83,4 +84,4 @@ |
83 | 84 | Remove account |
84 | 85 | %small.cred.pull-right |
85 | 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 | 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
app/views/projects/_new_form.html.haml
... | ... | @@ -28,7 +28,7 @@ |
28 | 28 | .input |
29 | 29 | = f.text_field :import_url, class: 'xlarge', placeholder: 'https://github.com/randx/six.git' |
30 | 30 | .light |
31 | - URL should be clonable | |
31 | + URL must be clonable | |
32 | 32 | |
33 | 33 | %p.padded |
34 | 34 | New projects are private by default. You choose who can see the project and commit to repository. | ... | ... |
app/views/projects/files.html.haml
... | ... | @@ -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 | -- 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 | -- 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 | 2 | .ui-box |
3 | 3 | %h5.title |
4 | 4 | = Project.access_options.key(access).pluralize |
5 | 5 | %small= members.size |
6 | 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 @@ |
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 | -- 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 | 18 | %hr |
19 | 19 | |
20 | 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 | 1 | %h3.page_title= "Edit Team #{@team.name}" |
2 | 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 | 10 | %br |
11 | 11 | %small.cgray= user.email |
12 | 12 | |
13 | - .span6.pull-right | |
13 | + .span4 | |
14 | 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 | 17 | %li All created teams are public (users can view who enter into team and which project are assigned for this team) |
18 | 18 | %li People within a team see only projects they have access to |
19 | 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 | 21 | return false |
22 | 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 | 26 | email = project.repository.commit(newrev).author.email rescue nil |
28 | 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 | 36 | key_id = identifier.gsub("key-", "") |
33 | 37 | Key.find_by_id(key_id).try(:user) |
34 | 38 | end | ... | ... |
config/gitlab.yml.example
... | ... | @@ -7,121 +7,132 @@ |
7 | 7 | # 2. Replace gitlab -> host with your domain |
8 | 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 | 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 | 1 | class Settings < Settingslogic |
2 | 2 | source "#{Rails.root}/config/gitlab.yml" |
3 | + namespace Rails.env | |
3 | 4 | |
4 | 5 | class << self |
5 | 6 | def gitlab_on_non_standard_port? |
... | ... | @@ -56,6 +57,7 @@ Settings.gitlab['support_email'] ||= Settings.gitlab.email_from |
56 | 57 | Settings.gitlab['url'] ||= Settings.send(:build_gitlab_url) |
57 | 58 | Settings.gitlab['user'] ||= 'git' |
58 | 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 | 63 | # Gravatar | ... | ... |
config/initializers/2_app.rb
config/routes.rb
... | ... | @@ -47,6 +47,11 @@ Gitlab::Application.routes.draw do |
47 | 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 | 55 | # Admin Area |
51 | 56 | # |
52 | 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 | 16 | project_id: project.id, |
17 | 17 | author_id: user_id, |
18 | 18 | assignee_id: user_id, |
19 | - closed: [true, false].sample, | |
19 | + state: ['opened', 'closed'].sample, | |
20 | 20 | milestone: project.milestones.sample, |
21 | 21 | title: Faker::Lorem.sentence(6) |
22 | 22 | }]) | ... | ... |
db/fixtures/development/10_merge_requests.rb
... | ... | @@ -17,7 +17,7 @@ Gitlab::Seeder.quiet do |
17 | 17 | project_id: project.id, |
18 | 18 | author_id: user_id, |
19 | 19 | assignee_id: user_id, |
20 | - closed: [true, false].sample, | |
20 | + state: ['opened', 'closed'].sample, | |
21 | 21 | milestone: project.milestones.sample, |
22 | 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 @@ |
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 @@ |
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 @@ |
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 | 11 | # |
12 | 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 | 16 | create_table "events", :force => true do |t| |
17 | 17 | t.string "target_type" |
... | ... | @@ -37,18 +37,17 @@ ActiveRecord::Schema.define(:version => 20130131070232) do |
37 | 37 | t.integer "assignee_id" |
38 | 38 | t.integer "author_id" |
39 | 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 | 42 | t.integer "position", :default => 0 |
44 | 43 | t.string "branch_name" |
45 | 44 | t.text "description" |
46 | 45 | t.integer "milestone_id" |
46 | + t.string "state" | |
47 | 47 | end |
48 | 48 | |
49 | 49 | add_index "issues", ["assignee_id"], :name => "index_issues_on_assignee_id" |
50 | 50 | add_index "issues", ["author_id"], :name => "index_issues_on_author_id" |
51 | - add_index "issues", ["closed"], :name => "index_issues_on_closed" | |
52 | 51 | add_index "issues", ["created_at"], :name => "index_issues_on_created_at" |
53 | 52 | add_index "issues", ["milestone_id"], :name => "index_issues_on_milestone_id" |
54 | 53 | add_index "issues", ["project_id"], :name => "index_issues_on_project_id" |
... | ... | @@ -69,25 +68,23 @@ ActiveRecord::Schema.define(:version => 20130131070232) do |
69 | 68 | add_index "keys", ["user_id"], :name => "index_keys_on_user_id" |
70 | 69 | |
71 | 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 | 74 | t.integer "author_id" |
76 | 75 | t.integer "assignee_id" |
77 | 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 | 79 | t.text "st_commits", :limit => 2147483647 |
82 | 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 | 82 | t.integer "milestone_id" |
83 | + t.string "state" | |
86 | 84 | end |
87 | 85 | |
88 | 86 | add_index "merge_requests", ["assignee_id"], :name => "index_merge_requests_on_assignee_id" |
89 | 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 | 88 | add_index "merge_requests", ["created_at"], :name => "index_merge_requests_on_created_at" |
92 | 89 | add_index "merge_requests", ["milestone_id"], :name => "index_merge_requests_on_milestone_id" |
93 | 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 | 93 | add_index "merge_requests", ["title"], :name => "index_merge_requests_on_title" |
97 | 94 | |
98 | 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 | 98 | t.text "description" |
102 | 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 | 103 | end |
107 | 104 | |
108 | 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 | 34 | Parameters: |
35 | 35 | |
36 | 36 | + `id` (required) - The ID of a project |
37 | -+ `milestone_id` (required) - The ID of a project milestone | |
38 | 37 | + `title` (required) - The title of an milestone |
39 | 38 | + `description` (optional) - The description of the milestone |
40 | 39 | + `due_date` (optional) - The due date of the milestone | ... | ... |
doc/api/projects.md
... | ... | @@ -23,7 +23,7 @@ GET /projects |
23 | 23 | "blocked": false, |
24 | 24 | "created_at": "2012-05-23T08:00:58Z" |
25 | 25 | }, |
26 | - "private": true, | |
26 | + "public": true, | |
27 | 27 | "path": "rails", |
28 | 28 | "path_with_namespace": "rails/rails", |
29 | 29 | "issues_enabled": false, |
... | ... | @@ -45,7 +45,7 @@ GET /projects |
45 | 45 | "blocked": false, |
46 | 46 | "created_at": "2012-05-23T08:00:58Z" |
47 | 47 | }, |
48 | - "private": true, | |
48 | + "public": true, | |
49 | 49 | "path": "gitlab", |
50 | 50 | "path_with_namespace": "randx/gitlab", |
51 | 51 | "issues_enabled": true, |
... | ... | @@ -89,7 +89,7 @@ Parameters: |
89 | 89 | "blocked": false, |
90 | 90 | "created_at": "2012-05-23T08:00:58Z" |
91 | 91 | }, |
92 | - "private": true, | |
92 | + "public": true, | |
93 | 93 | "path": "gitlab", |
94 | 94 | "path_with_namespace": "randx/gitlab", |
95 | 95 | "issues_enabled": true, | ... | ... |
doc/install/databases.md
... | ... | @@ -27,7 +27,7 @@ GitLab supports the following databases: |
27 | 27 | mysql> \q |
28 | 28 | |
29 | 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 | 32 | ## PostgreSQL |
33 | 33 | |
... | ... | @@ -47,5 +47,5 @@ GitLab supports the following databases: |
47 | 47 | template1=# \q |
48 | 48 | |
49 | 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 | 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 | 6 | **Important Note:** |
... | ... | @@ -8,12 +8,13 @@ The following steps have been known to work. |
8 | 8 | If you deviate from this guide, do it with caution and make sure you don't |
9 | 9 | violate any assumptions GitLab makes about its environment. |
10 | 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 | 15 | **Important Note:** |
15 | 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 | 25 | 1. Packages / Dependencies |
25 | 26 | 2. Ruby |
26 | 27 | 3. System Users |
27 | -4. Gitolite | |
28 | +4. GitLab shell | |
28 | 29 | 5. Database |
29 | 30 | 6. GitLab |
30 | 31 | 7. Nginx |
... | ... | @@ -32,16 +33,13 @@ The GitLab installation consists of setting up the following components: |
32 | 33 | |
33 | 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 | 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 | 44 | **Note:** |
47 | 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 | 94 | |
97 | 95 | # 4. GitLab shell |
98 | 96 | |
99 | - # login as git | |
97 | + # Login as git | |
100 | 98 | sudo su git |
101 | 99 | |
102 | - # go to home directory | |
100 | + # Go to home directory | |
103 | 101 | cd /home/git |
104 | 102 | |
105 | - # clone gitlab shell | |
103 | + # Clone gitlab shell | |
106 | 104 | git clone https://github.com/gitlabhq/gitlab-shell.git |
107 | 105 | |
108 | - # setup | |
106 | + # Setup | |
109 | 107 | cd gitlab-shell |
110 | 108 | cp config.yml.example config.yml |
111 | 109 | ./bin/install |
112 | 110 | |
113 | 111 | |
114 | - | |
115 | 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 | 117 | # 6. GitLab |
... | ... | @@ -154,9 +151,13 @@ do so with caution! |
154 | 151 | sudo chmod -R u+rwX log/ |
155 | 152 | sudo chmod -R u+rwX tmp/ |
156 | 153 | |
157 | - # Make directory for satellites | |
154 | + # Create directory for satellites | |
158 | 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 | 161 | # Copy the example Unicorn config |
161 | 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 | 188 | |
188 | 189 | |
189 | 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 | 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 | 208 | |
206 | 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 | 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 | 230 | |
228 | 231 | **Note:** |
229 | 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 | 235 | ## Installation |
233 | 236 | sudo apt-get install nginx |
... | ... | @@ -244,11 +247,11 @@ Make sure to edit the config file to match your setup: |
244 | 247 | # Change **YOUR_SERVER_IP** and **YOUR_SERVER_FQDN** |
245 | 248 | # to the IP address and fully-qualified domain name |
246 | 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 | 252 | ## Restart |
250 | 253 | |
251 | - sudo /etc/init.d/nginx restart | |
254 | + sudo service nginx restart | |
252 | 255 | |
253 | 256 | |
254 | 257 | # Done! |
... | ... | @@ -282,7 +285,7 @@ a different host, you can configure its connection string via the |
282 | 285 | |
283 | 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 | 290 | # Add to /home/git/.ssh/config |
288 | 291 | host localhost # Give your setup a name (here: override localhost) | ... | ... |