Commit 8045a81bcf5822f1992442750e1484a93c368229
Exists in
master
and in
4 other branches
Merge branch 'master' into fixes/api
Showing
262 changed files
with
1808 additions
and
1431 deletions
Show diff stats
CHANGELOG
Gemfile
... | ... | @@ -32,9 +32,6 @@ gem 'gitlab_omniauth-ldap', '1.0.2', require: "omniauth-ldap" |
32 | 32 | # Dump db to yml file. Mostly used to migrate from sqlite to mysql |
33 | 33 | gem 'gitlab_yaml_db', '1.0.0', require: "yaml_db" |
34 | 34 | |
35 | -# Gitolite client (for work with gitolite-admin repo) | |
36 | -gem "gitolite", '1.1.0' | |
37 | - | |
38 | 35 | # Syntax highlighter |
39 | 36 | gem "pygments.rb", git: "https://github.com/gitlabhq/pygments.rb.git", branch: "master" |
40 | 37 | |
... | ... | @@ -165,5 +162,5 @@ group :test do |
165 | 162 | end |
166 | 163 | |
167 | 164 | group :production do |
168 | - gem "gitlab_meta", '4.0' | |
165 | + gem "gitlab_meta", '5.0' | |
169 | 166 | end | ... | ... |
Gemfile.lock
... | ... | @@ -107,7 +107,6 @@ GEM |
107 | 107 | coderay (>= 1.0.0) |
108 | 108 | erubis (>= 2.7.0) |
109 | 109 | binding_of_caller (0.6.8) |
110 | - blankslate (3.1.2) | |
111 | 110 | bootstrap-sass (2.2.1.1) |
112 | 111 | sass (~> 3.2) |
113 | 112 | builder (3.0.4) |
... | ... | @@ -188,17 +187,13 @@ GEM |
188 | 187 | mime-types (~> 1.19) |
189 | 188 | pygments.rb (>= 0.2.13) |
190 | 189 | github-markup (0.7.4) |
191 | - gitlab_meta (4.0) | |
190 | + gitlab_meta (5.0) | |
192 | 191 | gitlab_omniauth-ldap (1.0.2) |
193 | 192 | net-ldap (~> 0.2.2) |
194 | 193 | omniauth (~> 1.0) |
195 | 194 | pyu-ruby-sasl (~> 0.0.3.1) |
196 | 195 | rubyntlm (~> 0.1.1) |
197 | 196 | gitlab_yaml_db (1.0.0) |
198 | - gitolite (1.1.0) | |
199 | - gratr19 (~> 0.4.4.1) | |
200 | - grit (~> 2.5.0) | |
201 | - hashery (~> 1.5.0) | |
202 | 197 | grape (0.2.2) |
203 | 198 | activesupport |
204 | 199 | hashie (~> 1.2) |
... | ... | @@ -208,7 +203,6 @@ GEM |
208 | 203 | rack-accept |
209 | 204 | rack-mount |
210 | 205 | virtus |
211 | - gratr19 (0.4.4.1) | |
212 | 206 | growl (1.0.3) |
213 | 207 | guard (1.5.4) |
214 | 208 | listen (>= 0.4.2) |
... | ... | @@ -227,8 +221,6 @@ GEM |
227 | 221 | activesupport (>= 3.1, < 4.1) |
228 | 222 | haml (~> 3.1) |
229 | 223 | railties (>= 3.1, < 4.1) |
230 | - hashery (1.5.0) | |
231 | - blankslate | |
232 | 224 | hashie (1.2.0) |
233 | 225 | hike (1.2.1) |
234 | 226 | http_parser.rb (0.5.3) |
... | ... | @@ -494,10 +486,9 @@ DEPENDENCIES |
494 | 486 | git |
495 | 487 | github-linguist (~> 2.3.4) |
496 | 488 | github-markup (~> 0.7.4) |
497 | - gitlab_meta (= 4.0) | |
489 | + gitlab_meta (= 5.0) | |
498 | 490 | gitlab_omniauth-ldap (= 1.0.2) |
499 | 491 | gitlab_yaml_db (= 1.0.0) |
500 | - gitolite (= 1.1.0) | |
501 | 492 | grack! |
502 | 493 | grape (~> 0.2.1) |
503 | 494 | grit! | ... | ... |
ROADMAP.md
1 | 1 | ## GitLab Roadmap |
2 | 2 | |
3 | -### v4.3 March 22 | |
3 | +### v5.0 March 22 | |
4 | 4 | |
5 | -* Jenkins CI integration service | |
5 | +* Replace gitolite with gitlab-shell | |
6 | 6 | * Usability improvements |
7 | 7 | * Notification improvements |
8 | 8 | |
9 | 9 | ### v4.2 February 22 |
10 | 10 | |
11 | -* Campfire integration service | |
12 | 11 | * Teams |
13 | 12 | ... | ... |
VERSION
app/assets/images/home_icon.PNG
596 Bytes
app/assets/images/icon-attachment.png
450 Bytes
app/assets/javascripts/notes.js
... | ... | @@ -20,12 +20,12 @@ var NoteList = { |
20 | 20 | |
21 | 21 | if(NoteList.reversed) { |
22 | 22 | var form = $(".js-main-target-form"); |
23 | - form.find(".buttons, .note_options").hide(); | |
23 | + form.find(".note-form-actions").hide(); | |
24 | 24 | var textarea = form.find(".js-note-text"); |
25 | 25 | textarea.css("height", "40px"); |
26 | 26 | textarea.on("focus", function(){ |
27 | 27 | textarea.css("height", "80px"); |
28 | - form.find(".buttons, .note_options").show(); | |
28 | + form.find(".note-form-actions").show(); | |
29 | 29 | }); |
30 | 30 | } |
31 | 31 | ... | ... |
app/assets/stylesheets/common.scss
app/assets/stylesheets/gitlab_bootstrap.scss
... | ... | @@ -17,6 +17,8 @@ $baseLineHeight: 18px !default; |
17 | 17 | @import "gitlab_bootstrap/variables.scss"; |
18 | 18 | @import "gitlab_bootstrap/fonts.scss"; |
19 | 19 | @import "gitlab_bootstrap/mixins.scss"; |
20 | +@import "gitlab_bootstrap/avatar.scss"; | |
21 | +@import "gitlab_bootstrap/nav.scss"; | |
20 | 22 | @import "gitlab_bootstrap/common.scss"; |
21 | 23 | @import "gitlab_bootstrap/typography.scss"; |
22 | 24 | @import "gitlab_bootstrap/buttons.scss"; | ... | ... |
... | ... | @@ -0,0 +1,8 @@ |
1 | +/** AVATARS **/ | |
2 | +img.avatar { float: left; margin-right: 12px; width: 40px; border: 1px solid #ddd; padding: 1px; } | |
3 | +img.avatar.s16 { width: 16px; height: 16px; margin-right: 6px; } | |
4 | +img.avatar.s24 { width: 24px; height: 24px; margin-right: 8px; } | |
5 | +img.avatar.s32 { width: 32px; height: 32px; margin-right: 10px; } | |
6 | +img.avatar.s90 { width: 90px; height: 90px; margin-right: 15px; } | |
7 | +img.lil_av { padding-left: 4px; padding-right: 3px; } | |
8 | +img.small { width: 80px; } | ... | ... |
app/assets/stylesheets/gitlab_bootstrap/blocks.scss
app/assets/stylesheets/gitlab_bootstrap/buttons.scss
1 | 1 | .btn { |
2 | - @include linear-gradient(#f7f7f7, #d5d5d5); | |
2 | + @include linear-gradient(#f1f1f1, #e1e1e1); | |
3 | + text-shadow: 0 1px 1px #FFF; | |
3 | 4 | border-color: #BBB; |
5 | + | |
4 | 6 | &:hover { |
5 | - @include bg-gray-gradient; | |
6 | - border-color: #bbb; | |
7 | + background: #f1f1f1; | |
8 | + @include linear-gradient(#fAfAfA, #f1f1f1); | |
9 | + border-color: #AAA; | |
7 | 10 | color: #333; |
8 | 11 | } |
9 | 12 | |
10 | - &.btn-white { | |
11 | - background: #FFF; | |
12 | - } | |
13 | - | |
14 | - &.primary { | |
13 | + &.btn-primary { | |
15 | 14 | background: #2a79A3; |
16 | 15 | @include linear-gradient(#47A7b7, #2585b5); |
17 | 16 | border-color: #2A79A3; |
... | ... | @@ -58,21 +57,18 @@ |
58 | 57 | } |
59 | 58 | } |
60 | 59 | |
61 | - &.save-btn { | |
60 | + &.btn-create { | |
62 | 61 | @extend .wide; |
63 | - @extend .primary; | |
62 | + @extend .success; | |
64 | 63 | } |
65 | 64 | |
66 | - &.cancel-btn { | |
67 | - float: right; | |
68 | - } | |
69 | - | |
70 | - &.wide { | |
71 | - padding-left: 30px; | |
72 | - padding-right: 30px; | |
65 | + &.btn-save { | |
66 | + @extend .wide; | |
67 | + @extend .btn-primary; | |
73 | 68 | } |
74 | 69 | |
75 | - &.danger { | |
70 | + &.btn-close, | |
71 | + &.btn-remove { | |
76 | 72 | @extend .btn-danger; |
77 | 73 | border-color: #BD362F; |
78 | 74 | |
... | ... | @@ -82,8 +78,13 @@ |
82 | 78 | } |
83 | 79 | } |
84 | 80 | |
85 | - &.danger { | |
86 | - @extend .btn-danger; | |
81 | + &.btn-cancel { | |
82 | + float: right; | |
83 | + } | |
84 | + | |
85 | + &.wide { | |
86 | + padding-left: 20px; | |
87 | + padding-right: 20px; | |
87 | 88 | } |
88 | 89 | |
89 | 90 | &.small { |
... | ... | @@ -95,7 +96,7 @@ |
95 | 96 | background-color: #ccc; |
96 | 97 | } |
97 | 98 | |
98 | - &.very_small { | |
99 | + &.btn-tiny { | |
99 | 100 | font-size: 11px; |
100 | 101 | padding: 2px 6px; |
101 | 102 | line-height: 16px; | ... | ... |
app/assets/stylesheets/gitlab_bootstrap/common.scss
... | ... | @@ -9,7 +9,6 @@ |
9 | 9 | |
10 | 10 | /** COMMON CLASSES **/ |
11 | 11 | .left { float:left } |
12 | -.right { float:right!important } | |
13 | 12 | .append-bottom-10 { margin-bottom:10px } |
14 | 13 | .append-bottom-20 { margin-bottom:20px } |
15 | 14 | .prepend-top-10 { margin-top:10px } |
... | ... | @@ -22,82 +21,13 @@ |
22 | 21 | .light { color: #888 } |
23 | 22 | .tiny { font-weight: normal } |
24 | 23 | |
25 | -/** PILLS & TABS**/ | |
26 | -.nav-pills { | |
27 | - .active a { | |
28 | - background: $primary_color; | |
29 | - } | |
30 | - | |
31 | - > li > a { | |
32 | - @include border-radius(0); | |
33 | - } | |
34 | - &.nav-stacked { | |
35 | - > li > a { | |
36 | - border-left: 4px solid #EEE; | |
37 | - padding: 12px; | |
38 | - } | |
39 | - > .active > a { | |
40 | - border-color: #29B; | |
41 | - border-radius: 0; | |
42 | - background: #F1F1F1; | |
43 | - color: $style_color; | |
44 | - font-weight: bold; | |
45 | - } | |
46 | - } | |
47 | -} | |
48 | - | |
49 | -.nav-pills > .active > a > i[class^="icon-"] { background: inherit; } | |
50 | - | |
51 | - | |
52 | - | |
53 | -/** | |
54 | - * nav-tabs | |
55 | - * | |
56 | - */ | |
57 | -.nav-tabs > li > a, .nav-pills > li > a { color: $style_color; } | |
58 | -.nav.nav-tabs { | |
59 | - li { | |
60 | - > a { | |
61 | - padding: 8px 20px; | |
62 | - margin-right: 7px; | |
63 | - line-height: 20px; | |
64 | - border-color: #EEE; | |
65 | - color: #888; | |
66 | - border-bottom: 1px solid #ddd; | |
67 | - .badge { | |
68 | - background-color: #eee; | |
69 | - color: #888; | |
70 | - text-shadow: 0 1px 1px #fff; | |
71 | - } | |
72 | - i[class^="icon-"] { | |
73 | - line-height: 14px; | |
74 | - } | |
75 | - } | |
76 | - &.active { | |
77 | - > a { | |
78 | - border-color: #CCC; | |
79 | - border-bottom: 1px solid #fff; | |
80 | - color: #333; | |
81 | - } | |
82 | - } | |
83 | - } | |
84 | - | |
85 | - &.nav-small-tabs > li > a { padding: 6px 9px; } | |
86 | -} | |
87 | 24 | |
88 | 25 | /** ALERT MESSAGES **/ |
89 | -.alert-message { @extend .alert; } | |
90 | -.alert-messag.success { @extend .alert-success; } | |
91 | -.alert-message.error { @extend .alert-error; } | |
92 | - | |
93 | -/** AVATARS **/ | |
94 | -img.avatar { float: left; margin-right: 12px; width: 40px; border: 1px solid #ddd; padding: 1px; } | |
95 | -img.avatar.s16 { width: 16px; height: 16px; margin-right: 6px; } | |
96 | -img.avatar.s24 { width: 24px; height: 24px; margin-right: 8px; } | |
97 | -img.avatar.s32 { width: 32px; height: 32px; margin-right: 10px; } | |
98 | -img.avatar.s90 { width: 90px; height: 90px; margin-right: 15px; } | |
99 | -img.lil_av { padding-left: 4px; padding-right: 3px; } | |
100 | -img.small { width: 80px; } | |
26 | +.alert.alert-disabled { | |
27 | + background: #EEE; | |
28 | + color: #777; | |
29 | + border-color: #DDD; | |
30 | +} | |
101 | 31 | |
102 | 32 | /** HELPERS **/ |
103 | 33 | .nothing_here_message { | ... | ... |
... | ... | @@ -0,0 +1,65 @@ |
1 | +/** | |
2 | + * nav-pills | |
3 | + * | |
4 | + */ | |
5 | +.nav-pills { | |
6 | + .active a { | |
7 | + background: $primary_color; | |
8 | + } | |
9 | + | |
10 | + > li > a { | |
11 | + @include border-radius(0); | |
12 | + } | |
13 | + &.nav-stacked { | |
14 | + > li > a { | |
15 | + border-left: 4px solid #EEE; | |
16 | + padding: 12px; | |
17 | + } | |
18 | + > .active > a { | |
19 | + border-color: #29B; | |
20 | + border-radius: 0; | |
21 | + background: #F1F1F1; | |
22 | + color: $style_color; | |
23 | + font-weight: bold; | |
24 | + } | |
25 | + } | |
26 | +} | |
27 | + | |
28 | +.nav-pills > .active > a > i[class^="icon-"] { background: inherit; } | |
29 | + | |
30 | + | |
31 | + | |
32 | +/** | |
33 | + * nav-tabs | |
34 | + * | |
35 | + */ | |
36 | +.nav-tabs > li > a, .nav-pills > li > a { color: $style_color; } | |
37 | +.nav.nav-tabs { | |
38 | + li { | |
39 | + > a { | |
40 | + padding: 8px 20px; | |
41 | + margin-right: 7px; | |
42 | + line-height: 20px; | |
43 | + border-color: #EEE; | |
44 | + color: #888; | |
45 | + border-bottom: 1px solid #ddd; | |
46 | + .badge { | |
47 | + background-color: #eee; | |
48 | + color: #888; | |
49 | + text-shadow: 0 1px 1px #fff; | |
50 | + } | |
51 | + i[class^="icon-"] { | |
52 | + line-height: 14px; | |
53 | + } | |
54 | + } | |
55 | + &.active { | |
56 | + > a { | |
57 | + border-color: #CCC; | |
58 | + border-bottom: 1px solid #fff; | |
59 | + color: #333; | |
60 | + } | |
61 | + } | |
62 | + } | |
63 | + | |
64 | + &.nav-small-tabs > li > a { padding: 6px 9px; } | |
65 | +} | ... | ... |
app/assets/stylesheets/sections/events.scss
app/assets/stylesheets/sections/login.scss
app/assets/stylesheets/sections/nav.scss
... | ... | @@ -6,8 +6,7 @@ ul.main_menu { |
6 | 6 | margin: auto; |
7 | 7 | margin: 30px 0; |
8 | 8 | margin-top: 10px; |
9 | - border-bottom: 1px solid #DDD; | |
10 | - height: 37px; | |
9 | + height: 38px; | |
11 | 10 | position: relative; |
12 | 11 | overflow: hidden; |
13 | 12 | .count { |
... | ... | @@ -33,6 +32,7 @@ ul.main_menu { |
33 | 32 | margin: 0; |
34 | 33 | display: table-cell; |
35 | 34 | width: 1%; |
35 | + border-bottom: 2px solid #EEE; | |
36 | 36 | &.active { |
37 | 37 | border-bottom: 2px solid #474D57; |
38 | 38 | a { |
... | ... | @@ -42,10 +42,8 @@ ul.main_menu { |
42 | 42 | |
43 | 43 | &.home { |
44 | 44 | a { |
45 | - background: url(home_icon.PNG) no-repeat center center; | |
46 | - text-indent:-9999px; | |
47 | - min-width: 20px; | |
48 | - img { | |
45 | + i { | |
46 | + font-size: 20px; | |
49 | 47 | position: relative; |
50 | 48 | top: 4px; |
51 | 49 | } |
... | ... | @@ -56,7 +54,7 @@ ul.main_menu { |
56 | 54 | display: block; |
57 | 55 | text-align: center; |
58 | 56 | font-weight: normal; |
59 | - height: 35px; | |
57 | + height: 36px; | |
60 | 58 | line-height: 36px; |
61 | 59 | color: #777; |
62 | 60 | text-shadow: 0 1px 1px white; | ... | ... |
app/assets/stylesheets/sections/notes.scss
... | ... | @@ -81,14 +81,6 @@ ul.notes { |
81 | 81 | .attachment { |
82 | 82 | font-size: 14px; |
83 | 83 | margin-top: -20px; |
84 | - | |
85 | - .icon-attachment { | |
86 | - @extend .icon-paper-clip; | |
87 | - font-size: 24px; | |
88 | - position: relative; | |
89 | - text-align: right; | |
90 | - top: 6px; | |
91 | - } | |
92 | 84 | } |
93 | 85 | .note-body { |
94 | 86 | margin-left: 45px; |
... | ... | @@ -214,9 +206,11 @@ ul.notes { |
214 | 206 | * Note Form |
215 | 207 | */ |
216 | 208 | |
217 | -.comment-btn, | |
209 | +.comment-btn { | |
210 | + @extend .btn-create; | |
211 | +} | |
218 | 212 | .reply-btn { |
219 | - @extend .save-btn; | |
213 | + @extend .btn-primary; | |
220 | 214 | } |
221 | 215 | .file .content tr.line_holder:hover > td { background: $hover !important; } |
222 | 216 | .file .content tr.line_holder:hover > td .line_note_link { |
... | ... | @@ -227,11 +221,6 @@ ul.notes { |
227 | 221 | .discussion { |
228 | 222 | .new_note { |
229 | 223 | margin: 8px 5px 8px 0; |
230 | - | |
231 | - .note_options { | |
232 | - // because of the smaller width and the extra "cancel" button | |
233 | - margin-top: 8px; | |
234 | - } | |
235 | 224 | } |
236 | 225 | } |
237 | 226 | .new_note { |
... | ... | @@ -244,37 +233,6 @@ ul.notes { |
244 | 233 | .clearfix { |
245 | 234 | margin-bottom: 0; |
246 | 235 | } |
247 | - .note_options { | |
248 | - h6 { | |
249 | - @extend .left; | |
250 | - line-height: 20px; | |
251 | - padding-right: 16px; | |
252 | - padding-bottom: 16px; | |
253 | - } | |
254 | - label { | |
255 | - padding: 0; | |
256 | - } | |
257 | - | |
258 | - .attachment { | |
259 | - @extend .right; | |
260 | - position: relative; | |
261 | - width: 350px; | |
262 | - height: 50px; | |
263 | - margin:0 0 5px !important; | |
264 | - | |
265 | - // hide the actual file field | |
266 | - input { | |
267 | - display: none; | |
268 | - } | |
269 | - | |
270 | - .choose-btn { | |
271 | - float: right; | |
272 | - } | |
273 | - } | |
274 | - .notify_options { | |
275 | - @extend .right; | |
276 | - } | |
277 | - } | |
278 | 236 | .note_text_and_preview { |
279 | 237 | // makes the "absolute" position for links relative to this |
280 | 238 | position: relative; |
... | ... | @@ -313,3 +271,17 @@ ul.notes { |
313 | 271 | @extend .thumbnail; |
314 | 272 | margin-left: 45px; |
315 | 273 | } |
274 | + | |
275 | + | |
276 | +.note-form-actions { | |
277 | + background: #F9F9F9; | |
278 | + height: 45px; | |
279 | + padding: 0 5px; | |
280 | + | |
281 | + .note-form-option { | |
282 | + margin-top: 8px; | |
283 | + margin-left: 15px; | |
284 | + @extend .pull-left; | |
285 | + @extend .span4; | |
286 | + } | |
287 | +} | ... | ... |
app/assets/stylesheets/sections/projects.scss
app/controllers/application_controller.rb
... | ... | @@ -4,16 +4,12 @@ class ApplicationController < ActionController::Base |
4 | 4 | before_filter :set_current_user_for_observers |
5 | 5 | before_filter :add_abilities |
6 | 6 | before_filter :dev_tools if Rails.env == 'development' |
7 | + before_filter :default_headers | |
7 | 8 | |
8 | 9 | protect_from_forgery |
9 | 10 | |
10 | 11 | helper_method :abilities, :can? |
11 | 12 | |
12 | - rescue_from Gitlab::Gitolite::AccessDenied do |exception| | |
13 | - log_exception(exception) | |
14 | - render "errors/gitolite", layout: "errors", status: 500 | |
15 | - end | |
16 | - | |
17 | 13 | rescue_from Encoding::CompatibilityError do |exception| |
18 | 14 | log_exception(exception) |
19 | 15 | render "errors/encoding", layout: "errors", status: 500 |
... | ... | @@ -148,4 +144,8 @@ class ApplicationController < ActionController::Base |
148 | 144 | Rack::MiniProfiler.authorize_request |
149 | 145 | end |
150 | 146 | |
147 | + def default_headers | |
148 | + headers['X-Frame-Options'] = 'DENY' | |
149 | + headers['X-XSS-Protection'] = '1; mode=block' | |
150 | + end | |
151 | 151 | end | ... | ... |
... | ... | @@ -0,0 +1,18 @@ |
1 | +class GraphController < ProjectResourceController | |
2 | + include ExtractsPath | |
3 | + | |
4 | + # Authorize | |
5 | + before_filter :authorize_read_project! | |
6 | + before_filter :authorize_code_access! | |
7 | + before_filter :require_non_empty_project | |
8 | + | |
9 | + def show | |
10 | + respond_to do |format| | |
11 | + format.html | |
12 | + format.json do | |
13 | + graph = Gitlab::Graph::JsonBuilder.new(project, @ref) | |
14 | + render :json => graph.to_json | |
15 | + end | |
16 | + end | |
17 | + end | |
18 | +end | ... | ... |
app/controllers/groups_controller.rb
... | ... | @@ -6,6 +6,7 @@ class GroupsController < ApplicationController |
6 | 6 | |
7 | 7 | # Authorize |
8 | 8 | before_filter :authorize_read_group!, except: [:new, :create] |
9 | + before_filter :authorize_admin_group!, only: [:edit, :update, :destroy] | |
9 | 10 | before_filter :authorize_create_group!, only: [:new, :create] |
10 | 11 | |
11 | 12 | # Load group projects |
... | ... | @@ -84,6 +85,31 @@ class GroupsController < ApplicationController |
84 | 85 | redirect_to people_group_path(@group), notice: 'Users was successfully added.' |
85 | 86 | end |
86 | 87 | |
88 | + def edit | |
89 | + end | |
90 | + | |
91 | + def update | |
92 | + group_params = params[:group].dup | |
93 | + owner_id =group_params.delete(:owner_id) | |
94 | + | |
95 | + if owner_id | |
96 | + @group.owner = User.find(owner_id) | |
97 | + end | |
98 | + | |
99 | + if @group.update_attributes(group_params) | |
100 | + redirect_to @group, notice: 'Group was successfully updated.' | |
101 | + else | |
102 | + render action: "edit" | |
103 | + end | |
104 | + end | |
105 | + | |
106 | + def destroy | |
107 | + @group.truncate_teams | |
108 | + @group.destroy | |
109 | + | |
110 | + redirect_to root_path, notice: 'Group was removed.' | |
111 | + end | |
112 | + | |
87 | 113 | protected |
88 | 114 | |
89 | 115 | def group |
... | ... | @@ -106,6 +132,14 @@ class GroupsController < ApplicationController |
106 | 132 | end |
107 | 133 | |
108 | 134 | def authorize_create_group! |
109 | - can?(current_user, :create_group, nil) | |
135 | + unless can?(current_user, :create_group, nil) | |
136 | + return render_404 | |
137 | + end | |
138 | + end | |
139 | + | |
140 | + def authorize_admin_group! | |
141 | + unless can?(current_user, :manage_group, group) | |
142 | + return render_404 | |
143 | + end | |
110 | 144 | end |
111 | 145 | end | ... | ... |
app/controllers/projects_controller.rb
... | ... | @@ -90,16 +90,6 @@ class ProjectsController < ProjectResourceController |
90 | 90 | end |
91 | 91 | end |
92 | 92 | |
93 | - def graph | |
94 | - respond_to do |format| | |
95 | - format.html | |
96 | - format.json do | |
97 | - graph = Gitlab::Graph::JsonBuilder.new(project) | |
98 | - render :json => graph.to_json | |
99 | - end | |
100 | - end | |
101 | - end | |
102 | - | |
103 | 93 | def destroy |
104 | 94 | return access_denied! unless can?(current_user, :remove_project, project) |
105 | 95 | ... | ... |
app/controllers/refs_controller.rb
... | ... | @@ -13,6 +13,8 @@ class RefsController < ProjectResourceController |
13 | 13 | format.html do |
14 | 14 | new_path = if params[:destination] == "tree" |
15 | 15 | project_tree_path(@project, (@ref + "/" + params[:path])) |
16 | + elsif params[:destination] == "graph" | |
17 | + project_graph_path(@project, @ref) | |
16 | 18 | else |
17 | 19 | project_commits_path(@project, @ref) |
18 | 20 | end | ... | ... |
app/helpers/projects_helper.rb
... | ... | @@ -43,7 +43,7 @@ module ProjectsHelper |
43 | 43 | tm = project.team_member_by_id(author) |
44 | 44 | |
45 | 45 | if tm |
46 | - link_to author_html, project_team_member_path(project, tm), class: "author_link" | |
46 | + link_to author_html, project_team_member_path(project, tm.user_username), class: "author_link" | |
47 | 47 | else |
48 | 48 | author_html |
49 | 49 | end.html_safe | ... | ... |
app/mailers/notify.rb
... | ... | @@ -10,6 +10,10 @@ class Notify < ActionMailer::Base |
10 | 10 | |
11 | 11 | default from: Gitlab.config.gitlab.email_from |
12 | 12 | |
13 | + # Just send email with 3 seconds delay | |
14 | + def self.delay | |
15 | + delay_for(2.seconds) | |
16 | + end | |
13 | 17 | |
14 | 18 | |
15 | 19 | # |
... | ... | @@ -63,12 +67,12 @@ class Notify < ActionMailer::Base |
63 | 67 | # Note |
64 | 68 | # |
65 | 69 | |
66 | - def note_commit_email(commit_autor_email, note_id) | |
70 | + def note_commit_email(recipient_id, note_id) | |
67 | 71 | @note = Note.find(note_id) |
68 | 72 | @commit = @note.noteable |
69 | 73 | @commit = CommitDecorator.decorate(@commit) |
70 | 74 | @project = @note.project |
71 | - mail(to: commit_autor_email, subject: subject("note for commit #{@commit.short_id}", @commit.title)) | |
75 | + mail(to: recipient(recipient_id), subject: subject("note for commit #{@commit.short_id}", @commit.title)) | |
72 | 76 | end |
73 | 77 | |
74 | 78 | def note_issue_email(recipient_id, note_id) | ... | ... |
app/models/key.rb
... | ... | @@ -24,8 +24,8 @@ class Key < ActiveRecord::Base |
24 | 24 | before_save :set_identifier |
25 | 25 | |
26 | 26 | validates :title, presence: true, length: { within: 0..255 } |
27 | - validates :key, presence: true, length: { within: 0..5000 }, format: { :with => /ssh-.{3} / } | |
28 | - validate :unique_key, :fingerprintable_key | |
27 | + validates :key, presence: true, length: { within: 0..5000 }, format: { :with => /ssh-.{3} / }, uniqueness: true | |
28 | + validate :fingerprintable_key | |
29 | 29 | |
30 | 30 | delegate :name, :email, to: :user, prefix: true |
31 | 31 | |
... | ... | @@ -33,14 +33,6 @@ class Key < ActiveRecord::Base |
33 | 33 | self.key = self.key.strip unless self.key.blank? |
34 | 34 | end |
35 | 35 | |
36 | - def unique_key | |
37 | - query = Key.where(key: key) | |
38 | - query = query.where('(project_id IS NULL OR project_id = ?)', project_id) if project_id | |
39 | - if (query.count > 0) | |
40 | - errors.add :key, 'already exist.' | |
41 | - end | |
42 | - end | |
43 | - | |
44 | 36 | def fingerprintable_key |
45 | 37 | return true unless key # Don't test if there is no key. |
46 | 38 | # `ssh-keygen -lf /dev/stdin <<< "#{key}"` errors with: redirection unexpected |
... | ... | @@ -65,7 +57,7 @@ class Key < ActiveRecord::Base |
65 | 57 | end |
66 | 58 | |
67 | 59 | def is_deploy_key |
68 | - true if project_id | |
60 | + !!project_id | |
69 | 61 | end |
70 | 62 | |
71 | 63 | # projects that has this key |
... | ... | @@ -77,7 +69,7 @@ class Key < ActiveRecord::Base |
77 | 69 | end |
78 | 70 | end |
79 | 71 | |
80 | - def last_deploy? | |
81 | - Key.where(identifier: identifier).count == 0 | |
72 | + def shell_id | |
73 | + "key-#{self.id}" | |
82 | 74 | end |
83 | 75 | end | ... | ... |
app/models/namespace.rb
... | ... | @@ -27,7 +27,6 @@ class Namespace < ActiveRecord::Base |
27 | 27 | |
28 | 28 | after_create :ensure_dir_exist |
29 | 29 | after_update :move_dir |
30 | - after_commit :update_gitolite, on: :update, if: :require_update_gitolite | |
31 | 30 | after_destroy :rm_dir |
32 | 31 | |
33 | 32 | scope :root, where('type IS NULL') |
... | ... | @@ -89,11 +88,6 @@ class Namespace < ActiveRecord::Base |
89 | 88 | end |
90 | 89 | end |
91 | 90 | |
92 | - def update_gitolite | |
93 | - @require_update_gitolite = false | |
94 | - projects.each(&:update_repository) | |
95 | - end | |
96 | - | |
97 | 91 | def rm_dir |
98 | 92 | dir_path = File.join(Gitlab.config.gitolite.repos_path, path) |
99 | 93 | FileUtils.rm_r( dir_path, force: true ) | ... | ... |
app/models/project.rb
... | ... | @@ -8,7 +8,6 @@ |
8 | 8 | # description :text |
9 | 9 | # created_at :datetime not null |
10 | 10 | # updated_at :datetime not null |
11 | -# private_flag :boolean default(TRUE), not null | |
12 | 11 | # creator_id :integer |
13 | 12 | # default_branch :string(255) |
14 | 13 | # issues_enabled :boolean default(TRUE), not null |
... | ... | @@ -16,6 +15,7 @@ |
16 | 15 | # merge_requests_enabled :boolean default(TRUE), not null |
17 | 16 | # wiki_enabled :boolean default(TRUE), not null |
18 | 17 | # namespace_id :integer |
18 | +# public :boolean default(FALSE), not null | |
19 | 19 | # |
20 | 20 | |
21 | 21 | require "grit" |
... | ... | @@ -262,8 +262,6 @@ class Project < ActiveRecord::Base |
262 | 262 | |
263 | 263 | Gitlab::ProjectMover.new(self, old_dir, new_dir).execute |
264 | 264 | |
265 | - gitolite.move_repository(old_repo, self) | |
266 | - | |
267 | 265 | save! |
268 | 266 | end |
269 | 267 | rescue Gitlab::ProjectMover::ProjectMoveError => ex |
... | ... | @@ -459,20 +457,6 @@ class Project < ActiveRecord::Base |
459 | 457 | namespace.try(:path) || '' |
460 | 458 | end |
461 | 459 | |
462 | - def update_repository | |
463 | - GitoliteWorker.perform_async( | |
464 | - :update_repository, | |
465 | - self.id | |
466 | - ) | |
467 | - end | |
468 | - | |
469 | - def destroy_repository | |
470 | - GitoliteWorker.perform_async( | |
471 | - :remove_repository, | |
472 | - self.path_with_namespace | |
473 | - ) | |
474 | - end | |
475 | - | |
476 | 460 | def repo_exists? |
477 | 461 | @repo_exists ||= (repository && repository.branches.present?) |
478 | 462 | rescue | ... | ... |
app/models/project_team.rb
app/models/protected_branch.rb
... | ... | @@ -18,13 +18,6 @@ class ProtectedBranch < ActiveRecord::Base |
18 | 18 | validates :name, presence: true |
19 | 19 | validates :project, presence: true |
20 | 20 | |
21 | - after_save :update_repository | |
22 | - after_destroy :update_repository | |
23 | - | |
24 | - def update_repository | |
25 | - project.update_repository | |
26 | - end | |
27 | - | |
28 | 21 | def commit |
29 | 22 | project.repository.commit(self.name) |
30 | 23 | end | ... | ... |
app/models/user.rb
app/models/user_team.rb
1 | +# == Schema Information | |
2 | +# | |
3 | +# Table name: user_teams | |
4 | +# | |
5 | +# id :integer not null, primary key | |
6 | +# name :string(255) | |
7 | +# path :string(255) | |
8 | +# owner_id :integer | |
9 | +# created_at :datetime not null | |
10 | +# updated_at :datetime not null | |
11 | +# | |
12 | + | |
1 | 13 | class UserTeam < ActiveRecord::Base |
2 | 14 | attr_accessible :name, :owner_id, :path |
3 | 15 | ... | ... |
app/models/user_team_project_relationship.rb
1 | +# == Schema Information | |
2 | +# | |
3 | +# Table name: user_team_project_relationships | |
4 | +# | |
5 | +# id :integer not null, primary key | |
6 | +# project_id :integer | |
7 | +# user_team_id :integer | |
8 | +# greatest_access :integer | |
9 | +# created_at :datetime not null | |
10 | +# updated_at :datetime not null | |
11 | +# | |
12 | + | |
1 | 13 | class UserTeamProjectRelationship < ActiveRecord::Base |
2 | 14 | attr_accessible :greatest_access, :project_id, :user_team_id |
3 | 15 | ... | ... |
app/models/user_team_user_relationship.rb
1 | +# == Schema Information | |
2 | +# | |
3 | +# Table name: user_team_user_relationships | |
4 | +# | |
5 | +# id :integer not null, primary key | |
6 | +# user_id :integer | |
7 | +# user_team_id :integer | |
8 | +# group_admin :boolean | |
9 | +# permission :integer | |
10 | +# created_at :datetime not null | |
11 | +# updated_at :datetime not null | |
12 | +# | |
13 | + | |
1 | 14 | class UserTeamUserRelationship < ActiveRecord::Base |
2 | 15 | attr_accessible :group_admin, :permission, :user_id, :user_team_id |
3 | 16 | ... | ... |
app/models/users_project.rb
... | ... | @@ -25,15 +25,12 @@ class UsersProject < ActiveRecord::Base |
25 | 25 | |
26 | 26 | attr_accessor :skip_git |
27 | 27 | |
28 | - after_save :update_repository, unless: :skip_git? | |
29 | - after_destroy :update_repository, unless: :skip_git? | |
30 | - | |
31 | 28 | validates :user, presence: true |
32 | 29 | validates :user_id, uniqueness: { scope: [:project_id], message: "already exists in project" } |
33 | 30 | validates :project_access, inclusion: { in: [GUEST, REPORTER, DEVELOPER, MASTER] }, presence: true |
34 | 31 | validates :project, presence: true |
35 | 32 | |
36 | - delegate :name, :email, to: :user, prefix: true | |
33 | + delegate :name, :username, :email, to: :user, prefix: true | |
37 | 34 | |
38 | 35 | scope :guests, where(project_access: GUEST) |
39 | 36 | scope :reporters, where(project_access: REPORTER) |
... | ... | @@ -84,11 +81,6 @@ class UsersProject < ActiveRecord::Base |
84 | 81 | end |
85 | 82 | end |
86 | 83 | |
87 | - GitoliteWorker.perform_async( | |
88 | - :update_repositories, | |
89 | - project_ids | |
90 | - ) | |
91 | - | |
92 | 84 | true |
93 | 85 | rescue |
94 | 86 | false |
... | ... | @@ -103,11 +95,6 @@ class UsersProject < ActiveRecord::Base |
103 | 95 | end |
104 | 96 | end |
105 | 97 | |
106 | - GitoliteWorker.perform_async( | |
107 | - :update_repositories, | |
108 | - project_ids | |
109 | - ) | |
110 | - | |
111 | 98 | true |
112 | 99 | rescue |
113 | 100 | false |
... | ... | @@ -136,10 +123,6 @@ class UsersProject < ActiveRecord::Base |
136 | 123 | end |
137 | 124 | end |
138 | 125 | |
139 | - def update_repository | |
140 | - project.update_repository | |
141 | - end | |
142 | - | |
143 | 126 | def project_access_human |
144 | 127 | Project.access_options.key(self.project_access) |
145 | 128 | end | ... | ... |
app/observers/key_observer.rb
... | ... | @@ -3,20 +3,17 @@ class KeyObserver < ActiveRecord::Observer |
3 | 3 | |
4 | 4 | def after_save(key) |
5 | 5 | GitoliteWorker.perform_async( |
6 | - :set_key, | |
7 | - key.identifier, | |
8 | - key.key, | |
9 | - key.projects.map(&:id) | |
6 | + :add_key, | |
7 | + key.shell_id, | |
8 | + key.key | |
10 | 9 | ) |
11 | 10 | end |
12 | 11 | |
13 | 12 | def after_destroy(key) |
14 | - return if key.is_deploy_key && !key.last_deploy? | |
15 | - | |
16 | 13 | GitoliteWorker.perform_async( |
17 | 14 | :remove_key, |
18 | - key.identifier, | |
19 | - key.projects.map(&:id) | |
15 | + key.shell_id, | |
16 | + key.key, | |
20 | 17 | ) |
21 | 18 | end |
22 | 19 | end | ... | ... |
app/observers/note_observer.rb
... | ... | @@ -11,7 +11,9 @@ class NoteObserver < ActiveRecord::Observer |
11 | 11 | notify_team(note) |
12 | 12 | elsif note.notify_author |
13 | 13 | # Notify only author of resource |
14 | - Notify.delay.note_commit_email(note.noteable.author_email, note.id) | |
14 | + if note.commit_author | |
15 | + Notify.delay.note_commit_email(note.commit_author.id, note.id) | |
16 | + end | |
15 | 17 | else |
16 | 18 | # Otherwise ignore it |
17 | 19 | nil | ... | ... |
app/observers/project_observer.rb
1 | 1 | class ProjectObserver < ActiveRecord::Observer |
2 | 2 | def after_create(project) |
3 | - project.update_repository | |
3 | + GitoliteWorker.perform_async( | |
4 | + :add_repository, | |
5 | + project.path_with_namespace | |
6 | + ) | |
7 | + | |
8 | + log_info("#{project.owner.name} created a new project \"#{project.name_with_namespace}\"") | |
4 | 9 | end |
5 | 10 | |
6 | 11 | def after_update(project) |
... | ... | @@ -8,14 +13,14 @@ class ProjectObserver < ActiveRecord::Observer |
8 | 13 | end |
9 | 14 | |
10 | 15 | def after_destroy(project) |
11 | - log_info("Project \"#{project.name}\" was removed") | |
16 | + GitoliteWorker.perform_async( | |
17 | + :remove_repository, | |
18 | + project.path_with_namespace | |
19 | + ) | |
12 | 20 | |
13 | 21 | project.satellite.destroy |
14 | - project.destroy_repository | |
15 | - end | |
16 | 22 | |
17 | - def after_create project | |
18 | - log_info("#{project.owner.name} created a new project \"#{project.name_with_namespace}\"") | |
23 | + log_info("Project \"#{project.name}\" was removed") | |
19 | 24 | end |
20 | 25 | |
21 | 26 | protected | ... | ... |
app/views/admin/dashboard/index.html.haml
... | ... | @@ -6,7 +6,7 @@ |
6 | 6 | = link_to admin_projects_path do |
7 | 7 | %h1= Project.count |
8 | 8 | %hr |
9 | - = link_to 'New Project', new_project_path, class: "btn small" | |
9 | + = link_to 'New Project', new_project_path, class: "btn btn-small" | |
10 | 10 | .span4 |
11 | 11 | .ui-box |
12 | 12 | %h5.title Groups |
... | ... | @@ -14,7 +14,7 @@ |
14 | 14 | = link_to admin_groups_path do |
15 | 15 | %h1= Group.count |
16 | 16 | %hr |
17 | - = link_to 'New Group', new_admin_group_path, class: "btn small" | |
17 | + = link_to 'New Group', new_admin_group_path, class: "btn btn-small" | |
18 | 18 | .span4 |
19 | 19 | .ui-box |
20 | 20 | %h5.title Users |
... | ... | @@ -22,7 +22,7 @@ |
22 | 22 | = link_to admin_users_path do |
23 | 23 | %h1= User.count |
24 | 24 | %hr |
25 | - = link_to 'New User', new_admin_user_path, class: "btn small" | |
25 | + = link_to 'New User', new_admin_user_path, class: "btn btn-small" | |
26 | 26 | |
27 | 27 | .row |
28 | 28 | .span4 |
... | ... | @@ -31,7 +31,7 @@ |
31 | 31 | - @projects.each do |project| |
32 | 32 | %p |
33 | 33 | = link_to project.name_with_namespace, [:admin, project] |
34 | - %span.light.right | |
34 | + %span.light.pull-right | |
35 | 35 | = time_ago_in_words project.created_at |
36 | 36 | ago |
37 | 37 | |
... | ... | @@ -42,7 +42,7 @@ |
42 | 42 | %p |
43 | 43 | = link_to [:admin, user] do |
44 | 44 | = user.name |
45 | - %span.light.right | |
45 | + %span.light.pull-right | |
46 | 46 | = time_ago_in_words user.created_at |
47 | 47 | ago |
48 | 48 | |
... | ... | @@ -51,25 +51,25 @@ |
51 | 51 | %hr |
52 | 52 | %p |
53 | 53 | Issues |
54 | - %span.light.right | |
54 | + %span.light.pull-right | |
55 | 55 | = Issue.count |
56 | 56 | %p |
57 | 57 | Merge Requests |
58 | - %span.light.right | |
58 | + %span.light.pull-right | |
59 | 59 | = MergeRequest.count |
60 | 60 | %p |
61 | 61 | Notes |
62 | - %span.light.right | |
62 | + %span.light.pull-right | |
63 | 63 | = Note.count |
64 | 64 | %p |
65 | 65 | Snippets |
66 | - %span.light.right | |
66 | + %span.light.pull-right | |
67 | 67 | = Snippet.count |
68 | 68 | %p |
69 | 69 | SSH Keys |
70 | - %span.light.right | |
70 | + %span.light.pull-right | |
71 | 71 | = Key.count |
72 | 72 | %p |
73 | 73 | Milestones |
74 | - %span.light.right | |
74 | + %span.light.pull-right | |
75 | 75 | = Milestone.count | ... | ... |
app/views/admin/groups/edit.html.haml
... | ... | @@ -2,7 +2,7 @@ |
2 | 2 | %hr |
3 | 3 | = form_for [:admin, @group] do |f| |
4 | 4 | - if @group.errors.any? |
5 | - .alert-message.block-message.error | |
5 | + .alert.alert-error | |
6 | 6 | %span= @group.errors.full_messages.first |
7 | 7 | .clearfix.group_name_holder |
8 | 8 | = f.label :name do |
... | ... | @@ -24,5 +24,5 @@ |
24 | 24 | %li It will change the git path to repositories under this group. |
25 | 25 | |
26 | 26 | .form-actions |
27 | - = f.submit 'Rename group', class: "btn danger" | |
28 | - = link_to 'Cancel', admin_groups_path, class: "btn cancel-btn" | |
27 | + = f.submit 'Rename group', class: "btn btn-remove" | |
28 | + = link_to 'Cancel', admin_groups_path, class: "btn btn-cancel" | ... | ... |
app/views/admin/groups/index.html.haml
... | ... | @@ -4,11 +4,11 @@ |
4 | 4 | allows you to keep projects organized. |
5 | 5 | Use groups for uniting related projects. |
6 | 6 | |
7 | - = link_to 'New Group', new_admin_group_path, class: "btn small right" | |
7 | + = link_to 'New Group', new_admin_group_path, class: "btn btn-small pull-right" | |
8 | 8 | %br |
9 | 9 | = form_tag admin_groups_path, method: :get, class: 'form-inline' do |
10 | 10 | = text_field_tag :name, params[:name], class: "xlarge" |
11 | - = submit_tag "Search", class: "btn submit primary" | |
11 | + = submit_tag "Search", class: "btn submit btn-primary" | |
12 | 12 | |
13 | 13 | %table |
14 | 14 | %thead |
... | ... | @@ -30,6 +30,6 @@ |
30 | 30 | %td |
31 | 31 | = link_to group.owner_name, admin_user_path(group.owner_id) |
32 | 32 | %td.bgred |
33 | - = link_to 'Rename', edit_admin_group_path(group), id: "edit_#{dom_id(group)}", class: "btn small" | |
34 | - = link_to 'Destroy', [:admin, group], confirm: "REMOVE #{group.name}? Are you sure?", method: :delete, class: "btn small danger" | |
33 | + = link_to 'Rename', edit_admin_group_path(group), id: "edit_#{dom_id(group)}", class: "btn btn-small" | |
34 | + = link_to 'Destroy', [:admin, group], confirm: "REMOVE #{group.name}? Are you sure?", method: :delete, class: "btn btn-small btn-remove" | |
35 | 35 | = paginate @groups, theme: "admin" | ... | ... |
app/views/admin/groups/new.html.haml
... | ... | @@ -2,7 +2,7 @@ |
2 | 2 | %hr |
3 | 3 | = form_for [:admin, @group] do |f| |
4 | 4 | - if @group.errors.any? |
5 | - .alert-message.block-message.error | |
5 | + .alert.alert-error | |
6 | 6 | %span= @group.errors.full_messages.first |
7 | 7 | .clearfix |
8 | 8 | = f.label :name do |
... | ... | @@ -10,7 +10,7 @@ |
10 | 10 | .input |
11 | 11 | = f.text_field :name, placeholder: "Ex. OpenSource", class: "xxlarge left" |
12 | 12 | |
13 | - = f.submit 'Create group', class: "btn primary" | |
13 | + = f.submit 'Create group', class: "btn btn-primary" | |
14 | 14 | %hr |
15 | 15 | .padded |
16 | 16 | %ul | ... | ... |
app/views/admin/groups/show.html.haml
... | ... | @@ -14,7 +14,7 @@ |
14 | 14 | %td |
15 | 15 | = @group.name |
16 | 16 | |
17 | - = link_to edit_admin_group_path(@group), class: "btn btn-small right" do | |
17 | + = link_to edit_admin_group_path(@group), class: "btn btn-small pull-right" do | |
18 | 18 | %i.icon-edit |
19 | 19 | Rename |
20 | 20 | %tr |
... | ... | @@ -29,7 +29,7 @@ |
29 | 29 | Owner: |
30 | 30 | %td |
31 | 31 | = @group.owner_name |
32 | - .right | |
32 | + .pull-right | |
33 | 33 | = link_to "#", class: "btn btn-small change-owner-link" do |
34 | 34 | %i.icon-edit |
35 | 35 | Change owner |
... | ... | @@ -42,7 +42,7 @@ |
42 | 42 | = form_for [:admin, @group] do |f| |
43 | 43 | = f.select :owner_id, User.all.map { |user| [user.name, user.id] }, {}, {class: 'chosen'} |
44 | 44 | %div |
45 | - = f.submit 'Change Owner', class: "btn danger" | |
45 | + = f.submit 'Change Owner', class: "btn btn-remove" | |
46 | 46 | = link_to "Cancel", "#", class: "btn change-owner-cancel-link" |
47 | 47 | |
48 | 48 | - if @group.projects.any? |
... | ... | @@ -63,7 +63,7 @@ |
63 | 63 | %span.monospace= project.path_with_namespace + ".git" |
64 | 64 | %td= project.users.count |
65 | 65 | %td.bgred |
66 | - = link_to 'Transfer project to global namespace', remove_project_admin_group_path(@group, project_id: project.id), confirm: 'Remove project from group and move to global namespace. Are you sure?', method: :delete, class: "btn danger small" | |
66 | + = link_to 'Transfer project to global namespace', remove_project_admin_group_path(@group, project_id: project.id), confirm: 'Remove project from group and move to global namespace. Are you sure?', method: :delete, class: "btn btn-remove small" | |
67 | 67 | |
68 | 68 | = form_tag project_teams_update_admin_group_path(@group), id: "new_team_member", class: "bulk_import", method: :put do |
69 | 69 | %table.zebra-striped |
... | ... | @@ -88,7 +88,7 @@ |
88 | 88 | %td= select_tag :project_access, options_for_select(Project.access_options), {class: "project-access-select chosen span3"} |
89 | 89 | |
90 | 90 | %tr |
91 | - %td= submit_tag 'Add user to projects in group', class: "btn primary" | |
91 | + %td= submit_tag 'Add user to projects in group', class: "btn btn-primary" | |
92 | 92 | %td |
93 | 93 | Read more about project permissions |
94 | 94 | %strong= link_to "here", help_permissions_path, class: "vlink" |
... | ... | @@ -110,7 +110,7 @@ |
110 | 110 | .input |
111 | 111 | = select_tag :project_ids, options_from_collection_for_select(@projects , :id, :name_with_namespace), multiple: true, data: {placeholder: 'Select projects'}, class: 'chosen span5' |
112 | 112 | .form-actions |
113 | - = submit_tag 'Add', class: "btn primary" | |
113 | + = submit_tag 'Add', class: "btn btn-primary" | |
114 | 114 | |
115 | 115 | :javascript |
116 | 116 | $(function(){ | ... | ... |
app/views/admin/hooks/index.html.haml
... | ... | @@ -7,7 +7,7 @@ |
7 | 7 | |
8 | 8 | = form_for @hook, as: :hook, url: admin_hooks_path, html: { class: 'form-inline' } do |f| |
9 | 9 | -if @hook.errors.any? |
10 | - .alert-message.block-message.error | |
10 | + .alert.alert-error | |
11 | 11 | - @hook.errors.full_messages.each do |msg| |
12 | 12 | %p= msg |
13 | 13 | .clearfix |
... | ... | @@ -15,7 +15,7 @@ |
15 | 15 | .input |
16 | 16 | = f.text_field :url, class: "text_field xxlarge" |
17 | 17 | |
18 | - = f.submit "Add System Hook", class: "btn primary" | |
18 | + = f.submit "Add System Hook", class: "btn btn-primary" | |
19 | 19 | %hr |
20 | 20 | |
21 | 21 | -if @hooks.any? |
... | ... | @@ -33,7 +33,7 @@ |
33 | 33 | %td |
34 | 34 | = link_to admin_hook_path(hook) do |
35 | 35 | %strong= hook.url |
36 | - = link_to 'Test Hook', admin_hook_test_path(hook), class: "btn small right" | |
36 | + = link_to 'Test Hook', admin_hook_test_path(hook), class: "btn btn-small pull-right" | |
37 | 37 | %td POST |
38 | 38 | %td |
39 | - = link_to 'Remove', admin_hook_path(hook), confirm: 'Are you sure?', method: :delete, class: "danger btn small right" | |
39 | + = link_to 'Remove', admin_hook_path(hook), confirm: 'Are you sure?', method: :delete, class: "btn btn-remove btn-small pull-right" | ... | ... |
app/views/admin/logs/show.html.haml
... | ... | @@ -15,7 +15,7 @@ |
15 | 15 | .file_title |
16 | 16 | %i.icon-file |
17 | 17 | githost.log |
18 | - .right | |
18 | + .pull-right | |
19 | 19 | = link_to '#', class: 'log-bottom' do |
20 | 20 | %i.icon-arrow-down |
21 | 21 | Scroll down |
... | ... | @@ -29,7 +29,7 @@ |
29 | 29 | .file_title |
30 | 30 | %i.icon-file |
31 | 31 | application.log |
32 | - .right | |
32 | + .pull-right | |
33 | 33 | = link_to '#', class: 'log-bottom' do |
34 | 34 | %i.icon-arrow-down |
35 | 35 | Scroll down |
... | ... | @@ -43,7 +43,7 @@ |
43 | 43 | .file_title |
44 | 44 | %i.icon-file |
45 | 45 | production.log |
46 | - .right | |
46 | + .pull-right | |
47 | 47 | = link_to '#', class: 'log-bottom' do |
48 | 48 | %i.icon-arrow-down |
49 | 49 | Scroll down |
... | ... | @@ -57,7 +57,7 @@ |
57 | 57 | .file_title |
58 | 58 | %i.icon-file |
59 | 59 | sidekiq.log |
60 | - .right | |
60 | + .pull-right | |
61 | 61 | = link_to '#', class: 'log-bottom' do |
62 | 62 | %i.icon-arrow-down |
63 | 63 | Scroll down | ... | ... |
app/views/admin/projects/_form.html.haml
1 | 1 | = form_for [:admin, project] do |f| |
2 | 2 | -if project.errors.any? |
3 | - .alert-message.block-message.error | |
3 | + .alert.alert-error | |
4 | 4 | %ul |
5 | 5 | - project.errors.full_messages.each do |msg| |
6 | 6 | %li= msg |
... | ... | @@ -65,8 +65,8 @@ |
65 | 65 | |
66 | 66 | |
67 | 67 | .actions |
68 | - = f.submit 'Save Project', class: "btn save-btn" | |
69 | - = link_to 'Cancel', admin_projects_path, class: "btn cancel-btn" | |
68 | + = f.submit 'Save Project', class: "btn btn-save" | |
69 | + = link_to 'Cancel', admin_projects_path, class: "btn btn-cancel" | |
70 | 70 | |
71 | 71 | |
72 | 72 | ... | ... |
app/views/admin/projects/index.html.haml
1 | 1 | %h3.page_title |
2 | 2 | Projects |
3 | - = link_to 'New Project', new_project_path, class: "btn small right" | |
3 | + = link_to 'New Project', new_project_path, class: "btn btn-small pull-right" | |
4 | 4 | |
5 | 5 | %hr |
6 | 6 | |
... | ... | @@ -37,7 +37,7 @@ |
37 | 37 | |
38 | 38 | |
39 | 39 | .form-actions |
40 | - = submit_tag "Search", class: "btn submit primary" | |
40 | + = submit_tag "Search", class: "btn submit btn-primary" | |
41 | 41 | = link_to "Reset", admin_projects_path, class: "btn" |
42 | 42 | .span8 |
43 | 43 | .ui-box |
... | ... | @@ -51,9 +51,9 @@ |
51 | 51 | - else |
52 | 52 | %i.icon-lock.cgreen |
53 | 53 | = link_to project.name_with_namespace, [:admin, project] |
54 | - .right | |
55 | - = link_to 'Edit', edit_admin_project_path(project), id: "edit_#{dom_id(project)}", class: "btn small" | |
56 | - = link_to 'Destroy', [:admin, project], confirm: "REMOVE #{project.name}? Are you sure?", method: :delete, class: "btn small danger" | |
54 | + .pull-right | |
55 | + = link_to 'Edit', edit_admin_project_path(project), id: "edit_#{dom_id(project)}", class: "btn btn-small" | |
56 | + = link_to 'Destroy', [:admin, project], confirm: "REMOVE #{project.name}? Are you sure?", method: :delete, class: "btn btn-small btn-remove" | |
57 | 57 | - if @projects.blank? |
58 | 58 | %p.nothing_here_message 0 projects matches |
59 | 59 | - else | ... | ... |
app/views/admin/projects/members/_form.html.haml
1 | 1 | = form_for @team_member_relation, as: :team_member, url: admin_project_member_path(@project, @member) do |f| |
2 | 2 | -if @team_member_relation.errors.any? |
3 | - .alert-message.block-message.error | |
3 | + .alert.alert-error | |
4 | 4 | %ul |
5 | 5 | - @team_member_relation.errors.full_messages.each do |msg| |
6 | 6 | %li= msg |
... | ... | @@ -12,5 +12,5 @@ |
12 | 12 | |
13 | 13 | %br |
14 | 14 | .actions |
15 | - = f.submit 'Save', class: "btn primary" | |
15 | + = f.submit 'Save', class: "btn btn-primary" | |
16 | 16 | = link_to 'Cancel', :back, class: "btn" | ... | ... |
app/views/admin/projects/show.html.haml
1 | 1 | %h3.page_title |
2 | 2 | Project: #{@project.name_with_namespace} |
3 | - = link_to edit_admin_project_path(@project), class: "btn right" do | |
3 | + = link_to edit_admin_project_path(@project), class: "btn pull-right" do | |
4 | 4 | %i.icon-edit |
5 | 5 | Edit |
6 | 6 | |
... | ... | @@ -129,8 +129,8 @@ |
129 | 129 | %td |
130 | 130 | = link_to tm.name, admin_user_path(tm) |
131 | 131 | %td= @project.project_access_human(tm) |
132 | - %td= link_to 'Edit Access', edit_admin_project_member_path(@project, tm), class: "btn small" | |
133 | - %td= link_to 'Remove from team', admin_project_member_path(@project, tm), confirm: 'Are you sure?', method: :delete, class: "btn danger small" | |
132 | + %td= link_to 'Edit Access', edit_admin_project_member_path(@project, tm), class: "btn btn-small" | |
133 | + %td= link_to 'Remove from team', admin_project_member_path(@project, tm), confirm: 'Are you sure?', method: :delete, class: "btn btn-remove small" | |
134 | 134 | |
135 | 135 | %br |
136 | 136 | %h5 Add new team member |
... | ... | @@ -147,7 +147,7 @@ |
147 | 147 | %td= select_tag :project_access, options_for_select(Project.access_options), {class: "project-access-select chosen span3"} |
148 | 148 | |
149 | 149 | %tr |
150 | - %td= submit_tag 'Add', class: "btn primary" | |
150 | + %td= submit_tag 'Add', class: "btn btn-primary" | |
151 | 151 | %td |
152 | 152 | Read more about project permissions |
153 | 153 | %strong= link_to "here", help_permissions_path, class: "vlink" | ... | ... |
app/views/admin/teams/edit.html.haml
... | ... | @@ -2,7 +2,7 @@ |
2 | 2 | %hr |
3 | 3 | = form_for @team, url: admin_team_path(@team), method: :put do |f| |
4 | 4 | - if @team.errors.any? |
5 | - .alert-message.block-message.error | |
5 | + .alert.alert-error | |
6 | 6 | %span= @team.errors.full_messages.first |
7 | 7 | .clearfix.team_name_holder |
8 | 8 | = f.label :name do |
... | ... | @@ -19,5 +19,5 @@ |
19 | 19 | %li It will change web url for access team and team projects. |
20 | 20 | |
21 | 21 | .form-actions |
22 | - = f.submit 'Rename team', class: "btn danger" | |
23 | - = link_to 'Cancel', admin_teams_path, class: "btn cancel-btn" | |
22 | + = f.submit 'Rename team', class: "btn btn-remove" | |
23 | + = link_to 'Cancel', admin_teams_path, class: "btn btn-cancel" | ... | ... |
app/views/admin/teams/index.html.haml
... | ... | @@ -3,12 +3,12 @@ |
3 | 3 | %small |
4 | 4 | simple Teams description |
5 | 5 | |
6 | - = link_to 'New Team', new_admin_team_path, class: "btn small right" | |
6 | + = link_to 'New Team', new_admin_team_path, class: "btn btn-small pull-right" | |
7 | 7 | %br |
8 | 8 | |
9 | 9 | = form_tag admin_teams_path, method: :get, class: 'form-inline' do |
10 | 10 | = text_field_tag :name, params[:name], class: "xlarge" |
11 | - = submit_tag "Search", class: "btn submit primary" | |
11 | + = submit_tag "Search", class: "btn submit btn-primary" | |
12 | 12 | |
13 | 13 | %table |
14 | 14 | %thead |
... | ... | @@ -32,7 +32,7 @@ |
32 | 32 | %td |
33 | 33 | = link_to team.owner.name, admin_user_path(team.owner_id) |
34 | 34 | %td.bgred |
35 | - = link_to 'Rename', edit_admin_team_path(team), id: "edit_#{dom_id(team)}", class: "btn small" | |
36 | - = link_to 'Destroy', admin_team_path(team), confirm: "REMOVE #{team.name}? Are you sure?", method: :delete, class: "btn small danger" | |
35 | + = link_to 'Rename', edit_admin_team_path(team), id: "edit_#{dom_id(team)}", class: "btn btn-small" | |
36 | + = link_to 'Destroy', admin_team_path(team), confirm: "REMOVE #{team.name}? Are you sure?", method: :delete, class: "btn btn-small btn-remove" | |
37 | 37 | |
38 | 38 | = paginate @teams, theme: "admin" | ... | ... |
app/views/admin/teams/members/_form.html.haml
1 | 1 | = form_tag admin_team_member_path(@team, @member), method: :put do |
2 | 2 | -if @member.errors.any? |
3 | - .alert-message.block-message.error | |
3 | + .alert.alert-error | |
4 | 4 | %ul |
5 | 5 | - @member.errors.full_messages.each do |msg| |
6 | 6 | %li= msg |
... | ... | @@ -16,5 +16,5 @@ |
16 | 16 | |
17 | 17 | %br |
18 | 18 | .actions |
19 | - = submit_tag 'Save', class: "btn primary" | |
19 | + = submit_tag 'Save', class: "btn btn-primary" | |
20 | 20 | = link_to 'Cancel', :back, class: "btn" | ... | ... |
app/views/admin/teams/members/new.html.haml
app/views/admin/teams/new.html.haml
... | ... | @@ -2,7 +2,7 @@ |
2 | 2 | %hr |
3 | 3 | = form_for @team, url: admin_teams_path do |f| |
4 | 4 | - if @team.errors.any? |
5 | - .alert-message.block-message.error | |
5 | + .alert.alert-error | |
6 | 6 | %span= @team.errors.full_messages.first |
7 | 7 | .clearfix |
8 | 8 | = f.label :name do |
... | ... | @@ -10,7 +10,7 @@ |
10 | 10 | .input |
11 | 11 | = f.text_field :name, placeholder: "Ex. OpenSource", class: "xxlarge left" |
12 | 12 | |
13 | - = f.submit 'Create team', class: "btn primary" | |
13 | + = f.submit 'Create team', class: "btn btn-primary" | |
14 | 14 | %hr |
15 | 15 | .padded |
16 | 16 | %ul | ... | ... |
app/views/admin/teams/projects/_form.html.haml
1 | 1 | = form_tag admin_team_project_path(@team, @project), method: :put do |
2 | 2 | -if @project.errors.any? |
3 | - .alert-message.block-message.error | |
3 | + .alert.alert-error | |
4 | 4 | %ul |
5 | 5 | - @project.errors.full_messages.each do |msg| |
6 | 6 | %li= msg |
... | ... | @@ -12,5 +12,5 @@ |
12 | 12 | |
13 | 13 | %br |
14 | 14 | .actions |
15 | - = submit_tag 'Save', class: "btn primary" | |
15 | + = submit_tag 'Save', class: "btn btn-primary" | |
16 | 16 | = link_to 'Cancel', :back, class: "btn" | ... | ... |
app/views/admin/teams/projects/new.html.haml
... | ... | @@ -20,4 +20,4 @@ |
20 | 20 | %tr |
21 | 21 | %td= select_tag :project_ids, options_from_collection_for_select(@projects , :id, :name_with_namespace), multiple: true, data: {placeholder: 'Select projects'}, class: 'chosen span5' |
22 | 22 | %td= select_tag :greatest_project_access, options_for_select(Project.access_options), {class: "project-access-select chosen span3" } |
23 | - %td= submit_tag 'Add', class: "btn primary", id: :assign_projects_to_team | |
23 | + %td= submit_tag 'Add', class: "btn btn-primary", id: :assign_projects_to_team | ... | ... |
app/views/admin/teams/show.html.haml
... | ... | @@ -14,7 +14,7 @@ |
14 | 14 | %td |
15 | 15 | = @team.name |
16 | 16 | |
17 | - = link_to edit_admin_team_path(@team), class: "btn btn-small right" do | |
17 | + = link_to edit_admin_team_path(@team), class: "btn btn-small pull-right" do | |
18 | 18 | %i.icon-edit |
19 | 19 | Rename |
20 | 20 | %tr |
... | ... | @@ -23,7 +23,7 @@ |
23 | 23 | Owner: |
24 | 24 | %td |
25 | 25 | = @team.owner.name |
26 | - .right | |
26 | + .pull-right | |
27 | 27 | = link_to "#", class: "btn btn-small change-owner-link" do |
28 | 28 | %i.icon-edit |
29 | 29 | Change owner |
... | ... | @@ -36,13 +36,13 @@ |
36 | 36 | = form_for @team, url: admin_team_path(@team) do |f| |
37 | 37 | = f.select :owner_id, User.all.map { |user| [user.name, user.id] }, {}, {class: 'chosen'} |
38 | 38 | %div |
39 | - = f.submit 'Change Owner', class: "btn danger" | |
39 | + = f.submit 'Change Owner', class: "btn btn-remove" | |
40 | 40 | = link_to "Cancel", "#", class: "btn change-owner-cancel-link" |
41 | 41 | |
42 | 42 | %fieldset |
43 | 43 | %legend |
44 | 44 | Members (#{@team.members.count}) |
45 | - %span= link_to 'Add members', new_admin_team_member_path(@team), class: "btn success small right", id: :add_members_to_team | |
45 | + %span= link_to 'Add members', new_admin_team_member_path(@team), class: "btn btn-primary btn-small pull-right", id: :add_members_to_team | |
46 | 46 | - if @team.members.any? |
47 | 47 | %table#members_list |
48 | 48 | %thead |
... | ... | @@ -60,14 +60,14 @@ |
60 | 60 | %td= @team.human_default_projects_access(member) |
61 | 61 | %td= @team.admin?(member) ? "Admin" : "Member" |
62 | 62 | %td.bgred |
63 | - = link_to 'Edit', edit_admin_team_member_path(@team, member), class: "btn small" | |
63 | + = link_to 'Edit', edit_admin_team_member_path(@team, member), class: "btn btn-small" | |
64 | 64 | |
65 | - = link_to 'Remove', admin_team_member_path(@team, member), confirm: 'Remove member from team. Are you sure?', method: :delete, class: "btn danger small", id: "remove_member_#{member.id}" | |
65 | + = link_to 'Remove', admin_team_member_path(@team, member), confirm: 'Remove member from team. Are you sure?', method: :delete, class: "btn btn-remove btn-small", id: "remove_member_#{member.id}" | |
66 | 66 | |
67 | 67 | %fieldset |
68 | 68 | %legend |
69 | 69 | Projects (#{@team.projects.count}) |
70 | - %span= link_to 'Add projects', new_admin_team_project_path(@team), class: "btn success small right", id: :assign_projects_to_team | |
70 | + %span= link_to 'Add projects', new_admin_team_project_path(@team), class: "btn btn-primary btn-small pull-right", id: :assign_projects_to_team | |
71 | 71 | - if @team.projects.any? |
72 | 72 | %table#projects_list |
73 | 73 | %thead |
... | ... | @@ -82,9 +82,9 @@ |
82 | 82 | %td |
83 | 83 | %span= @team.human_max_project_access(project) |
84 | 84 | %td.bgred |
85 | - = link_to 'Edit', edit_admin_team_project_path(@team, project), class: "btn small" | |
85 | + = link_to 'Edit', edit_admin_team_project_path(@team, project), class: "btn btn-small" | |
86 | 86 | |
87 | - = link_to 'Relegate', admin_team_project_path(@team, project), confirm: 'Remove project from team. Are you sure?', method: :delete, class: "btn danger small", id: "relegate_project_#{project.id}" | |
87 | + = link_to 'Relegate', admin_team_project_path(@team, project), confirm: 'Remove project from team. Are you sure?', method: :delete, class: "btn btn-remove small", id: "relegate_project_#{project.id}" | |
88 | 88 | |
89 | 89 | :javascript |
90 | 90 | $(function(){ | ... | ... |
app/views/admin/users/_form.html.haml
... | ... | @@ -63,10 +63,10 @@ |
63 | 63 | .alert.alert-error |
64 | 64 | - if @admin_user.blocked |
65 | 65 | %p This user is blocked and is not able to login to GitLab |
66 | - = link_to 'Unblock User', unblock_admin_user_path(@admin_user), method: :put, class: "btn small" | |
66 | + = link_to 'Unblock User', unblock_admin_user_path(@admin_user), method: :put, class: "btn btn-small" | |
67 | 67 | - else |
68 | 68 | %p Blocked users will be removed from all projects & will not be able to login to GitLab. |
69 | - = link_to 'Block User', block_admin_user_path(@admin_user), confirm: 'USER WILL BE BLOCKED! Are you sure?', method: :put, class: "btn small danger" | |
69 | + = link_to 'Block User', block_admin_user_path(@admin_user), confirm: 'USER WILL BE BLOCKED! Are you sure?', method: :put, class: "btn btn-small btn-remove" | |
70 | 70 | %fieldset |
71 | 71 | %legend Profile |
72 | 72 | .clearfix |
... | ... | @@ -80,8 +80,8 @@ |
80 | 80 | .input= f.text_field :twitter |
81 | 81 | |
82 | 82 | .actions |
83 | - = f.submit 'Save', class: "btn save-btn" | |
83 | + = f.submit 'Save', class: "btn btn-save" | |
84 | 84 | - if @admin_user.new_record? |
85 | - = link_to 'Cancel', admin_users_path, class: "btn cancel-btn" | |
85 | + = link_to 'Cancel', admin_users_path, class: "btn btn-cancel" | |
86 | 86 | - else |
87 | - = link_to 'Cancel', admin_user_path(@admin_user), class: "btn cancel-btn" | |
87 | + = link_to 'Cancel', admin_user_path(@admin_user), class: "btn btn-cancel" | ... | ... |
app/views/admin/users/index.html.haml
1 | 1 | %h3.page_title |
2 | 2 | Users |
3 | - = link_to 'New User', new_admin_user_path, class: "btn small right" | |
3 | + = link_to 'New User', new_admin_user_path, class: "btn btn-small pull-right" | |
4 | 4 | %br |
5 | 5 | |
6 | 6 | = form_tag admin_users_path, method: :get, class: 'form-inline' do |
7 | 7 | = text_field_tag :name, params[:name], class: "xlarge" |
8 | - = submit_tag "Search", class: "btn submit primary" | |
8 | + = submit_tag "Search", class: "btn submit btn-primary" | |
9 | 9 | %ul.nav.nav-tabs |
10 | 10 | %li{class: "#{'active' unless params[:filter]}"} |
11 | 11 | = link_to admin_users_path do |
... | ... | @@ -44,15 +44,15 @@ |
44 | 44 | %td= user.username |
45 | 45 | %td= user.email |
46 | 46 | %td= user.users_projects.count |
47 | - %td= link_to 'Edit', edit_admin_user_path(user), id: "edit_#{dom_id(user)}", class: "btn small" | |
47 | + %td= link_to 'Edit', edit_admin_user_path(user), id: "edit_#{dom_id(user)}", class: "btn btn-small" | |
48 | 48 | %td.bgred |
49 | 49 | - if user == current_user |
50 | 50 | %span.cred It's you! |
51 | 51 | - else |
52 | 52 | - if user.blocked |
53 | - = link_to 'Unblock', unblock_admin_user_path(user), method: :put, class: "btn small success" | |
53 | + = link_to 'Unblock', unblock_admin_user_path(user), method: :put, class: "btn btn-small success" | |
54 | 54 | - else |
55 | - = link_to 'Block', block_admin_user_path(user), confirm: 'USER WILL BE BLOCKED! Are you sure?', method: :put, class: "btn small danger" | |
56 | - = link_to 'Destroy', [:admin, user], confirm: "USER #{user.name} WILL BE REMOVED! Are you sure?", method: :delete, class: "btn small danger" | |
55 | + = link_to 'Block', block_admin_user_path(user), confirm: 'USER WILL BE BLOCKED! Are you sure?', method: :put, class: "btn btn-small btn-remove" | |
56 | + = link_to 'Destroy', [:admin, user], confirm: "USER #{user.name} WILL BE REMOVED! Are you sure?", method: :delete, class: "btn btn-small btn-remove" | |
57 | 57 | |
58 | 58 | = paginate @admin_users, theme: "admin" | ... | ... |
app/views/admin/users/show.html.haml
... | ... | @@ -4,7 +4,7 @@ |
4 | 4 | %small Blocked |
5 | 5 | - if @admin_user.admin |
6 | 6 | %small Administrator |
7 | - = link_to edit_admin_user_path(@admin_user), class: "btn right" do | |
7 | + = link_to edit_admin_user_path(@admin_user), class: "btn pull-right" do | |
8 | 8 | %i.icon-edit |
9 | 9 | Edit |
10 | 10 | |
... | ... | @@ -86,7 +86,7 @@ |
86 | 86 | %td= select_tag :project_access, options_for_select(Project.access_options), class: "project-access-select chosen span3" |
87 | 87 | |
88 | 88 | %tr |
89 | - %td= submit_tag 'Add', class: "btn primary" | |
89 | + %td= submit_tag 'Add', class: "btn btn-primary" | |
90 | 90 | %td |
91 | 91 | Read more about project permissions |
92 | 92 | %strong= link_to "here", help_permissions_path, class: "vlink" |
... | ... | @@ -123,5 +123,5 @@ |
123 | 123 | %tr |
124 | 124 | %td= link_to project.name_with_namespace, admin_project_path(project) |
125 | 125 | %td= tm.project_access_human |
126 | - %td= link_to 'Edit Access', edit_admin_project_member_path(project, tm.user), class: "btn small" | |
127 | - %td= link_to 'Remove from team', admin_project_member_path(project, tm.user), confirm: 'Are you sure?', method: :delete, class: "btn small danger" | |
126 | + %td= link_to 'Edit Access', edit_admin_project_member_path(project, tm.user), class: "btn btn-small" | |
127 | + %td= link_to 'Remove from team', admin_project_member_path(project, tm.user), confirm: 'Are you sure?', method: :delete, class: "btn btn-small btn-remove" | ... | ... |
app/views/blame/_head.html.haml
app/views/commit/huge_commit.html.haml
app/views/commit/show.html.haml
app/views/commits/_commit_box.html.haml
1 | 1 | .ui-box.ui-box-show |
2 | 2 | .ui-box-head |
3 | - .right | |
3 | + .pull-right | |
4 | 4 | - if @notes_count > 0 |
5 | 5 | %span.btn.disabled.grouped |
6 | 6 | %i.icon-comment |
... | ... | @@ -13,7 +13,7 @@ |
13 | 13 | %ul.dropdown-menu |
14 | 14 | %li= link_to "Email Patches", project_commit_path(@project, @commit, format: :patch) |
15 | 15 | %li= link_to "Plain Diff", project_commit_path(@project, @commit, format: :diff) |
16 | - = link_to project_tree_path(@project, @commit), class: "btn primary grouped" do | |
16 | + = link_to project_tree_path(@project, @commit), class: "btn btn-primary grouped" do | |
17 | 17 | %span Browse Code » |
18 | 18 | %h3.commit-title.page_title |
19 | 19 | = gfm escape_once(@commit.title) | ... | ... |
app/views/commits/_diffs.html.haml
1 | 1 | - if @suppress_diff |
2 | - .alert-message.block-message | |
2 | + .alert.alert-block | |
3 | 3 | %p |
4 | - %strong Warning! Large commit with more then #{Commit::DIFF_SAFE_SIZE} files changed. | |
4 | + %strong Warning! Large commit with more than #{Commit::DIFF_SAFE_SIZE} files changed. | |
5 | 5 | %p To prevent performance issue we rejected diff information. |
6 | 6 | %p |
7 | 7 | But if you still want to see diff |
... | ... | @@ -25,7 +25,7 @@ |
25 | 25 | %span= diff.old_path |
26 | 26 | |
27 | 27 | - if @commit.prev_commit |
28 | - = link_to project_tree_path(@project, tree_join(@commit.prev_commit_id, diff.new_path)), {:class => 'btn right view-file'} do | |
28 | + = link_to project_tree_path(@project, tree_join(@commit.prev_commit_id, diff.new_path)), {:class => 'btn pull-right view-file'} do | |
29 | 29 | View file @ |
30 | 30 | %span.commit-short-id= @commit.short_id(6) |
31 | 31 | - else |
... | ... | @@ -33,7 +33,7 @@ |
33 | 33 | - if diff.a_mode && diff.b_mode && diff.a_mode != diff.b_mode |
34 | 34 | %span.file-mode= "#{diff.a_mode} → #{diff.b_mode}" |
35 | 35 | |
36 | - = link_to project_tree_path(@project, tree_join(@commit.id, diff.new_path)), {:class => 'btn very_small right view-file'} do | |
36 | + = link_to project_tree_path(@project, tree_join(@commit.id, diff.new_path)), {:class => 'btn btn-tiny pull-right view-file'} do | |
37 | 37 | View file @ |
38 | 38 | %span.commit-short-id= @commit.short_id(6) |
39 | 39 | ... | ... |
app/views/commits/_head.html.haml
... | ... | @@ -22,7 +22,7 @@ |
22 | 22 | |
23 | 23 | |
24 | 24 | - if current_controller?(:commits) && current_user.private_token |
25 | - %li.right | |
25 | + %li.pull-right | |
26 | 26 | %span.rss-icon |
27 | 27 | = link_to project_commits_path(@project, @ref, {format: :atom, private_token: current_user.private_token}), title: "Feed" do |
28 | 28 | = image_tag "rss_ui.png", title: "feed" | ... | ... |
app/views/compare/_form.html.haml
... | ... | @@ -19,7 +19,7 @@ |
19 | 19 | = text_field_tag :to, params[:to], placeholder: "aa8b4ef", class: "xlarge" |
20 | 20 | .pull-left |
21 | 21 | |
22 | - = submit_tag "Compare", class: "btn primary wide commits-compare-btn" | |
22 | + = submit_tag "Compare", class: "btn btn-primary wide commits-compare-btn" | |
23 | 23 | - if @refs_are_same |
24 | 24 | .alert |
25 | 25 | %span Refs are the same | ... | ... |
app/views/dashboard/_filter.html.haml
... | ... | @@ -25,9 +25,9 @@ |
25 | 25 | %li{class: ("active" if params[:project_id] == project.id.to_s)} |
26 | 26 | = link_to dashboard_filter_path(entity, project_id: project.id) do |
27 | 27 | = project.name_with_namespace |
28 | - %small.right= entities_per_project(project, entity) | |
28 | + %small.pull-right= entities_per_project(project, entity) | |
29 | 29 | |
30 | 30 | %fieldset |
31 | 31 | %hr |
32 | - = link_to "Reset", dashboard_filter_path(entity), class: 'btn right' | |
32 | + = link_to "Reset", dashboard_filter_path(entity), class: 'btn pull-right' | |
33 | 33 | ... | ... |
app/views/dashboard/_groups.html.haml
... | ... | @@ -4,8 +4,8 @@ |
4 | 4 | %small |
5 | 5 | (#{groups.count}) |
6 | 6 | - if current_user.can_create_group? |
7 | - %span.right | |
8 | - = link_to new_group_path, class: "btn very_small info" do | |
7 | + %span.pull-right | |
8 | + = link_to new_group_path, class: "btn btn-tiny info" do | |
9 | 9 | %i.icon-plus |
10 | 10 | New Group |
11 | 11 | %ul.well-list |
... | ... | @@ -13,6 +13,6 @@ |
13 | 13 | %li |
14 | 14 | = link_to group_path(id: group.path), class: dom_class(group) do |
15 | 15 | %strong.well-title= truncate(group.name, length: 35) |
16 | - %span.right.light | |
16 | + %span.pull-right.light | |
17 | 17 | - if group.owner == current_user |
18 | 18 | %i.icon-wrench | ... | ... |
app/views/dashboard/_projects.html.haml
... | ... | @@ -4,8 +4,8 @@ |
4 | 4 | %small |
5 | 5 | (#{@projects_count}) |
6 | 6 | - if current_user.can_create_project? |
7 | - %span.right | |
8 | - = link_to new_project_path, class: "btn very_small info" do | |
7 | + %span.pull-right | |
8 | + = link_to new_project_path, class: "btn btn-tiny info" do | |
9 | 9 | %i.icon-plus |
10 | 10 | New Project |
11 | 11 | ... | ... |
app/views/dashboard/_teams.html.haml
... | ... | @@ -3,8 +3,8 @@ |
3 | 3 | Teams |
4 | 4 | %small |
5 | 5 | (#{@teams.count}) |
6 | - %span.right | |
7 | - = link_to new_team_path, class: "btn very_small info" do | |
6 | + %span.pull-right | |
7 | + = link_to new_team_path, class: "btn btn-tiny info" do | |
8 | 8 | %i.icon-plus |
9 | 9 | New Team |
10 | 10 | %ul.well-list |
... | ... | @@ -12,7 +12,7 @@ |
12 | 12 | %li |
13 | 13 | = link_to team_path(id: team.path), class: dom_class(team) do |
14 | 14 | %strong.well-title= truncate(team.name, length: 35) |
15 | - %span.right.light | |
15 | + %span.pull-right.light | |
16 | 16 | - if team.owner == current_user |
17 | 17 | %i.icon-wrench |
18 | 18 | - tm = current_user.user_team_user_relationships.find_by_user_team_id(team.id) | ... | ... |
app/views/dashboard/_zero_authorized_projects.html.haml
... | ... | @@ -6,7 +6,7 @@ |
6 | 6 | = current_user.projects_limit |
7 | 7 | projects. Click on button below to add a new one |
8 | 8 | .link_holder |
9 | - = link_to new_project_path, class: "btn primary" do | |
9 | + = link_to new_project_path, class: "btn btn-primary" do | |
10 | 10 | New Project » |
11 | 11 | - else |
12 | 12 | If you will be added to project - it will be displayed here | ... | ... |
app/views/dashboard/issues.html.haml
app/views/dashboard/merge_requests.html.haml
app/views/dashboard/projects.html.haml
... | ... | @@ -3,8 +3,8 @@ |
3 | 3 | %span |
4 | 4 | (#{@projects.total_count}) |
5 | 5 | - if current_user.can_create_project? |
6 | - %span.right | |
7 | - = link_to new_project_path, class: "btn very_small info" do | |
6 | + %span.pull-right | |
7 | + = link_to new_project_path, class: "btn btn-tiny info" do | |
8 | 8 | %i.icon-plus |
9 | 9 | New Project |
10 | 10 | |
... | ... | @@ -42,7 +42,7 @@ |
42 | 42 | %small.light |
43 | 43 | %strong Last activity: |
44 | 44 | %span= project_last_activity(project) |
45 | - .right.light | |
45 | + .pull-right.light | |
46 | 46 | - if project.owner == current_user |
47 | 47 | %i.icon-wrench |
48 | 48 | - tm = project.team.get_tm(current_user.id) | ... | ... |
app/views/deploy_keys/_form.html.haml
1 | 1 | %div |
2 | 2 | = form_for [@project, @key], url: project_deploy_keys_path do |f| |
3 | 3 | -if @key.errors.any? |
4 | - .alert-message.block-message.error | |
4 | + .alert.alert-error | |
5 | 5 | %ul |
6 | 6 | - @key.errors.full_messages.each do |msg| |
7 | 7 | %li= msg |
... | ... | @@ -18,6 +18,6 @@ |
18 | 18 | = link_to "here", help_ssh_path |
19 | 19 | |
20 | 20 | .actions |
21 | - = f.submit 'Save', class: "save-btn btn" | |
22 | - = link_to "Cancel", project_deploy_keys_path(@project), class: "btn cancel-btn" | |
21 | + = f.submit 'Save', class: "btn-save btn" | |
22 | + = link_to "Cancel", project_deploy_keys_path(@project), class: "btn btn-cancel" | |
23 | 23 | ... | ... |
app/views/deploy_keys/_show.html.haml
... | ... | @@ -8,5 +8,5 @@ |
8 | 8 | = time_ago_in_words(key.created_at) |
9 | 9 | ago |
10 | 10 | %td |
11 | - = link_to 'Remove', project_deploy_key_path(key.project, key), confirm: 'Are you sure?', method: :delete, class: "danger btn delete-key small right" | |
11 | + = link_to 'Remove', project_deploy_key_path(key.project, key), confirm: 'Are you sure?', method: :delete, class: "btn btn-remove delete-key btn-small pull-right" | |
12 | 12 | ... | ... |
app/views/deploy_keys/index.html.haml
... | ... | @@ -4,7 +4,7 @@ |
4 | 4 | Deploy keys allow read-only access to repository. It matches perfectly for CI, staging or production servers. |
5 | 5 | |
6 | 6 | - if can? current_user, :admin_project, @project |
7 | - = link_to new_project_deploy_key_path(@project), class: "btn small", title: "New Deploy Key" do | |
7 | + = link_to new_project_deploy_key_path(@project), class: "btn btn-small", title: "New Deploy Key" do | |
8 | 8 | Add Deploy Key |
9 | 9 | - if @keys.any? |
10 | 10 | %table | ... | ... |
app/views/deploy_keys/show.html.haml
... | ... | @@ -10,5 +10,5 @@ |
10 | 10 | ← To keys list |
11 | 11 | %hr |
12 | 12 | %pre= @key.key |
13 | -.right | |
14 | - = link_to 'Remove', project_deploy_key_path(@key.project, @key), confirm: 'Are you sure?', method: :delete, class: "danger btn delete-key" | |
13 | +.pull-right | |
14 | + = link_to 'Remove', project_deploy_key_path(@key.project, @key), confirm: 'Are you sure?', method: :delete, class: "btn-remove btn delete-key" | ... | ... |
app/views/devise/passwords/edit.html.haml
... | ... | @@ -8,5 +8,5 @@ |
8 | 8 | %div |
9 | 9 | = f.password_field :password_confirmation, class: "text bottom", placeholder: "Confirm new password" |
10 | 10 | %div |
11 | - = f.submit "Change my password", class: "btn primary" | |
12 | - .right= render partial: "devise/shared/links" | |
11 | + = f.submit "Change my password", class: "btn btn-primary" | |
12 | + .pull-right= render partial: "devise/shared/links" | ... | ... |
app/views/devise/passwords/new.html.erb
1 | -<%= form_for(resource, :as => resource_name, :url => password_path(resource_name), :html => { :class => "login-box", :method => :post }) do |f| %> | |
2 | - <%= image_tag "login-logo.png", :width => "304", :height => "66", :class => "login-logo", :alt => "Login Logo" %> | |
1 | +<%= form_for(resource, as: resource_name, url: password_path(resource_name), html: { class: "login-box", method: :post }) do |f| %> | |
2 | + <%= image_tag "login-logo.png", width: "304", height: "66", class: "login-logo", alt: "Login Logo" %> | |
3 | 3 | <%= devise_error_messages! %> |
4 | - <%= f.email_field :email, :placeholder => "Email", :class => "text" %> | |
4 | + <%= f.email_field :email, placeholder: "Email", class: "text" %> | |
5 | 5 | <br/> |
6 | 6 | <br/> |
7 | - <%= f.submit "Reset password", :class => "primary btn" %> | |
8 | - <div class="right"> <%= link_to "Sign in", new_session_path(resource_name), :class => "btn" %><br /></div> | |
7 | + <%= f.submit "Reset password", class: "btn-primary btn" %> | |
8 | + <div class="pull-right"> <%= link_to "Sign in", new_session_path(resource_name), class: "btn" %><br /></div> | |
9 | 9 | <% end %> | ... | ... |
app/views/devise/registrations/new.html.haml
1 | -= form_for(resource, :as => resource_name, :url => registration_path(resource_name), :html => { :class => "login-box" }) do |f| | |
2 | - = image_tag "login-logo.png", :width => "304", :height => "66", :class => "login-logo", :alt => "Login Logo" | |
1 | += form_for(resource, as: resource_name, url: registration_path(resource_name), html: { class: "login-box" }) do |f| | |
2 | + = image_tag "login-logo.png", width: "304", height: "66", class: "login-logo", alt: "Login Logo" | |
3 | 3 | = devise_error_messages! |
4 | 4 | %div |
5 | - = f.text_field :name, :class => "text top", :placeholder => "Name", :required => true | |
5 | + = f.text_field :name, class: "text top", placeholder: "Name", required: true | |
6 | 6 | %div |
7 | - = f.text_field :username, :class => "text middle", :placeholder => "Username", :required => true | |
7 | + = f.text_field :username, class: "text middle", placeholder: "Username", required: true | |
8 | 8 | %div |
9 | - = f.email_field :email, :class => "text middle", :placeholder => "Email", :required => true | |
9 | + = f.email_field :email, class: "text middle", placeholder: "Email", required: true | |
10 | 10 | %div |
11 | - = f.password_field :password, :class => "text middle", :placeholder => "Password", :required => true | |
11 | + = f.password_field :password, class: "text middle", placeholder: "Password", required: true | |
12 | 12 | %div |
13 | - = f.password_field :password_confirmation, :class => "text bottom", :placeholder => "Confirm password", :required => true | |
13 | + = f.password_field :password_confirmation, class: "text bottom", placeholder: "Confirm password", required: true | |
14 | 14 | %div |
15 | - = f.submit "Sign up", :class => "primary btn wide" | |
16 | - %br | |
15 | + = f.submit "Sign up", class: "btn-create btn" | |
17 | 16 | %hr |
18 | 17 | = link_to "Sign in", new_session_path(resource_name) |
19 | - = link_to "Forgot your password?", new_password_path(resource_name), :class => "right" | |
18 | + = link_to "Forgot your password?", new_password_path(resource_name), class: "pull-right" | ... | ... |
app/views/devise/sessions/_new_ldap.html.haml
... | ... | @@ -3,11 +3,11 @@ |
3 | 3 | = text_field_tag :username, nil, {:class => "text top", :placeholder => "LDAP Login"} |
4 | 4 | = password_field_tag :password, nil, {:class => "text bottom", :placeholder => "Password"} |
5 | 5 | %br/ |
6 | - = submit_tag "LDAP Sign in", :class => "primary btn" | |
6 | + = submit_tag "LDAP Sign in", :class => "btn-primary btn" | |
7 | 7 | - if devise_mapping.omniauthable? |
8 | 8 | - (resource_class.omniauth_providers - [:ldap]).each do |provider| |
9 | 9 | %hr/ |
10 | - = link_to "Sign in with #{provider.to_s.titleize}", omniauth_authorize_path(resource_name, provider), :class => "btn primary" | |
10 | + = link_to "Sign in with #{provider.to_s.titleize}", omniauth_authorize_path(resource_name, provider), :class => "btn btn-primary" | |
11 | 11 | %br/ |
12 | 12 | %hr/ |
13 | 13 | %a#other_form_toggle{:href => "#", :onclick => "javascript:$('#new_user').toggle();"} Other Sign in |
... | ... | @@ -24,6 +24,6 @@ |
24 | 24 | = f.check_box :remember_me |
25 | 25 | %span Remember me |
26 | 26 | %br/ |
27 | - = f.submit "Sign in", :class => "primary btn" | |
28 | - .right | |
27 | + = f.submit "Sign in", :class => "btn-primary btn" | |
28 | + .pull-right | |
29 | 29 | = render :partial => "devise/shared/links" | ... | ... |
app/views/devise/sessions/new.html.haml
... | ... | @@ -11,18 +11,18 @@ |
11 | 11 | = f.check_box :remember_me |
12 | 12 | %span Remember me |
13 | 13 | %br/ |
14 | - = f.submit "Sign in", :class => "primary btn wide" | |
15 | - .right | |
14 | + = f.submit "Sign in", :class => "btn-create btn" | |
15 | + .pull-right | |
16 | 16 | = link_to "Forgot your password?", new_password_path(resource_name), :class => "btn" |
17 | 17 | %br/ |
18 | - %br/ | |
19 | 18 | - if Gitlab.config.gitlab.signup_enabled |
20 | 19 | %hr/ |
21 | 20 | Don't have an account? |
22 | 21 | = link_to "Sign up", new_registration_path(resource_name) |
23 | - .clearfix | |
24 | 22 | - if devise_mapping.omniauthable? && resource_class.omniauth_providers.present? |
23 | + %hr | |
25 | 24 | %div |
25 | + %span Sign in with: | |
26 | 26 | - resource_class.omniauth_providers.each do |provider| |
27 | 27 | %span |
28 | 28 | = link_to authbutton(provider, 32), omniauth_authorize_path(resource_name, provider) | ... | ... |
app/views/events/_event.html.haml
... | ... | @@ -0,0 +1,19 @@ |
1 | +%h3.page_title Project Network Graph | |
2 | +%br | |
3 | += render partial: 'shared/ref_switcher', locals: {destination: 'graph', path: @path} | |
4 | +%br | |
5 | +.graph_holder | |
6 | + %h4 | |
7 | + %small You can move around the graph by using the arrow keys. | |
8 | + #holder.graph | |
9 | + .loading.loading-gray | |
10 | + | |
11 | +:javascript | |
12 | + var branch_graph; | |
13 | + $(function(){ | |
14 | + branch_graph = new BranchGraph($("#holder"), { | |
15 | + url: '#{project_graph_path(@project, @ref, format: :json)}', | |
16 | + commit_url: '#{project_commit_path(@project, 'ae45ca32').gsub("ae45ca32", "%s")}', | |
17 | + ref: '#{@ref}' | |
18 | + }); | |
19 | + }); | ... | ... |
app/views/groups/_filter.html.haml
... | ... | @@ -25,9 +25,9 @@ |
25 | 25 | %li{class: ("active" if params[:project_id] == project.id.to_s)} |
26 | 26 | = link_to group_filter_path(entity, project_id: project.id) do |
27 | 27 | = project.name_with_namespace |
28 | - %small.right= entities_per_project(project, entity) | |
28 | + %small.pull-right= entities_per_project(project, entity) | |
29 | 29 | |
30 | 30 | %fieldset |
31 | 31 | %hr |
32 | - = link_to "Reset", group_filter_path(entity), class: 'btn right' | |
32 | + = link_to "Reset", group_filter_path(entity), class: 'btn pull-right' | |
33 | 33 | ... | ... |
app/views/groups/_new_group_member.html.haml
app/views/groups/_new_member.html.haml
app/views/groups/_people_filter.html.haml
... | ... | @@ -6,9 +6,9 @@ |
6 | 6 | %li{class: ("active" if params[:project_id] == project.id.to_s)} |
7 | 7 | = link_to people_group_path(@group, project_id: project.id) do |
8 | 8 | = project.name_with_namespace |
9 | - %small.right= project.users.count | |
9 | + %small.pull-right= project.users.count | |
10 | 10 | |
11 | 11 | %fieldset |
12 | 12 | %hr |
13 | - = link_to "Reset", people_group_path(@group), class: 'btn right' | |
13 | + = link_to "Reset", people_group_path(@group), class: 'btn pull-right' | |
14 | 14 | ... | ... |
app/views/groups/_projects.html.haml
... | ... | @@ -4,8 +4,8 @@ |
4 | 4 | %small |
5 | 5 | (#{projects.count}) |
6 | 6 | - if can? current_user, :manage_group, @group |
7 | - %span.right | |
8 | - = link_to new_project_path(namespace_id: @group.id), class: "btn very_small info" do | |
7 | + %span.pull-right | |
8 | + = link_to new_project_path(namespace_id: @group.id), class: "btn btn-tiny info" do | |
9 | 9 | %i.icon-plus |
10 | 10 | New Project |
11 | 11 | %ul.well-list | ... | ... |
... | ... | @@ -0,0 +1,50 @@ |
1 | +%h3.page_title Edit Group | |
2 | +%hr | |
3 | += form_for @group do |f| | |
4 | + - if @group.errors.any? | |
5 | + .alert.alert-error | |
6 | + %span= @group.errors.full_messages.first | |
7 | + .clearfix | |
8 | + = f.label :name do | |
9 | + Group name is | |
10 | + .input | |
11 | + = f.text_field :name, placeholder: "Ex. OpenSource", class: "xxlarge left" | |
12 | + | |
13 | + = f.submit 'Save group', class: "btn btn-save" | |
14 | +%hr | |
15 | + | |
16 | + | |
17 | +.row | |
18 | + .span7 | |
19 | + .ui-box | |
20 | + %h5.title Projects | |
21 | + %ul.well-list | |
22 | + - @group.projects.each do |project| | |
23 | + %li | |
24 | + - if project.public | |
25 | + %i.icon-share | |
26 | + - else | |
27 | + %i.icon-lock.cgreen | |
28 | + = link_to project.name_with_namespace, project | |
29 | + .pull-right | |
30 | + = link_to 'Team', project_team_index_path(project), id: "edit_#{dom_id(project)}", class: "btn btn-small" | |
31 | + = link_to 'Edit', edit_project_path(project), id: "edit_#{dom_id(project)}", class: "btn btn-small" | |
32 | + = link_to 'Remove', project, confirm: "REMOVE #{project.name}? Are you sure?", method: :delete, class: "btn btn-small btn-remove" | |
33 | + | |
34 | + .span5 | |
35 | + .ui-box | |
36 | + %h5.title Transfer group | |
37 | + .padded | |
38 | + %p | |
39 | + Transferring group will cause loss of admin control over group and all child projects | |
40 | + = form_for @group do |f| | |
41 | + = f.select :owner_id, User.all.map { |user| [user.name, user.id] }, {}, {class: 'chosen'} | |
42 | + = f.submit 'Transfer group', class: "btn btn-small" | |
43 | + .ui-box | |
44 | + %h5.title Remove group | |
45 | + .padded.bgred | |
46 | + %p | |
47 | + Remove of group will cause removing all child projects and resources | |
48 | + %br | |
49 | + Removed group can not be restored! | |
50 | + = link_to 'Remove Group', @group, confirm: 'Removed group can not be restored! Are you sure?', method: :delete, class: "btn btn-remove btn-small" | ... | ... |
app/views/groups/issues.html.haml
app/views/groups/merge_requests.html.haml
app/views/groups/new.html.haml
... | ... | @@ -2,7 +2,7 @@ |
2 | 2 | %hr |
3 | 3 | = form_for @group do |f| |
4 | 4 | - if @group.errors.any? |
5 | - .alert-message.block-message.error | |
5 | + .alert.alert-error | |
6 | 6 | %span= @group.errors.full_messages.first |
7 | 7 | .clearfix |
8 | 8 | = f.label :name do |
... | ... | @@ -10,7 +10,7 @@ |
10 | 10 | .input |
11 | 11 | = f.text_field :name, placeholder: "Ex. OpenSource", class: "xxlarge left" |
12 | 12 | |
13 | - = f.submit 'Create group', class: "btn primary" | |
13 | + = f.submit 'Create group', class: "btn btn-create" | |
14 | 14 | %hr |
15 | 15 | .padded |
16 | 16 | %ul | ... | ... |
app/views/groups/people.html.haml
app/views/groups/search.html.haml
... | ... | @@ -4,6 +4,6 @@ |
4 | 4 | %strong Looking for |
5 | 5 | .input |
6 | 6 | = search_field_tag :search, params[:search], placeholder: "issue 143", class: "input-xxlarge search-text-input", id: "dashboard_search" |
7 | - = submit_tag 'Search', class: "btn primary wide" | |
7 | + = submit_tag 'Search', class: "btn btn-primary wide" | |
8 | 8 | - if params[:search].present? |
9 | 9 | = render 'search/result' | ... | ... |
app/views/groups/show.html.haml
1 | 1 | .projects |
2 | 2 | .activities.span8 |
3 | 3 | = render "events/event_last_push", event: @last_push |
4 | - = link_to dashboard_path, class: 'btn very_small' do | |
4 | + = link_to dashboard_path, class: 'btn btn-tiny' do | |
5 | 5 | ← To dashboard |
6 | 6 | |
7 | 7 | %span.cgray You will only see events from projects in this group | ... | ... |
app/views/help/_layout.html.haml
app/views/help/index.html.haml
app/views/hooks/index.html.haml
... | ... | @@ -10,7 +10,7 @@ |
10 | 10 | |
11 | 11 | = form_for [@project, @hook], as: :hook, url: project_hooks_path(@project), html: { class: 'form-inline' } do |f| |
12 | 12 | -if @hook.errors.any? |
13 | - .alert-message.block-message.error | |
13 | + .alert.alert-error | |
14 | 14 | - @hook.errors.full_messages.each do |msg| |
15 | 15 | %p= msg |
16 | 16 | .clearfix |
... | ... | @@ -18,7 +18,7 @@ |
18 | 18 | .input |
19 | 19 | = f.text_field :url, class: "text_field xxlarge" |
20 | 20 | |
21 | - = f.submit "Add Web Hook", class: "btn primary" | |
21 | + = f.submit "Add Web Hook", class: "btn btn-primary" | |
22 | 22 | %hr |
23 | 23 | |
24 | 24 | -if @hooks.any? |
... | ... | @@ -37,6 +37,6 @@ |
37 | 37 | → |
38 | 38 | %span.monospace= hook.url |
39 | 39 | %td |
40 | - .right | |
41 | - = link_to 'Test Hook', test_project_hook_path(@project, hook), class: "btn small grouped" | |
42 | - = link_to 'Remove', project_hook_path(@project, hook), confirm: 'Are you sure?', method: :delete, class: "danger btn small grouped" | |
40 | + .pull-right | |
41 | + = link_to 'Test Hook', test_project_hook_path(@project, hook), class: "btn btn-small grouped" | |
42 | + = link_to 'Remove', project_hook_path(@project, hook), confirm: 'Are you sure?', method: :delete, class: "btn btn-remove btn-small grouped" | ... | ... |
app/views/issues/_filter.html.haml
app/views/issues/_form.html.haml
... | ... | @@ -2,7 +2,7 @@ |
2 | 2 | %h3.page_title= @issue.new_record? ? "New Issue" : "Edit Issue ##{@issue.id}" |
3 | 3 | = form_for [@project, @issue] do |f| |
4 | 4 | -if @issue.errors.any? |
5 | - .alert-message.block-message.error | |
5 | + .alert.alert-error | |
6 | 6 | - @issue.errors.full_messages.each do |msg| |
7 | 7 | %span= msg |
8 | 8 | %br |
... | ... | @@ -44,12 +44,12 @@ |
44 | 44 | |
45 | 45 | .actions |
46 | 46 | - if @issue.new_record? |
47 | - = f.submit 'Submit new issue', class: "btn success" | |
47 | + = f.submit 'Submit new issue', class: "btn btn-create" | |
48 | 48 | -else |
49 | - = f.submit 'Save changes', class: "save-btn btn" | |
49 | + = f.submit 'Save changes', class: "btn-save btn" | |
50 | 50 | |
51 | 51 | - cancel_path = @issue.new_record? ? project_issues_path(@project) : project_issue_path(@project, @issue) |
52 | - = link_to "Cancel", cancel_path, class: 'btn cancel-btn' | |
52 | + = link_to "Cancel", cancel_path, class: 'btn btn-cancel' | |
53 | 53 | |
54 | 54 | |
55 | 55 | ... | ... |
app/views/issues/_head.html.haml
... | ... | @@ -5,7 +5,7 @@ |
5 | 5 | = link_to 'Milestones', project_milestones_path(@project), class: "tab" |
6 | 6 | = nav_link(controller: :labels) do |
7 | 7 | = link_to 'Labels', project_labels_path(@project), class: "tab" |
8 | - %li.right | |
8 | + %li.pull-right | |
9 | 9 | %span.rss-icon |
10 | 10 | = link_to project_issues_path(@project, :atom, { private_token: current_user.private_token }) do |
11 | 11 | = image_tag "rss_ui.png", title: "feed" | ... | ... |
app/views/issues/_issues.html.haml
app/views/issues/_show.html.haml
... | ... | @@ -2,17 +2,17 @@ |
2 | 2 | - if controller.controller_name == 'issues' |
3 | 3 | .issue_check |
4 | 4 | = check_box_tag dom_id(issue,"selected"), nil, false, 'data-id' => issue.id, class: "selected_issue", disabled: !can?(current_user, :modify_issue, issue) |
5 | - .right | |
5 | + .pull-right | |
6 | 6 | - if issue.notes.any? |
7 | - %span.btn.small.disabled.grouped | |
7 | + %span.btn.btn-small.disabled.grouped | |
8 | 8 | %i.icon-comment |
9 | 9 | = issue.notes.count |
10 | 10 | - if can? current_user, :modify_issue, issue |
11 | 11 | - if issue.closed |
12 | - = link_to 'Reopen', project_issue_path(issue.project, issue, issue: {closed: false }, status_only: true), method: :put, class: "btn small grouped reopen_issue", remote: true | |
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 | |
13 | 13 | - else |
14 | - = link_to 'Close', project_issue_path(issue.project, issue, issue: {closed: true }, status_only: true), method: :put, class: "btn small grouped close_issue", remote: true | |
15 | - = link_to edit_project_issue_path(issue.project, issue), class: "btn small edit-issue-link grouped" do | |
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 | |
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 |
18 | 18 | ... | ... |
app/views/issues/index.html.haml
... | ... | @@ -3,16 +3,16 @@ |
3 | 3 | %h3.page_title |
4 | 4 | Issues |
5 | 5 | %span (<span class=issue_counter>#{@issues.total_count}</span>) |
6 | - .right | |
6 | + .pull-right | |
7 | 7 | .span5 |
8 | 8 | - if can? current_user, :write_issue, @project |
9 | - = link_to new_project_issue_path(@project, issue: { assignee_id: params[:assignee_id], milestone_id: params[:milestone_id]}), class: "right btn primary", title: "New Issue", id: "new_issue_link" do | |
9 | + = link_to new_project_issue_path(@project, issue: { assignee_id: params[:assignee_id], milestone_id: params[:milestone_id]}), class: "btn btn-primary pull-right", title: "New Issue", id: "new_issue_link" do | |
10 | 10 | %i.icon-plus |
11 | 11 | New Issue |
12 | - = form_tag search_project_issues_path(@project), method: :get, remote: true, id: "issue_search_form", class: :right do | |
12 | + = form_tag search_project_issues_path(@project), method: :get, remote: true, id: "issue_search_form", class: 'pull-right' do | |
13 | 13 | = hidden_field_tag :project_id, @project.id, { id: 'project_id' } |
14 | 14 | = hidden_field_tag :status, params[:status] |
15 | - = search_field_tag :issue_search, nil, { placeholder: 'Search', class: 'issue_search span3 right neib search-text-input' } | |
15 | + = search_field_tag :issue_search, nil, { placeholder: 'Search', class: 'issue_search span3 pull-right neib search-text-input' } | |
16 | 16 | |
17 | 17 | .clearfix |
18 | 18 | |
... | ... | @@ -33,7 +33,7 @@ |
33 | 33 | = select_tag('update[milestone_id]', options_from_collection_for_select(issues_active_milestones, "id", "title", params[:milestone_id]), prompt: "Milestone") |
34 | 34 | = hidden_field_tag 'update[issues_ids]', [] |
35 | 35 | = hidden_field_tag :status, params[:status] |
36 | - = button_tag "Save", class: "btn update_selected_issues btn-small save-btn" | |
36 | + = button_tag "Save", class: "btn update_selected_issues btn-small btn-save" | |
37 | 37 | .issues_filters |
38 | 38 | = form_tag project_issues_path(@project), method: :get do |
39 | 39 | = select_tag(:label_name, options_for_select(issue_tags, params[:label_name]), prompt: "Labels") | ... | ... |
app/views/issues/show.html.haml
... | ... | @@ -5,7 +5,7 @@ |
5 | 5 | created at |
6 | 6 | = @issue.created_at.stamp("Aug 21, 2011") |
7 | 7 | |
8 | - %span.right | |
8 | + %span.pull-right | |
9 | 9 | - if can?(current_user, :admin_project, @project) || @issue.author == current_user |
10 | 10 | - if @issue.closed |
11 | 11 | = link_to 'Reopen', project_issue_path(@project, @issue, issue: {closed: false }, status_only: true), method: :put, class: "btn grouped reopen_issue" |
... | ... | @@ -16,7 +16,7 @@ |
16 | 16 | %i.icon-edit |
17 | 17 | Edit |
18 | 18 | |
19 | -.right | |
19 | +.pull-right | |
20 | 20 | .span3#votes= render 'votes/votes_block', votable: @issue |
21 | 21 | |
22 | 22 | .back_link |
... | ... | @@ -42,7 +42,7 @@ |
42 | 42 | %cite.cgray and attached to milestone |
43 | 43 | %strong= link_to_gfm truncate(milestone.title, length: 20), project_milestone_path(milestone.project, milestone) |
44 | 44 | |
45 | - .right | |
45 | + .pull-right | |
46 | 46 | - @issue.labels.each do |label| |
47 | 47 | %span.label |
48 | 48 | %i.icon-tag | ... | ... |
app/views/keys/_form.html.haml
1 | 1 | %div |
2 | 2 | = form_for @key do |f| |
3 | 3 | -if @key.errors.any? |
4 | - .alert-message.block-message.error | |
4 | + .alert.alert-error | |
5 | 5 | %ul |
6 | 6 | - @key.errors.full_messages.each do |msg| |
7 | 7 | %li= msg |
... | ... | @@ -19,6 +19,6 @@ |
19 | 19 | |
20 | 20 | |
21 | 21 | .actions |
22 | - = f.submit 'Save', class: "btn save-btn" | |
23 | - = link_to "Cancel", keys_path, class: "btn cancel-btn" | |
22 | + = f.submit 'Save', class: "btn btn-save" | |
23 | + = link_to "Cancel", keys_path, class: "btn btn-cancel" | |
24 | 24 | ... | ... |
app/views/keys/_show.html.haml
... | ... | @@ -8,5 +8,5 @@ |
8 | 8 | = time_ago_in_words(key.created_at) |
9 | 9 | ago |
10 | 10 | %td |
11 | - = link_to 'Remove', key, confirm: 'Are you sure?', method: :delete, class: "btn small danger delete-key right" | |
11 | + = link_to 'Remove', key, confirm: 'Are you sure?', method: :delete, class: "btn btn-small btn-remove delete-key pull-right" | |
12 | 12 | ... | ... |
app/views/keys/index.html.haml
app/views/keys/show.html.haml
... | ... | @@ -10,5 +10,5 @@ |
10 | 10 | %hr |
11 | 11 | |
12 | 12 | %pre= @key.key |
13 | -.right | |
14 | - = link_to 'Remove', @key, confirm: 'Are you sure?', method: :delete, class: "btn danger delete-key" | |
13 | +.pull-right | |
14 | + = link_to 'Remove', @key, confirm: 'Are you sure?', method: :delete, class: "btn btn-remove delete-key" | ... | ... |
app/views/labels/_label.html.haml
app/views/layouts/admin.html.haml
... | ... | @@ -7,7 +7,8 @@ |
7 | 7 | .container |
8 | 8 | %ul.main_menu |
9 | 9 | = nav_link(controller: :dashboard, html_options: {class: 'home'}) do |
10 | - = link_to "Stats", admin_root_path | |
10 | + = link_to admin_root_path, title: "Stats" do | |
11 | + %i.icon-home | |
11 | 12 | = nav_link(controller: :projects) do |
12 | 13 | = link_to "Projects", admin_projects_path |
13 | 14 | = nav_link(controller: :teams) do | ... | ... |
app/views/layouts/application.html.haml
... | ... | @@ -7,7 +7,8 @@ |
7 | 7 | .container |
8 | 8 | %ul.main_menu |
9 | 9 | = nav_link(path: 'dashboard#show', html_options: {class: 'home'}) do |
10 | - = link_to "Home", root_path, title: "Home" | |
10 | + = link_to root_path, title: "Home" do | |
11 | + %i.icon-home | |
11 | 12 | = nav_link(path: 'dashboard#projects') do |
12 | 13 | = link_to projects_dashboard_path do |
13 | 14 | Projects | ... | ... |
app/views/layouts/group.html.haml
... | ... | @@ -7,7 +7,8 @@ |
7 | 7 | .container |
8 | 8 | %ul.main_menu |
9 | 9 | = nav_link(path: 'groups#show', html_options: {class: 'home'}) do |
10 | - = link_to "Home", group_path(@group), title: "Home" | |
10 | + = link_to group_path(@group), title: "Home" do | |
11 | + %i.icon-home | |
11 | 12 | = nav_link(path: 'groups#issues') do |
12 | 13 | = link_to issues_group_path(@group) do |
13 | 14 | Issues |
... | ... | @@ -21,4 +22,10 @@ |
21 | 22 | = nav_link(path: 'groups#people') do |
22 | 23 | = link_to "People", people_group_path(@group) |
23 | 24 | |
25 | + - if can?(current_user, :manage_group, @group) | |
26 | + = nav_link(path: 'groups#edit') do | |
27 | + = link_to edit_group_path(@group), class: "tab " do | |
28 | + %i.icon-edit | |
29 | + Edit Group | |
30 | + | |
24 | 31 | .content= yield | ... | ... |
app/views/layouts/profile.html.haml
... | ... | @@ -7,7 +7,8 @@ |
7 | 7 | .container |
8 | 8 | %ul.main_menu |
9 | 9 | = nav_link(path: 'profiles#show', html_options: {class: 'home'}) do |
10 | - = link_to "Profile", profile_path | |
10 | + = link_to profile_path, title: "Profile" do | |
11 | + %i.icon-home | |
11 | 12 | = nav_link(path: 'profiles#account') do |
12 | 13 | = link_to "Account", account_profile_path |
13 | 14 | = nav_link(controller: :keys) do | ... | ... |
app/views/layouts/project_resource.html.haml
... | ... | @@ -12,7 +12,8 @@ |
12 | 12 | .container |
13 | 13 | %ul.main_menu |
14 | 14 | = nav_link(html_options: {class: "home #{project_tab_class}"}) do |
15 | - = link_to @project.path, project_path(@project), title: "Project" | |
15 | + = link_to project_path(@project), title: "Project" do | |
16 | + %i.icon-home | |
16 | 17 | |
17 | 18 | - if @project.repo_exists? |
18 | 19 | - if can? current_user, :download_code, @project |
... | ... | @@ -20,8 +21,8 @@ |
20 | 21 | = link_to 'Files', project_tree_path(@project, @ref || @repository.root_ref) |
21 | 22 | = nav_link(controller: %w(commit commits compare repositories protected_branches)) do |
22 | 23 | = link_to "Commits", project_commits_path(@project, @ref || @repository.root_ref) |
23 | - = nav_link(path: 'projects#graph') do | |
24 | - = link_to "Network", graph_project_path(@project) | |
24 | + = nav_link(controller: %w(graph)) do | |
25 | + = link_to "Network", project_graph_path(@project, @ref || @repository.root_ref) | |
25 | 26 | |
26 | 27 | - if @project.issues_enabled |
27 | 28 | = nav_link(controller: %w(issues milestones labels)) do | ... | ... |
app/views/layouts/user_team.html.haml
... | ... | @@ -7,7 +7,8 @@ |
7 | 7 | .container |
8 | 8 | %ul.main_menu |
9 | 9 | = nav_link(path: 'teams#show', html_options: {class: 'home'}) do |
10 | - = link_to "Home", team_path(@team), title: "Home" | |
10 | + = link_to team_path(@team), title: "Home" do | |
11 | + %i.icon-home | |
11 | 12 | |
12 | 13 | = nav_link(path: 'teams#issues') do |
13 | 14 | = link_to issues_team_path(@team) do | ... | ... |
app/views/merge_requests/_filter.html.haml
app/views/merge_requests/_form.html.haml
1 | 1 | = form_for [@project, @merge_request], html: { class: "#{controller.action_name}-merge-request form-horizontal" } do |f| |
2 | 2 | -if @merge_request.errors.any? |
3 | - .alert-message.block-message.error | |
3 | + .alert.alert-error | |
4 | 4 | %ul |
5 | 5 | - @merge_request.errors.full_messages.each do |msg| |
6 | 6 | %li= msg |
... | ... | @@ -51,19 +51,19 @@ |
51 | 51 | |
52 | 52 | .form-actions |
53 | 53 | - if @merge_request.new_record? |
54 | - = f.submit 'Submit merge request', class: "btn success" | |
54 | + = f.submit 'Submit merge request', class: "btn btn-create" | |
55 | 55 | -else |
56 | - = f.submit 'Save changes', class: "save-btn btn" | |
56 | + = f.submit 'Save changes', class: "btn btn-save" | |
57 | 57 | - if @merge_request.new_record? |
58 | - = link_to project_merge_requests_path(@project), class: "btn cancel-btn" do | |
58 | + = link_to project_merge_requests_path(@project), class: "btn btn-cancel" do | |
59 | 59 | Cancel |
60 | 60 | - else |
61 | - = link_to project_merge_request_path(@project, @merge_request), class: "btn cancel-btn" do | |
61 | + = link_to project_merge_request_path(@project, @merge_request), class: "btn btn-cancel" do | |
62 | 62 | Cancel |
63 | 63 | |
64 | 64 | :javascript |
65 | 65 | $(function(){ |
66 | - disableButtonIfEmptyField("#merge_request_title", ".save-btn"); | |
66 | + disableButtonIfEmptyField("#merge_request_title", ".btn-save"); | |
67 | 67 | |
68 | 68 | var source_branch = $("#merge_request_source_branch") |
69 | 69 | , target_branch = $("#merge_request_target_branch"); | ... | ... |
app/views/merge_requests/_merge_request.html.haml
1 | 1 | %li{ class: mr_css_classes(merge_request) } |
2 | - .right | |
2 | + .pull-right | |
3 | 3 | .left |
4 | 4 | - if merge_request.merged? |
5 | - %span.btn.small.disabled.grouped | |
5 | + %span.btn.btn-small.disabled.grouped | |
6 | 6 | %strong |
7 | 7 | %i.icon-ok |
8 | 8 | = "MERGED" |
9 | 9 | - if merge_request.notes.any? |
10 | - %span.btn.small.disabled.grouped | |
10 | + %span.btn.btn-small.disabled.grouped | |
11 | 11 | %i.icon-comment |
12 | 12 | = merge_request.mr_and_commit_notes.count |
13 | 13 | - if merge_request.milestone_id? |
14 | - %span.btn.small.disabled.grouped | |
14 | + %span.btn.btn-small.disabled.grouped | |
15 | 15 | %i.icon-time |
16 | 16 | = merge_request.milestone.title |
17 | - %span.btn.small.disabled.grouped | |
17 | + %span.btn.btn-small.disabled.grouped | |
18 | 18 | = merge_request.source_branch |
19 | 19 | → |
20 | 20 | = merge_request.target_branch | ... | ... |
app/views/merge_requests/index.html.haml
1 | 1 | - if can? current_user, :write_merge_request, @project |
2 | - = link_to new_project_merge_request_path(@project), class: "right btn primary", title: "New Merge Request" do | |
2 | + = link_to new_project_merge_request_path(@project), class: "pull-right btn btn-primary", title: "New Merge Request" do | |
3 | 3 | %i.icon-plus |
4 | 4 | New Merge Request |
5 | 5 | %h3.page_title |
... | ... | @@ -28,8 +28,8 @@ |
28 | 28 | - if @merge_requests.present? |
29 | 29 | %li.bottom |
30 | 30 | .left= paginate @merge_requests, theme: "gitlab" |
31 | - .right | |
32 | - %span.cgray.right #{@merge_requests.total_count} merge requests for this filter | |
31 | + .pull-right | |
32 | + %span.cgray.pull-right #{@merge_requests.total_count} merge requests for this filter | |
33 | 33 | |
34 | 34 | :javascript |
35 | 35 | $(merge_requestsPage); | ... | ... |
app/views/merge_requests/show/_mr_accept.html.haml
1 | 1 | - unless can?(current_user, :accept_mr, @project) |
2 | - .alert-message | |
2 | + .alert | |
3 | 3 | %strong Only masters can accept MR |
4 | 4 | |
5 | 5 | |
... | ... | @@ -29,14 +29,14 @@ |
29 | 29 | %strong This repository does not have satellite. Ask administrator to fix this issue |
30 | 30 | |
31 | 31 | .automerge_widget.cannot_be_merged{style: "display:none"} |
32 | - .alert.alert-info | |
32 | + .alert.alert-disabled | |
33 | 33 | %span |
34 | - = link_to "Show how to merge", "#", class: "how_to_merge_link btn small padded", title: "How To Merge" | |
34 | + = link_to "Show how to merge", "#", class: "how_to_merge_link btn btn-small padded", title: "How To Merge" | |
35 | 35 | |
36 | 36 | %strong This request can't be merged with GitLab. You should do it manually |
37 | 37 | |
38 | 38 | .automerge_widget.unchecked |
39 | - .alert-message | |
39 | + .alert | |
40 | 40 | %strong |
41 | 41 | %i.icon-refresh |
42 | 42 | Checking for ability to automatically merge… | ... | ... |
app/views/merge_requests/show/_mr_ci.html.haml
app/views/merge_requests/show/_mr_title.html.haml
... | ... | @@ -5,7 +5,7 @@ |
5 | 5 | → |
6 | 6 | %span.label_branch= @merge_request.target_branch |
7 | 7 | |
8 | - %span.right | |
8 | + %span.pull-right | |
9 | 9 | - if can?(current_user, :modify_merge_request, @merge_request) |
10 | 10 | - if @merge_request.open? |
11 | 11 | .left.btn-group |
... | ... | @@ -17,13 +17,13 @@ |
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 danger", title: "Close merge request" | |
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" | |
21 | 21 | |
22 | 22 | = link_to edit_project_merge_request_path(@project, @merge_request), class: "btn grouped" do |
23 | 23 | %i.icon-edit |
24 | 24 | Edit |
25 | 25 | |
26 | -.right | |
26 | +.pull-right | |
27 | 27 | .span3#votes= render 'votes/votes_block', votable: @merge_request |
28 | 28 | |
29 | 29 | .back_link | ... | ... |
app/views/milestones/_form.html.haml
... | ... | @@ -7,7 +7,7 @@ |
7 | 7 | |
8 | 8 | = form_for [@project, @milestone], html: {class: "new_milestone form-horizontal"} do |f| |
9 | 9 | -if @milestone.errors.any? |
10 | - .alert-message.block-message.error | |
10 | + .alert.alert-error | |
11 | 11 | %ul |
12 | 12 | - @milestone.errors.full_messages.each do |msg| |
13 | 13 | %li= msg |
... | ... | @@ -32,16 +32,16 @@ |
32 | 32 | |
33 | 33 | .form-actions |
34 | 34 | - if @milestone.new_record? |
35 | - = f.submit 'Create milestone', class: "save-btn btn" | |
36 | - = link_to "Cancel", project_milestones_path(@project), class: "btn cancel-btn" | |
35 | + = f.submit 'Create milestone', class: "btn-save btn" | |
36 | + = link_to "Cancel", project_milestones_path(@project), class: "btn btn-cancel" | |
37 | 37 | -else |
38 | - = f.submit 'Save changes', class: "save-btn btn" | |
39 | - = link_to "Cancel", project_milestone_path(@project, @milestone), class: "btn cancel-btn" | |
38 | + = f.submit 'Save changes', class: "btn-save btn" | |
39 | + = link_to "Cancel", project_milestone_path(@project, @milestone), class: "btn btn-cancel" | |
40 | 40 | |
41 | 41 | |
42 | 42 | :javascript |
43 | 43 | $(function() { |
44 | - disableButtonIfEmptyField("#milestone_title", ".save-btn"); | |
44 | + disableButtonIfEmptyField("#milestone_title", ".btn-save"); | |
45 | 45 | $( ".datepicker" ).datepicker({ |
46 | 46 | dateFormat: "yy-mm-dd", |
47 | 47 | onSelect: function(dateText, inst) { $("#milestone_due_date").val(dateText) } | ... | ... |
app/views/milestones/_milestone.html.haml
1 | 1 | %li{class: "milestone milestone-#{milestone.closed ? 'closed' : 'open'}", id: dom_id(milestone) } |
2 | - .right | |
2 | + .pull-right | |
3 | 3 | - if can?(current_user, :admin_milestone, milestone.project) and milestone.open? |
4 | - = link_to edit_project_milestone_path(milestone.project, milestone), class: "btn small edit-milestone-link grouped" do | |
4 | + = link_to edit_project_milestone_path(milestone.project, milestone), class: "btn btn-small edit-milestone-link grouped" do | |
5 | 5 | %i.icon-edit |
6 | 6 | Edit |
7 | 7 | %h4 | ... | ... |
app/views/milestones/index.html.haml
... | ... | @@ -3,7 +3,7 @@ |
3 | 3 | %h3.page_title |
4 | 4 | Milestones |
5 | 5 | - if can? current_user, :admin_milestone, @project |
6 | - = link_to "New Milestone", new_project_milestone_path(@project), class: "right btn small", title: "New Milestone" | |
6 | + = link_to "New Milestone", new_project_milestone_path(@project), class: "pull-right btn btn-small", title: "New Milestone" | |
7 | 7 | %br |
8 | 8 | %div.ui-box |
9 | 9 | .title | ... | ... |
app/views/milestones/show.html.haml
... | ... | @@ -8,14 +8,14 @@ |
8 | 8 | = link_to project_milestones_path(@project) do |
9 | 9 | ← To milestones list |
10 | 10 | .span6 |
11 | - .right | |
11 | + .pull-right | |
12 | 12 | - unless @milestone.closed |
13 | - = link_to new_project_issue_path(@project, issue: { milestone_id: @milestone.id }), class: "btn small grouped", title: "New Issue" do | |
13 | + = link_to new_project_issue_path(@project, issue: { milestone_id: @milestone.id }), class: "btn btn-small grouped", title: "New Issue" do | |
14 | 14 | %i.icon-plus |
15 | 15 | New Issue |
16 | 16 | = link_to 'Browse Issues', project_issues_path(@milestone.project, milestone_id: @milestone.id), class: "btn edit-milestone-link small grouped" |
17 | 17 | - if can?(current_user, :admin_milestone, @project) |
18 | - = link_to edit_project_milestone_path(@project, @milestone), class: "btn small grouped" do | |
18 | + = link_to edit_project_milestone_path(@project, @milestone), class: "btn btn-small grouped" do | |
19 | 19 | %i.icon-edit |
20 | 20 | Edit |
21 | 21 | |
... | ... | @@ -25,7 +25,7 @@ |
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 small danger" | |
28 | + = link_to 'Close Milestone', project_milestone_path(@project, @milestone, milestone: {closed: true }), method: :put, class: "btn btn-small btn-remove" | |
29 | 29 | |
30 | 30 | .ui-box.ui-box-show |
31 | 31 | .ui-box-head |
... | ... | @@ -43,7 +43,7 @@ |
43 | 43 | #{@milestone.closed_items_count} closed |
44 | 44 | – |
45 | 45 | #{@milestone.open_items_count} open |
46 | - %span.right= @milestone.expires_at | |
46 | + %span.pull-right= @milestone.expires_at | |
47 | 47 | .progress.progress-info |
48 | 48 | .bar{style: "width: #{@milestone.percent_complete}%;"} |
49 | 49 | ... | ... |
app/views/notes/_form.html.haml
... | ... | @@ -15,30 +15,30 @@ |
15 | 15 | = f.text_area :note, size: 255, class: 'note_text js-note-text js-gfm-input turn-on' |
16 | 16 | .note_preview.js-note-preview.turn-off |
17 | 17 | |
18 | - .buttons | |
19 | - = f.submit 'Add Comment', class: "btn comment-btn grouped js-comment-button" | |
20 | - %a.btn.grouped.js-close-discussion-note-form Cancel | |
21 | 18 | .hint |
22 | - .right Comments are parsed with #{link_to "GitLab Flavored Markdown", help_markdown_path, target: '_blank'}. | |
19 | + .pull-right Comments are parsed with #{link_to "GitLab Flavored Markdown", help_markdown_path, target: '_blank'}. | |
23 | 20 | .clearfix |
24 | 21 | |
25 | - .note_options | |
26 | - .attachment | |
27 | - %h6 Attachment: | |
28 | - .file_name.js-attachment-filename File name... | |
29 | - %a.choose-btn.btn.small.js-choose-note-attachment-button Choose File ... | |
30 | - .hint Any file up to 10 MB | |
22 | + .note-form-actions | |
23 | + .buttons | |
24 | + = f.submit 'Add Comment', class: "btn comment-btn grouped js-comment-button" | |
25 | + %a.btn.grouped.js-close-discussion-note-form Cancel | |
31 | 26 | |
32 | - = f.file_field :attachment, class: "js-note-attachment-input" | |
33 | - | |
34 | - .notify_options | |
35 | - %h6 Notify via email: | |
27 | + .note-form-option | |
36 | 28 | = label_tag :notify do |
37 | 29 | = check_box_tag :notify, 1, !@note.for_commit? |
38 | - Project team | |
30 | + %span.light Notify team via email | |
39 | 31 | |
40 | 32 | .js-notify-commit-author |
41 | 33 | = label_tag :notify_author do |
42 | 34 | = check_box_tag :notify_author, 1 , @note.for_commit? |
43 | - Commit author | |
44 | - .clearfix | |
35 | + %span.light Notify commit author | |
36 | + .note-form-option | |
37 | + %a.choose-btn.btn.btn-small.js-choose-note-attachment-button | |
38 | + %i.icon-paper-clip | |
39 | + %span Choose File ... | |
40 | + | |
41 | + %span.file_name.js-attachment-filename File name... | |
42 | + = f.file_field :attachment, class: "js-note-attachment-input hide" | |
43 | + | |
44 | + .clearfix | ... | ... |
app/views/notes/_note.html.haml
... | ... | @@ -30,8 +30,8 @@ |
30 | 30 | - if note.attachment.url |
31 | 31 | - if note.attachment.image? |
32 | 32 | = image_tag note.attachment.url, class: 'note-image-attach' |
33 | - .attachment.right | |
33 | + .attachment.pull-right | |
34 | 34 | = link_to note.attachment.url, target: "_blank" do |
35 | - %i.icon-attachment | |
35 | + %i.icon-paper-clip | |
36 | 36 | = note.attachment_identifier |
37 | 37 | .clear | ... | ... |
app/views/profiles/account.html.haml
... | ... | @@ -12,7 +12,7 @@ |
12 | 12 | %fieldset |
13 | 13 | %legend |
14 | 14 | Private token |
15 | - %span.cred.right | |
15 | + %span.cred.pull-right | |
16 | 16 | keep it secret! |
17 | 17 | .padded |
18 | 18 | = form_for @user, url: reset_private_token_profile_path, method: :put do |f| |
... | ... | @@ -24,7 +24,7 @@ |
24 | 24 | %p.cgray |
25 | 25 | - if current_user.private_token |
26 | 26 | = text_field_tag "token", current_user.private_token, class: "xxlarge large_text" |
27 | - = f.submit 'Reset', confirm: "Are you sure?", class: "btn primary btn-build-token" | |
27 | + = f.submit 'Reset', confirm: "Are you sure?", class: "btn btn-primary btn-build-token" | |
28 | 28 | - else |
29 | 29 | %span You don`t have one yet. Click generate to fix it. |
30 | 30 | = f.submit 'Generate', class: "btn success btn-build-token" |
... | ... | @@ -35,7 +35,7 @@ |
35 | 35 | .padded |
36 | 36 | %p.slead After successful password update you will be redirected to login page where you should login with new password |
37 | 37 | -if @user.errors.any? |
38 | - .alert-message.block-message.error | |
38 | + .alert.alert-error | |
39 | 39 | %ul |
40 | 40 | - @user.errors.full_messages.each do |msg| |
41 | 41 | %li= msg |
... | ... | @@ -49,14 +49,14 @@ |
49 | 49 | = f.password_field :password_confirmation, required: true |
50 | 50 | .clearfix |
51 | 51 | .input |
52 | - = f.submit 'Save password', class: "btn save-btn" | |
52 | + = f.submit 'Save password', class: "btn btn-save" | |
53 | 53 | |
54 | 54 | |
55 | 55 | |
56 | 56 | %fieldset.update-username |
57 | 57 | %legend |
58 | 58 | Username |
59 | - %small.cred.right | |
59 | + %small.cred.pull-right | |
60 | 60 | Changing your username can have unintended side effects! |
61 | 61 | = form_for @user, url: update_username_profile_path, method: :put, remote: true do |f| |
62 | 62 | .padded |
... | ... | @@ -75,6 +75,6 @@ |
75 | 75 | %li It will change web url for personal projects. |
76 | 76 | %li It will change the git path to repositories for personal projects. |
77 | 77 | .input |
78 | - = f.submit 'Save username', class: "btn save-btn" | |
78 | + = f.submit 'Save username', class: "btn btn-save" | |
79 | 79 | |
80 | 80 | ... | ... |
app/views/profiles/show.html.haml
... | ... | @@ -6,7 +6,7 @@ |
6 | 6 | %small |
7 | 7 | = @user.email |
8 | 8 | |
9 | - .right | |
9 | + .pull-right | |
10 | 10 | = link_to destroy_user_session_path, class: "logout", method: :delete do |
11 | 11 | %small |
12 | 12 | %i.icon-signout |
... | ... | @@ -15,7 +15,7 @@ |
15 | 15 | |
16 | 16 | = form_for @user, url: profile_path, method: :put, html: { class: "edit_user form-horizontal" } do |f| |
17 | 17 | -if @user.errors.any? |
18 | - %div.alert-message.block-message.error | |
18 | + %div.alert.alert-error | |
19 | 19 | %ul |
20 | 20 | - @user.errors.full_messages.each do |msg| |
21 | 21 | %li= msg |
... | ... | @@ -46,7 +46,7 @@ |
46 | 46 | = f.text_area :bio, rows: 6, class: "input-xlarge", maxlength: 250 |
47 | 47 | %span.help-block Tell us about yourself in fewer than 250 characters. |
48 | 48 | |
49 | - .span5.right | |
49 | + .span5.pull-right | |
50 | 50 | %fieldset.tips |
51 | 51 | %legend Tips: |
52 | 52 | %ul |
... | ... | @@ -65,18 +65,18 @@ |
65 | 65 | %li |
66 | 66 | %p |
67 | 67 | Need a group for several dependent projects? |
68 | - = link_to new_group_path, class: "btn very_small" do | |
68 | + = link_to new_group_path, class: "btn btn-tiny" do | |
69 | 69 | Create a group |
70 | 70 | - if current_user.can_create_team? |
71 | 71 | %li |
72 | 72 | %p |
73 | 73 | Want to share a team between projects? |
74 | - = link_to new_team_path, class: "btn very_small" do | |
74 | + = link_to new_team_path, class: "btn btn-tiny" do | |
75 | 75 | Create a team |
76 | 76 | %fieldset |
77 | 77 | %legend |
78 | 78 | Personal projects: |
79 | - %small.right | |
79 | + %small.pull-right | |
80 | 80 | %span= current_user.personal_projects.count |
81 | 81 | of |
82 | 82 | %span= current_user.projects_limit |
... | ... | @@ -87,10 +87,10 @@ |
87 | 87 | %fieldset |
88 | 88 | %legend |
89 | 89 | SSH public keys: |
90 | - %span.right | |
90 | + %span.pull-right | |
91 | 91 | = link_to pluralize(current_user.keys.count, 'key'), keys_path |
92 | 92 | .padded |
93 | - = link_to "Add Public Key", new_key_path, class: "btn small" | |
93 | + = link_to "Add Public Key", new_key_path, class: "btn btn-small" | |
94 | 94 | |
95 | 95 | .form-actions |
96 | - = f.submit 'Save', class: "btn save-btn" | |
96 | + = f.submit 'Save', class: "btn btn-save" | ... | ... |
app/views/projects/_clone_panel.html.haml
... | ... | @@ -2,8 +2,8 @@ |
2 | 2 | .row |
3 | 3 | .span7 |
4 | 4 | .form-horizontal= render "shared/clone_panel" |
5 | - .span4.right | |
6 | - .right | |
5 | + .span4.pull-right | |
6 | + .pull-right | |
7 | 7 | - unless @project.empty_repo? |
8 | 8 | - if can? current_user, :download_code, @project |
9 | 9 | = link_to archive_project_repository_path(@project), class: "btn-small btn grouped" do | ... | ... |
app/views/projects/_form.html.haml
1 | 1 | = form_for(@project, remote: true) do |f| |
2 | 2 | - if @project.errors.any? |
3 | - .alert-message.block-message.error | |
3 | + .alert.alert-error | |
4 | 4 | %ul |
5 | 5 | - @project.errors.full_messages.each do |msg| |
6 | 6 | %li= msg |
... | ... | @@ -42,7 +42,7 @@ |
42 | 42 | = f.check_box :wiki_enabled |
43 | 43 | %span.descr Pages for project documentation |
44 | 44 | |
45 | - - if can? current_user, :change_public_mode, @project | |
45 | + - if can?(current_user, :change_public_mode, @project) | |
46 | 46 | %fieldset.features |
47 | 47 | %legend |
48 | 48 | %i.icon-share |
... | ... | @@ -77,9 +77,9 @@ |
77 | 77 | %br |
78 | 78 | |
79 | 79 | .actions |
80 | - = f.submit 'Save', class: "btn save-btn" | |
80 | + = f.submit 'Save', class: "btn btn-save" | |
81 | 81 | = link_to 'Cancel', @project, class: "btn" |
82 | 82 | - unless @project.new_record? |
83 | 83 | - if can?(current_user, :remove_project, @project) |
84 | - .right | |
85 | - = link_to 'Remove Project', @project, confirm: 'Removed project can not be restored! Are you sure?', method: :delete, class: "btn danger" | |
84 | + .pull-right | |
85 | + = link_to 'Remove Project', @project, confirm: 'Removed project can not be restored! Are you sure?', method: :delete, class: "btn btn-remove" | ... | ... |
app/views/projects/_new_form.html.haml
1 | 1 | = form_for(@project, remote: true) do |f| |
2 | 2 | - if @project.errors.any? |
3 | - .alert-message.block-message.error | |
3 | + .alert.alert-error | |
4 | 4 | %span= @project.errors.full_messages.first |
5 | 5 | .clearfix.project_name_holder |
6 | 6 | = f.label :name do |
7 | 7 | Project name is |
8 | 8 | .input |
9 | 9 | = f.text_field :name, placeholder: "Example Project", class: "xxlarge" |
10 | - = f.submit 'Create project', class: "btn success project-submit" | |
10 | + = f.submit 'Create project', class: "btn btn-create project-submit" | |
11 | 11 | |
12 | 12 | - if current_user.can_select_namespace? |
13 | 13 | .clearfix |
... | ... | @@ -24,11 +24,11 @@ |
24 | 24 | .clearfix |
25 | 25 | .input.light |
26 | 26 | Need a group for several dependent projects? |
27 | - = link_to new_group_path, class: "btn very_small" do | |
27 | + = link_to new_group_path, class: "btn btn-tiny" do | |
28 | 28 | Create a group |
29 | 29 | - if current_user.can_create_team? |
30 | 30 | .clearfix |
31 | 31 | .input.light |
32 | 32 | Want to share a project between team? |
33 | - = link_to new_team_path, class: "btn very_small" do | |
33 | + = link_to new_team_path, class: "btn btn-tiny" do | |
34 | 34 | Create a team | ... | ... |
app/views/projects/_project_head.html.haml
... | ... | @@ -13,19 +13,19 @@ |
13 | 13 | = link_to 'Snippets', project_snippets_path(@project), class: "snippets-tab tab" |
14 | 14 | |
15 | 15 | - if can? current_user, :admin_project, @project |
16 | - = nav_link(controller: :deploy_keys, html_options: {class: 'right'}) do | |
16 | + = nav_link(controller: :deploy_keys, html_options: {class: 'pull-right'}) do | |
17 | 17 | = link_to project_deploy_keys_path(@project) do |
18 | 18 | %span |
19 | 19 | Deploy Keys |
20 | - = nav_link(controller: :hooks, html_options: {class: 'right'}) do | |
20 | + = nav_link(controller: :hooks, html_options: {class: 'pull-right'}) do | |
21 | 21 | = link_to project_hooks_path(@project) do |
22 | 22 | %span |
23 | 23 | Hooks |
24 | - = nav_link(controller: :services, html_options: {class: 'right'}) do | |
24 | + = nav_link(controller: :services, html_options: {class: 'pull-right'}) do | |
25 | 25 | = link_to project_services_path(@project) do |
26 | 26 | %span |
27 | 27 | Services |
28 | - = nav_link(path: 'projects#edit', html_options: {class: 'right'}) do | |
28 | + = nav_link(path: 'projects#edit', html_options: {class: 'pull-right'}) do | |
29 | 29 | = link_to edit_project_path(@project), class: "stat-tab tab " do |
30 | 30 | %i.icon-edit |
31 | 31 | Edit | ... | ... |
app/views/projects/empty.html.haml
... | ... | @@ -31,4 +31,4 @@ |
31 | 31 | |
32 | 32 | - if can? current_user, :remove_project, @project |
33 | 33 | .prepend-top-20 |
34 | - = link_to 'Remove project', @project, confirm: 'Are you sure?', method: :delete, class: "btn danger right" | |
34 | + = link_to 'Remove project', @project, confirm: 'Are you sure?', method: :delete, class: "btn btn-remove pull-right" | ... | ... |
app/views/projects/graph.html.haml
... | ... | @@ -1,17 +0,0 @@ |
1 | -%h3.page_title Project Network Graph | |
2 | -%br | |
3 | - | |
4 | -.graph_holder | |
5 | - %h4 | |
6 | - %small You can move around the graph by using the arrow keys. | |
7 | - #holder.graph | |
8 | - .loading.loading-gray | |
9 | - | |
10 | -:javascript | |
11 | - var branch_graph; | |
12 | - $(function(){ | |
13 | - branch_graph = new BranchGraph($("#holder"), { | |
14 | - url: '#{url_for controller: 'projects', action: 'graph', format: :json}', | |
15 | - commit_url: '#{project_commit_path(@project, 'ae45ca32').gsub("ae45ca32", "%s")}' | |
16 | - }); | |
17 | - }); |
app/views/projects/teams/available.html.haml
... | ... | @@ -17,6 +17,6 @@ |
17 | 17 | |
18 | 18 | |
19 | 19 | .actions |
20 | - = submit_tag 'Assign', class: "btn save-btn" | |
21 | - = link_to "Cancel", project_team_index_path(@project), class: "btn cancel-btn" | |
20 | + = submit_tag 'Assign', class: "btn btn-create" | |
21 | + = link_to "Cancel", project_team_index_path(@project), class: "btn btn-cancel" | |
22 | 22 | ... | ... |
app/views/protected_branches/index.html.haml
... | ... | @@ -14,7 +14,7 @@ |
14 | 14 | - if can? current_user, :admin_project, @project |
15 | 15 | = form_for [@project, @protected_branch] do |f| |
16 | 16 | -if @protected_branch.errors.any? |
17 | - .alert-message.block-message.error | |
17 | + .alert.alert-error | |
18 | 18 | %ul |
19 | 19 | - @protected_branch.errors.full_messages.each do |msg| |
20 | 20 | %li= msg |
... | ... | @@ -24,7 +24,7 @@ |
24 | 24 | .span3 |
25 | 25 | = f.select(:name, @project.open_branches.map { |br| [br.name, br.name] } , {include_blank: "Select branch"}, {class: "chosen span3"}) |
26 | 26 | |
27 | - = f.submit 'Protect', class: "primary btn" | |
27 | + = f.submit 'Protect', class: "btn-primary btn" | |
28 | 28 | |
29 | 29 | - unless @branches.empty? |
30 | 30 | %table |
... | ... | @@ -51,4 +51,4 @@ |
51 | 51 | (branch was removed from repository) |
52 | 52 | %td |
53 | 53 | - if can? current_user, :admin_project, @project |
54 | - = link_to 'Unprotect', [@project, branch], confirm: 'Are you sure?', method: :delete, class: "danger btn small" | |
54 | + = link_to 'Unprotect', [@project, branch], confirm: 'Are you sure?', method: :delete, class: "btn btn-remove btn-small" | ... | ... |
app/views/public/projects/index.html.haml
app/views/repositories/_feed.html.haml
app/views/repositories/stats.html.haml
app/views/search/show.html.haml
... | ... | @@ -4,7 +4,7 @@ |
4 | 4 | %span Looking for |
5 | 5 | .input |
6 | 6 | = search_field_tag :search, params[:search], placeholder: "issue 143", class: "input-xxlarge search-text-input", id: "dashboard_search" |
7 | - = submit_tag 'Search', class: "btn primary wide" | |
7 | + = submit_tag 'Search', class: "btn btn-primary wide" | |
8 | 8 | .clearfix |
9 | 9 | .row |
10 | 10 | .span3 | ... | ... |
app/views/services/_gitlab_ci.html.haml
1 | 1 | %h3.page_title |
2 | 2 | GitLab CI |
3 | 3 | %small Continuous integration server from GitLab |
4 | - .right | |
4 | + .pull-right | |
5 | 5 | - if @service.active |
6 | 6 | %small.cgreen Enabled |
7 | 7 | - else |
... | ... | @@ -16,7 +16,7 @@ |
16 | 16 | %hr |
17 | 17 | = form_for(@service, :as => :service, :url => project_service_path(@project, :gitlab_ci), :method => :put) do |f| |
18 | 18 | - if @service.errors.any? |
19 | - .alert-message.block-message.error | |
19 | + .alert.alert-error | |
20 | 20 | %ul |
21 | 21 | - @service.errors.full_messages.each do |msg| |
22 | 22 | %li= msg |
... | ... | @@ -40,7 +40,7 @@ |
40 | 40 | |
41 | 41 | |
42 | 42 | .form-actions |
43 | - = f.submit 'Save', class: 'btn save-btn' | |
43 | + = f.submit 'Save', class: 'btn btn-save' | |
44 | 44 | |
45 | 45 | - if @service.valid? && @service.active |
46 | 46 | = link_to 'Test settings', test_project_service_path(@project), class: 'btn btn-small' | ... | ... |
app/views/services/index.html.haml
... | ... | @@ -8,7 +8,7 @@ |
8 | 8 | = link_to edit_project_service_path(@project, :gitlab_ci) do |
9 | 9 | GitLab CI |
10 | 10 | %small Continuous integration server from GitLab |
11 | - .right | |
11 | + .pull-right | |
12 | 12 | - if @gitlab_ci_service.try(:active) |
13 | 13 | %small.cgreen |
14 | 14 | %i.icon-ok |
... | ... | @@ -21,11 +21,11 @@ |
21 | 21 | %h4 |
22 | 22 | Jenkins CI |
23 | 23 | %small An extendable open source continuous integration server |
24 | - .right | |
24 | + .pull-right | |
25 | 25 | %small Not implemented yet |
26 | 26 | %li.disabled |
27 | 27 | %h4 |
28 | 28 | Campfire |
29 | 29 | %small Web-based group chat tool |
30 | - .right | |
30 | + .pull-right | |
31 | 31 | %small Not implemented yet | ... | ... |
app/views/snippets/_blob.html.haml
... | ... | @@ -3,7 +3,7 @@ |
3 | 3 | %i.icon-file |
4 | 4 | %strong= @snippet.file_name |
5 | 5 | %span.options |
6 | - = link_to "raw", raw_project_snippet_path(@project, @snippet), class: "btn very_small", target: "_blank" | |
6 | + = link_to "raw", raw_project_snippet_path(@project, @snippet), class: "btn btn-tiny", target: "_blank" | |
7 | 7 | .file_content.code |
8 | 8 | - unless @snippet.content.empty? |
9 | 9 | %div{class: user_color_scheme_class} | ... | ... |
app/views/snippets/_form.html.haml
... | ... | @@ -4,7 +4,7 @@ |
4 | 4 | .snippet-form-holder |
5 | 5 | = form_for [@project, @snippet] do |f| |
6 | 6 | -if @snippet.errors.any? |
7 | - .alert-message.block-message.error | |
7 | + .alert.alert-error | |
8 | 8 | %ul |
9 | 9 | - @snippet.errors.full_messages.each do |msg| |
10 | 10 | %li= msg |
... | ... | @@ -27,10 +27,10 @@ |
27 | 27 | = f.hidden_field :content, class: 'snippet-file-content' |
28 | 28 | |
29 | 29 | .form-actions |
30 | - = f.submit 'Save', class: "save-btn btn" | |
30 | + = f.submit 'Save', class: "btn-save btn" | |
31 | 31 | = link_to "Cancel", project_snippets_path(@project), class: " btn" |
32 | 32 | - unless @snippet.new_record? |
33 | - .right= link_to 'Destroy', [@project, @snippet], confirm: 'Are you sure?', method: :delete, class: "btn right danger delete-snippet", id: "destroy_snippet_#{@snippet.id}" | |
33 | + .pull-right= link_to 'Destroy', [@project, @snippet], confirm: 'Are you sure?', method: :delete, class: "btn pull-right danger delete-snippet", id: "destroy_snippet_#{@snippet.id}" | |
34 | 34 | |
35 | 35 | |
36 | 36 | :javascript | ... | ... |
app/views/snippets/index.html.haml
... | ... | @@ -5,7 +5,7 @@ |
5 | 5 | %small share code pastes with others out of git repository |
6 | 6 | |
7 | 7 | - if can? current_user, :write_snippet, @project |
8 | - = link_to new_project_snippet_path(@project), class: "btn small add_new right", title: "New Snippet" do | |
8 | + = link_to new_project_snippet_path(@project), class: "btn btn-small add_new pull-right", title: "New Snippet" do | |
9 | 9 | Add new snippet |
10 | 10 | %br |
11 | 11 | %table | ... | ... |
app/views/snippets/show.html.haml
... | ... | @@ -4,7 +4,7 @@ |
4 | 4 | = @snippet.title |
5 | 5 | %small= @snippet.file_name |
6 | 6 | - if can?(current_user, :admin_snippet, @project) || @snippet.author == current_user |
7 | - = link_to "Edit", edit_project_snippet_path(@project, @snippet), class: "btn small right" | |
7 | + = link_to "Edit", edit_project_snippet_path(@project, @snippet), class: "btn btn-small pull-right" | |
8 | 8 | |
9 | 9 | %br |
10 | 10 | %div= render 'blob' | ... | ... |
app/views/team_members/_form.html.haml
... | ... | @@ -3,7 +3,7 @@ |
3 | 3 | %hr |
4 | 4 | = form_for @user_project_relation, as: :team_member, url: project_team_members_path(@project) do |f| |
5 | 5 | -if @user_project_relation.errors.any? |
6 | - .alert-message.block-message.error | |
6 | + .alert.alert-error | |
7 | 7 | %ul |
8 | 8 | - @user_project_relation.errors.full_messages.each do |msg| |
9 | 9 | %li= msg |
... | ... | @@ -19,5 +19,5 @@ |
19 | 19 | .input= select_tag :project_access, options_for_select(Project.access_options, @user_project_relation.project_access), class: "project-access-select chosen" |
20 | 20 | |
21 | 21 | .actions |
22 | - = f.submit 'Save', class: "btn save-btn" | |
23 | - = link_to "Cancel", project_team_index_path(@project), class: "btn cancel-btn" | |
22 | + = f.submit 'Add users', class: "btn btn-create" | |
23 | + = link_to "Cancel", project_team_index_path(@project), class: "btn btn-cancel" | ... | ... |
app/views/team_members/_show.html.haml
... | ... | @@ -10,19 +10,19 @@ |
10 | 10 | %br |
11 | 11 | %small.cgray= user.email |
12 | 12 | |
13 | - .span5.right | |
13 | + .span5.pull-right | |
14 | 14 | - if allow_admin |
15 | 15 | .left |
16 | 16 | = form_for(member, as: :team_member, url: project_team_member_path(@project, member.user)) do |f| |
17 | 17 | = f.select :project_access, options_for_select(UsersProject.access_roles, member.project_access), {}, class: "medium project-access-select span2" |
18 | - .right | |
18 | + .pull-right | |
19 | 19 | - if current_user == user |
20 | 20 | %span.btn.disabled This is you! |
21 | 21 | - if @project.namespace_owner == user |
22 | - %span.btn.disabled.success Owner | |
22 | + %span.btn.disabled Owner | |
23 | 23 | - elsif user.blocked |
24 | 24 | %span.btn.disabled.blocked Blocked |
25 | 25 | - elsif allow_admin |
26 | - = link_to project_team_member_path(@project, user), confirm: remove_from_project_team_message(@project, user), method: :delete, class: "very_small btn danger" do | |
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 | 27 | %i.icon-minus.icon-white |
28 | 28 | ... | ... |
app/views/team_members/_show_team.html.haml
... | ... | @@ -7,9 +7,9 @@ |
7 | 7 | %br |
8 | 8 | %small.cgray Members: #{team.members.count} |
9 | 9 | |
10 | - .span5.right | |
11 | - .right | |
10 | + .span5.pull-right | |
11 | + .pull-right | |
12 | 12 | - if allow_admin |
13 | 13 | .left |
14 | - = link_to resign_project_team_path(@project, team), method: :delete, confirm: "Are you shure?", class: "btn danger small" do | |
14 | + = link_to resign_project_team_path(@project, team), method: :delete, confirm: "Are you shure?", class: "btn btn-remove small" do | |
15 | 15 | %i.icon-minus.icon-white | ... | ... |
app/views/team_members/import.html.haml
... | ... | @@ -12,6 +12,6 @@ |
12 | 12 | .input= select_tag(:source_project_id, options_from_collection_for_select(current_user.authorized_projects, :id, :name_with_namespace), prompt: "Select project", class: "chosen xxlarge", required: true) |
13 | 13 | |
14 | 14 | .actions |
15 | - = submit_tag 'Import', class: "btn save-btn" | |
16 | - = link_to "Cancel", project_team_index_path(@project), class: "btn cancel-btn" | |
15 | + = submit_tag 'Import', class: "btn btn-save" | |
16 | + = link_to "Cancel", project_team_index_path(@project), class: "btn btn-cancel" | |
17 | 17 | ... | ... |
app/views/team_members/index.html.haml
... | ... | @@ -7,12 +7,12 @@ |
7 | 7 | %strong= link_to "here", help_permissions_path, class: "vlink" |
8 | 8 | |
9 | 9 | - if can? current_user, :admin_team_member, @project |
10 | - %span.right | |
11 | - = link_to import_project_team_members_path(@project), class: "btn small grouped", title: "Import team from another project" do | |
10 | + %span.pull-right | |
11 | + = link_to import_project_team_members_path(@project), class: "btn btn-small grouped", title: "Import team from another project" do | |
12 | 12 | Import team from another project |
13 | - = link_to available_project_teams_path(@project), class: "btn small grouped", title: "Assign project to team of users" do | |
13 | + = link_to available_project_teams_path(@project), class: "btn btn-small grouped", title: "Assign project to team of users" do | |
14 | 14 | Assign project to Team of users |
15 | - = link_to new_project_team_member_path(@project), class: "btn success small grouped", title: "New Team Member" do | |
15 | + = link_to new_project_team_member_path(@project), class: "btn btn-primary small grouped", title: "New Team Member" do | |
16 | 16 | New Team Member |
17 | 17 | |
18 | 18 | %hr | ... | ... |
app/views/team_members/show.html.haml
... | ... | @@ -2,7 +2,7 @@ |
2 | 2 | |
3 | 3 | .team_member_show |
4 | 4 | - if can? current_user, :admin_project, @project |
5 | - = link_to 'Remove from team', project_team_member_path(@project, @member), confirm: 'Are you sure?', method: :delete, class: "right btn danger" | |
5 | + = link_to 'Remove from team', project_team_member_path(@project, @member), confirm: 'Are you sure?', method: :delete, class: "btn btn-remove pull-right" | |
6 | 6 | .profile_avatar_holder |
7 | 7 | = image_tag gravatar_icon(@member.email, 60), class: "borders" |
8 | 8 | %h3.page_title | ... | ... |
app/views/teams/_filter.html.haml
... | ... | @@ -25,9 +25,9 @@ |
25 | 25 | %li{class: ("active" if params[:project_id] == project.id.to_s)} |
26 | 26 | = link_to team_filter_path(entity, project_id: project.id) do |
27 | 27 | = project.name_with_namespace |
28 | - %small.right= entities_per_project(project, entity) | |
28 | + %small.pull-right= entities_per_project(project, entity) | |
29 | 29 | |
30 | 30 | %fieldset |
31 | 31 | %hr |
32 | - = link_to "Reset", team_filter_path(entity), class: 'btn right' | |
32 | + = link_to "Reset", team_filter_path(entity), class: 'btn pull-right' | |
33 | 33 | ... | ... |
app/views/teams/_projects.html.haml
... | ... | @@ -4,8 +4,8 @@ |
4 | 4 | %small |
5 | 5 | (#{projects.count}) |
6 | 6 | - if can? current_user, :manage_user_team, @team |
7 | - %span.right | |
8 | - = link_to new_team_project_path(@team), class: "btn very_small info" do | |
7 | + %span.pull-right | |
8 | + = link_to new_team_project_path(@team), class: "btn btn-tiny info" do | |
9 | 9 | %i.icon-plus |
10 | 10 | Assign Project |
11 | 11 | %ul.well-list | ... | ... |
app/views/teams/edit.html.haml
1 | 1 | %h3.page_title= "Edit Team #{@team.name}" |
2 | 2 | %hr |
3 | -= form_for @team, url: teams_path do |f| | |
3 | += form_for @team, url: team_path(@team) do |f| | |
4 | 4 | - if @team.errors.any? |
5 | - .alert-message.block-message.error | |
5 | + .alert.alert-error | |
6 | 6 | %span= @team.errors.full_messages.first |
7 | 7 | .clearfix |
8 | 8 | = f.label :name do |
... | ... | @@ -15,8 +15,6 @@ |
15 | 15 | Team path is |
16 | 16 | .input |
17 | 17 | = f.text_field :path, placeholder: "opensource", class: "xxlarge left" |
18 | - .clearfix | |
19 | - .input.span3.center | |
20 | - = f.submit 'Save team changes', class: "btn primary" | |
21 | - .input.span3.center | |
22 | - = link_to 'Delete team', team_path(@team), method: :delete, confirm: "You are shure?", class: "btn danger" | |
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/issues.html.haml
app/views/teams/members/_form.html.haml
1 | 1 | = form_tag admin_team_member_path(@team, @member), method: :put do |
2 | 2 | -if @member.errors.any? |
3 | - .alert-message.block-message.error | |
3 | + .alert.alert-error | |
4 | 4 | %ul |
5 | 5 | - @member.errors.full_messages.each do |msg| |
6 | 6 | %li= msg |
... | ... | @@ -16,5 +16,5 @@ |
16 | 16 | |
17 | 17 | %br |
18 | 18 | .actions |
19 | - = submit_tag 'Save', class: "btn primary" | |
19 | + = submit_tag 'Save', class: "btn btn-save" | |
20 | 20 | = link_to 'Cancel', :back, class: "btn" | ... | ... |
app/views/teams/members/_show.html.haml
... | ... | @@ -10,22 +10,22 @@ |
10 | 10 | %br |
11 | 11 | %small.cgray= user.email |
12 | 12 | |
13 | - .span6.right | |
13 | + .span6.pull-right | |
14 | 14 | - if allow_admin |
15 | 15 | .left.span2 |
16 | 16 | = form_for(member, as: :team_member, url: team_member_path(@team, user)) do |f| |
17 | 17 | = f.select :permission, options_for_select(UsersProject.access_roles, @team.default_projects_access(user)), {}, class: "medium project-access-select span2" |
18 | 18 | .left.span2 |
19 | 19 | %span |
20 | - Admin access | |
21 | 20 | = check_box_tag :group_admin, true, @team.admin?(user) |
22 | - .right | |
21 | + Admin access | |
22 | + .pull-right | |
23 | 23 | - if current_user == user |
24 | 24 | %span.btn.disabled This is you! |
25 | 25 | - if @team.owner == user |
26 | - %span.btn.disabled.success Owner | |
26 | + %span.btn.disabled.btn-success Owner | |
27 | 27 | - elsif user.blocked |
28 | 28 | %span.btn.disabled.blocked Blocked |
29 | 29 | - elsif allow_admin |
30 | - = link_to team_member_path(@team, user), confirm: remove_from_user_team_message(@team, user), method: :delete, class: "very_small btn danger" do | |
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 | 31 | %i.icon-minus.icon-white | ... | ... |
app/views/teams/members/index.html.haml
... | ... | @@ -6,8 +6,8 @@ |
6 | 6 | %strong= link_to "here", help_permissions_path, class: "vlink" |
7 | 7 | |
8 | 8 | - if can? current_user, :manage_user_team, @team |
9 | - %span.right | |
10 | - = link_to new_team_member_path(@team), class: "btn success small grouped", title: "New Team Member" do | |
9 | + %span.pull-right | |
10 | + = link_to new_team_member_path(@team), class: "btn btn-primary small grouped", title: "New Team Member" do | |
11 | 11 | New Team Member |
12 | 12 | %hr |
13 | 13 | ... | ... |
app/views/teams/members/new.html.haml
app/views/teams/members/show.html.haml
... | ... | @@ -3,7 +3,7 @@ |
3 | 3 | |
4 | 4 | .team_member_show |
5 | 5 | - if can? current_user, :admin_project, @project |
6 | - = link_to 'Remove from team', project_team_member_path(project_id: @project, id: @team_member.id), confirm: 'Are you sure?', method: :delete, class: "right btn danger" | |
6 | + = link_to 'Remove from team', project_team_member_path(project_id: @project, id: @team_member.id), confirm: 'Are you sure?', method: :delete, class: "pull-right btn btn-remove" | |
7 | 7 | .profile_avatar_holder |
8 | 8 | = image_tag gravatar_icon(user.email, 60), class: "borders" |
9 | 9 | %h3.page_title | ... | ... |
app/views/teams/merge_requests.html.haml
app/views/teams/new.html.haml
... | ... | @@ -2,7 +2,7 @@ |
2 | 2 | %hr |
3 | 3 | = form_for @team, url: teams_path do |f| |
4 | 4 | - if @team.errors.any? |
5 | - .alert-message.block-message.error | |
5 | + .alert.alert-error | |
6 | 6 | %span= @team.errors.full_messages.first |
7 | 7 | .clearfix |
8 | 8 | = f.label :name do |
... | ... | @@ -10,7 +10,7 @@ |
10 | 10 | .input |
11 | 11 | = f.text_field :name, placeholder: "Ex. Ruby Developers", class: "xxlarge left" |
12 | 12 | |
13 | - = f.submit 'Create team', class: "btn primary" | |
13 | + = f.submit 'Create team', class: "btn btn-create" | |
14 | 14 | %hr |
15 | 15 | .padded |
16 | 16 | %ul | ... | ... |
app/views/teams/projects/_form.html.haml
1 | 1 | = form_tag team_project_path(@team, @project), method: :put do |
2 | 2 | -if @project.errors.any? |
3 | - .alert-message.block-message.error | |
3 | + .alert.alert-error | |
4 | 4 | %ul |
5 | 5 | - @project.errors.full_messages.each do |msg| |
6 | 6 | %li= msg |
... | ... | @@ -12,5 +12,5 @@ |
12 | 12 | |
13 | 13 | %br |
14 | 14 | .actions |
15 | - = submit_tag 'Save', class: "btn primary" | |
16 | - = link_to 'Cancel', :back, class: "btn" | |
15 | + = submit_tag 'Save', class: "btn btn-save" | |
16 | + = link_to 'Cancel', :back, class: "btn btn-cancel" | ... | ... |
app/views/teams/projects/edit.html.haml
1 | -%h3 | |
2 | - Edit max access in #{@project.name} for #{@team.name} team | |
1 | +%h3.page_title | |
2 | + Edit max access in #{link_to @project.name_with_namespace, @project} for #{link_to(@team.name, team_path(@team))} team | |
3 | 3 | |
4 | 4 | %hr |
5 | -%table.zebra-striped | |
6 | - %tr | |
7 | - %td Project: | |
8 | - %td= @project.name | |
9 | - %tr | |
10 | - %td Team: | |
11 | - %td= @team.name | |
12 | - %tr | |
13 | - %td Since: | |
14 | - %td= assigned_since(@team, @project).stamp("Nov 11, 2010") | |
15 | 5 | |
16 | 6 | = render 'form' | ... | ... |
app/views/teams/projects/index.html.haml
... | ... | @@ -5,8 +5,8 @@ |
5 | 5 | %strong= link_to "here", help_permissions_path, class: "vlink" |
6 | 6 | |
7 | 7 | - if current_user.can?(:manage_user_team, @team) && @avaliable_projects.any? |
8 | - %span.right | |
9 | - = link_to new_team_project_path(@team), class: "btn success small grouped", title: "New Team Member" do | |
8 | + %span.pull-right | |
9 | + = link_to new_team_project_path(@team), class: "btn btn-primary small grouped", title: "New Team Member" do | |
10 | 10 | Assign project to Team |
11 | 11 | |
12 | 12 | %hr |
... | ... | @@ -29,8 +29,8 @@ |
29 | 29 | |
30 | 30 | - if current_user.can?(:admin_user_team, @team) |
31 | 31 | %td.bgred |
32 | - = link_to 'Edit max access', edit_team_project_path(@team, project), class: "btn small" | |
33 | - = link_to 'Relegate', team_project_path(@team, project), confirm: 'Remove project from team and move to global namespace. Are you sure?', method: :delete, class: "btn danger small" | |
32 | + = link_to 'Edit max access', edit_team_project_path(@team, project), class: "btn btn-small" | |
33 | + = link_to 'Relegate', team_project_path(@team, project), confirm: 'Remove project from team and move to global namespace. Are you sure?', method: :delete, class: "btn btn-remove small" | |
34 | 34 | |
35 | 35 | - else |
36 | 36 | %p.nothing_here_message This team has no projects yet | ... | ... |
app/views/teams/projects/new.html.haml
... | ... | @@ -20,4 +20,4 @@ |
20 | 20 | %tr |
21 | 21 | %td= select_tag :project_ids, options_from_collection_for_select(@avaliable_projects , :id, :name_with_namespace), multiple: true, data: {placeholder: 'Select projects'}, class: 'chosen span5' |
22 | 22 | %td= select_tag :greatest_project_access, options_for_select(UserTeam.access_roles), {class: "project-access-select chosen span3" } |
23 | - %td= submit_tag 'Add', class: "btn primary", id: :assign_projects_to_team | |
23 | + %td= submit_tag 'Add Project', class: "btn btn-create", id: :assign_projects_to_team | ... | ... |
app/views/teams/show.html.haml
app/views/tree/_blob_actions.html.haml
1 | 1 | .btn-group.tree-btn-group |
2 | 2 | -# only show edit link for text files |
3 | 3 | - if @tree.text? |
4 | - = link_to "edit", edit_project_tree_path(@project, @id), class: "btn very_small", disabled: !allowed_tree_edit? | |
5 | - = link_to "raw", project_blob_path(@project, @id), class: "btn very_small", target: "_blank" | |
4 | + = link_to "edit", edit_project_tree_path(@project, @id), class: "btn btn-tiny", disabled: !allowed_tree_edit? | |
5 | + = link_to "raw", project_blob_path(@project, @id), class: "btn btn-tiny", target: "_blank" | |
6 | 6 | -# only show normal/blame view links for text files |
7 | 7 | - if @tree.text? |
8 | 8 | - if current_page? project_blame_path(@project, @id) |
9 | - = link_to "normal view", project_tree_path(@project, @id), class: "btn very_small" | |
9 | + = link_to "normal view", project_tree_path(@project, @id), class: "btn btn-tiny" | |
10 | 10 | - else |
11 | - = link_to "blame", project_blame_path(@project, @id), class: "btn very_small" | |
12 | - = link_to "history", project_commits_path(@project, @id), class: "btn very_small" | |
11 | + = link_to "blame", project_blame_path(@project, @id), class: "btn btn-tiny" | |
12 | + = link_to "history", project_commits_path(@project, @id), class: "btn btn-tiny" | ... | ... |
app/views/tree/_head.html.haml
app/views/tree/_tree.html.haml
... | ... | @@ -24,7 +24,7 @@ |
24 | 24 | %th Name |
25 | 25 | %th Last Update |
26 | 26 | %th Last Commit |
27 | - %th= link_to "history", project_commits_path(@project, @id), class: "btn very_small right" | |
27 | + %th= link_to "history", project_commits_path(@project, @id), class: "btn btn-tiny pull-right" | |
28 | 28 | |
29 | 29 | - if tree.up_dir? |
30 | 30 | %tr.tree-item | ... | ... |
app/views/tree/edit.html.haml
... | ... | @@ -10,7 +10,7 @@ |
10 | 10 | %strong= @ref |
11 | 11 | %span.options |
12 | 12 | .btn-group.tree-btn-group |
13 | - = link_to "Cancel", project_tree_path(@project, @id), class: "btn very_small cancel-btn", confirm: "Are you sure?" | |
13 | + = link_to "Cancel", project_tree_path(@project, @id), class: "btn btn-tiny btn-cancel", confirm: "Are you sure?" | |
14 | 14 | .file_content.code |
15 | 15 | %pre#editor= @tree.data |
16 | 16 | |
... | ... | @@ -27,7 +27,7 @@ |
27 | 27 | .message |
28 | 28 | to branch |
29 | 29 | %strong= @ref |
30 | - = link_to "Cancel", project_tree_path(@project, @id), class: "btn cancel-btn", confirm: "Are you sure?" | |
30 | + = link_to "Cancel", project_tree_path(@project, @id), class: "btn btn-cancel", confirm: "Are you sure?" | |
31 | 31 | |
32 | 32 | :javascript |
33 | 33 | var ace_mode = "#{@tree.language.try(:ace_mode)}"; | ... | ... |
app/views/users/_profile.html.haml
... | ... | @@ -4,20 +4,20 @@ |
4 | 4 | %ul.well-list |
5 | 5 | %li |
6 | 6 | %strong Email |
7 | - %span.right= mail_to @user.email | |
7 | + %span.pull-right= mail_to @user.email | |
8 | 8 | - unless @user.skype.blank? |
9 | 9 | %li |
10 | 10 | %strong Skype |
11 | - %span.right= @user.skype | |
11 | + %span.pull-right= @user.skype | |
12 | 12 | - unless @user.linkedin.blank? |
13 | 13 | %li |
14 | 14 | %strong LinkedIn |
15 | - %span.right= @user.linkedin | |
15 | + %span.pull-right= @user.linkedin | |
16 | 16 | - unless @user.twitter.blank? |
17 | 17 | %li |
18 | 18 | %strong Twitter |
19 | - %span.right= @user.twitter | |
19 | + %span.pull-right= @user.twitter | |
20 | 20 | - unless @user.bio.blank? |
21 | 21 | %li |
22 | 22 | %strong Bio |
23 | - %span.right= @user.bio | |
23 | + %span.pull-right= @user.bio | ... | ... |
app/views/users/_projects.html.haml
app/views/users/show.html.haml
... | ... | @@ -4,8 +4,8 @@ |
4 | 4 | = image_tag gravatar_icon(@user.email, 90), class: "avatar s90" |
5 | 5 | = @user.name |
6 | 6 | - if @user == current_user |
7 | - .right | |
8 | - = link_to profile_path, class: 'btn small' do | |
7 | + .pull-right | |
8 | + = link_to profile_path, class: 'btn btn-small' do | |
9 | 9 | %i.icon-edit |
10 | 10 | Edit Profile |
11 | 11 | %br | ... | ... |
app/views/wikis/_form.html.haml
... | ... | @@ -23,5 +23,5 @@ |
23 | 23 | = f.label :content |
24 | 24 | .input= f.text_area :content, class: 'span8 js-gfm-input' |
25 | 25 | .actions |
26 | - = f.submit 'Save', class: "save-btn btn" | |
27 | - = link_to "Cancel", project_wiki_path(@project, :index), class: "btn cancel-btn" | |
26 | + = f.submit 'Save', class: "btn-save btn" | |
27 | + = link_to "Cancel", project_wiki_path(@project, :index), class: "btn btn-cancel" | ... | ... |
app/views/wikis/edit.html.haml
... | ... | @@ -2,7 +2,7 @@ |
2 | 2 | %hr |
3 | 3 | = render 'form' |
4 | 4 | |
5 | -.right | |
5 | +.pull-right | |
6 | 6 | - if can? current_user, :admin_wiki, @project |
7 | - = link_to project_wiki_path(@project, @wiki), confirm: "Are you sure you want to delete this page?", method: :delete, class: "btn small danger" do | |
7 | + = link_to project_wiki_path(@project, @wiki), confirm: "Are you sure you want to delete this page?", method: :delete, class: "btn btn-small btn-remove" do | |
8 | 8 | Delete this page |
9 | 9 | \ No newline at end of file | ... | ... |
app/views/wikis/show.html.haml
1 | 1 | %h3.page_title |
2 | 2 | = @wiki.title |
3 | - %span.right | |
4 | - = link_to pages_project_wikis_path(@project), class: "btn small grouped" do | |
3 | + %span.pull-right | |
4 | + = link_to pages_project_wikis_path(@project), class: "btn btn-small grouped" do | |
5 | 5 | Pages |
6 | 6 | - if can? current_user, :write_wiki, @project |
7 | - = link_to history_project_wiki_path(@project, @wiki), class: "btn small grouped" do | |
7 | + = link_to history_project_wiki_path(@project, @wiki), class: "btn btn-small grouped" do | |
8 | 8 | History |
9 | - = link_to edit_project_wiki_path(@project, @wiki), class: "btn small grouped" do | |
9 | + = link_to edit_project_wiki_path(@project, @wiki), class: "btn btn-small grouped" do | |
10 | 10 | %i.icon-edit |
11 | 11 | Edit |
12 | 12 | %br | ... | ... |
app/workers/post_receive.rb
... | ... | @@ -27,11 +27,15 @@ class PostReceive |
27 | 27 | User.find_by_email(email) if email |
28 | 28 | elsif /^[A-Z0-9._%a-z\-]+@(?:[A-Z0-9a-z\-]+\.)+[A-Za-z]{2,4}$/.match(identifier) |
29 | 29 | User.find_by_email(identifier) |
30 | - else | |
31 | - Key.find_by_identifier(identifier).try(:user) | |
30 | + elsif identifier =~ /key/ | |
31 | + key_id = identifier.gsub("key-", "") | |
32 | + Key.find_by_id(key_id).try(:user) | |
32 | 33 | end |
33 | 34 | |
34 | - return false unless user | |
35 | + unless user | |
36 | + Gitlab::GitLogger.error("POST-RECEIVE: Triggered hook for non-existing user \"#{identifier} \"") | |
37 | + return false | |
38 | + end | |
35 | 39 | |
36 | 40 | project.trigger_post_receive(oldrev, newrev, ref, user) |
37 | 41 | end | ... | ... |
config/database.yml.postgresql
config/gitlab.yml.example
... | ... | @@ -96,7 +96,7 @@ omniauth: |
96 | 96 | # GitLab Satellites |
97 | 97 | satellites: |
98 | 98 | # Relative paths are relative to Rails.root (default: tmp/repo_satellites/) |
99 | - path: /home/gitlab/gitlab-satellites/ | |
99 | + path: /home/git/gitlab-satellites/ | |
100 | 100 | |
101 | 101 | ## Backup settings |
102 | 102 | backup: |
... | ... | @@ -105,8 +105,6 @@ backup: |
105 | 105 | |
106 | 106 | ## Gitolite settings |
107 | 107 | gitolite: |
108 | - admin_uri: git@localhost:gitolite-admin | |
109 | - | |
110 | 108 | # REPOS_PATH MUST NOT BE A SYMLINK!!! |
111 | 109 | repos_path: /home/git/repositories/ |
112 | 110 | hooks_path: /home/git/.gitolite/hooks/ | ... | ... |
config/initializers/1_settings.rb
... | ... | @@ -51,7 +51,7 @@ Settings.gitlab['protocol'] ||= Settings.gitlab.https ? "https" : "http" |
51 | 51 | Settings.gitlab['email_from'] ||= "gitlab@#{Settings.gitlab.host}" |
52 | 52 | Settings.gitlab['support_email'] ||= Settings.gitlab.email_from |
53 | 53 | Settings.gitlab['url'] ||= Settings.send(:build_gitlab_url) |
54 | -Settings.gitlab['user'] ||= 'gitlab' | |
54 | +Settings.gitlab['user'] ||= 'git' | |
55 | 55 | Settings.gitlab['signup_enabled'] ||= false |
56 | 56 | |
57 | 57 | Settings['gravatar'] ||= Settingslogic.new({}) | ... | ... |
config/initializers/5_backend.rb
config/routes.rb
... | ... | @@ -130,7 +130,7 @@ Gitlab::Application.routes.draw do |
130 | 130 | # |
131 | 131 | # Groups Area |
132 | 132 | # |
133 | - resources :groups, constraints: { id: /[^\/]+/ }, only: [:show, :new, :create] do | |
133 | + resources :groups, constraints: { id: /[^\/]+/ } do | |
134 | 134 | member do |
135 | 135 | get :issues |
136 | 136 | get :merge_requests |
... | ... | @@ -164,7 +164,6 @@ Gitlab::Application.routes.draw do |
164 | 164 | resources :projects, constraints: { id: /[a-zA-Z.0-9_\-\/]+/ }, except: [:new, :create, :index], path: "/" do |
165 | 165 | member do |
166 | 166 | get "wall" |
167 | - get "graph" | |
168 | 167 | get "files" |
169 | 168 | end |
170 | 169 | |
... | ... | @@ -174,6 +173,7 @@ Gitlab::Application.routes.draw do |
174 | 173 | resources :compare, only: [:index, :create] |
175 | 174 | resources :blame, only: [:show], constraints: {id: /.+/} |
176 | 175 | resources :blob, only: [:show], constraints: {id: /.+/} |
176 | + resources :graph, only: [:show], constraints: {id: /.+/} | |
177 | 177 | match "/compare/:from...:to" => "compare#show", as: "compare", |
178 | 178 | :via => [:get, :post], constraints: {from: /.+/, to: /.+/} |
179 | 179 | ... | ... |
config/unicorn.rb.example
db/migrate/20130131070232_remove_private_flag_from_project.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 => 20130125090214) do | |
14 | +ActiveRecord::Schema.define(:version => 20130131070232) do | |
15 | 15 | |
16 | 16 | create_table "events", :force => true do |t| |
17 | 17 | t.string "target_type" |
... | ... | @@ -147,7 +147,6 @@ ActiveRecord::Schema.define(:version => 20130125090214) do |
147 | 147 | t.text "description" |
148 | 148 | t.datetime "created_at", :null => false |
149 | 149 | t.datetime "updated_at", :null => false |
150 | - t.boolean "private_flag", :default => true, :null => false | |
151 | 150 | t.integer "creator_id" |
152 | 151 | t.string "default_branch" |
153 | 152 | t.boolean "issues_enabled", :default => true, :null => false | ... | ... |
doc/api/README.md
... | ... | @@ -32,6 +32,7 @@ When listing resources you can pass the following parameters: |
32 | 32 | + [Users](https://github.com/gitlabhq/gitlabhq/blob/master/doc/api/users.md) |
33 | 33 | + [Session](https://github.com/gitlabhq/gitlabhq/blob/master/doc/api/session.md) |
34 | 34 | + [Projects](https://github.com/gitlabhq/gitlabhq/blob/master/doc/api/projects.md) |
35 | ++ [Groups](https://github.com/gitlabhq/gitlabhq/blob/master/doc/api/groups.md) | |
35 | 36 | + [Snippets](https://github.com/gitlabhq/gitlabhq/blob/master/doc/api/snippets.md) |
36 | 37 | + [Repositories](https://github.com/gitlabhq/gitlabhq/blob/master/doc/api/repositories.md) |
37 | 38 | + [Issues](https://github.com/gitlabhq/gitlabhq/blob/master/doc/api/issues.md) | ... | ... |
... | ... | @@ -0,0 +1,45 @@ |
1 | +## List project groups | |
2 | + | |
3 | +Get a list of groups. (As user: my groups, as admin: all groups) | |
4 | + | |
5 | +``` | |
6 | +GET /groups | |
7 | +``` | |
8 | + | |
9 | +```json | |
10 | +[ | |
11 | + { | |
12 | + "id": 1, | |
13 | + "name": "Foobar Group", | |
14 | + "path": "foo-bar", | |
15 | + "owner_id": 18 | |
16 | + } | |
17 | +] | |
18 | +``` | |
19 | + | |
20 | +## Details of group | |
21 | + | |
22 | +Get all details of a group. | |
23 | + | |
24 | +``` | |
25 | +GET /groups/:id | |
26 | +``` | |
27 | + | |
28 | +Parameters: | |
29 | + | |
30 | ++ `id` (required) - The ID of a group | |
31 | + | |
32 | +## New group | |
33 | + | |
34 | +Create a new project group. Available only for admin | |
35 | + | |
36 | +``` | |
37 | +POST /groups | |
38 | +``` | |
39 | + | |
40 | +Parameters: | |
41 | ++ `name` (required) - Email | |
42 | ++ `path` - Password | |
43 | + | |
44 | +Will return created group with status `201 Created` on success, or `404 Not found` on fail. | |
45 | + | ... | ... |
doc/api/notes.md
... | ... | @@ -30,6 +30,19 @@ Parameters: |
30 | 30 | |
31 | 31 | + `id` (required) - The ID of a project |
32 | 32 | |
33 | +### List merge request notes | |
34 | + | |
35 | +Get a list of merge request notes. | |
36 | + | |
37 | +``` | |
38 | +GET /projects/:id/merge_requests/:merge_request_id/notes | |
39 | +``` | |
40 | + | |
41 | +Parameters: | |
42 | + | |
43 | ++ `id` (required) - The ID of a project | |
44 | ++ `merge_request_id` (required) - The ID of an merge request | |
45 | + | |
33 | 46 | ### List issue notes |
34 | 47 | |
35 | 48 | Get a list of issue notes. | ... | ... |
doc/api/projects.md
... | ... | @@ -22,6 +22,8 @@ GET /projects |
22 | 22 | "created_at": "2012-05-23T08:00:58Z" |
23 | 23 | }, |
24 | 24 | "private": true, |
25 | + "path": "rails", | |
26 | + "path_with_namespace": "rails/rails", | |
25 | 27 | "issues_enabled": false, |
26 | 28 | "merge_requests_enabled": false, |
27 | 29 | "wall_enabled": true, |
... | ... | @@ -42,6 +44,8 @@ GET /projects |
42 | 44 | "created_at": "2012-05-23T08:00:58Z" |
43 | 45 | }, |
44 | 46 | "private": true, |
47 | + "path": "gitlab", | |
48 | + "path_with_namespace": "randx/gitlab", | |
45 | 49 | "issues_enabled": true, |
46 | 50 | "merge_requests_enabled": true, |
47 | 51 | "wall_enabled": true, |
... | ... | @@ -78,6 +82,8 @@ Parameters: |
78 | 82 | "created_at": "2012-05-23T08:00:58Z" |
79 | 83 | }, |
80 | 84 | "private": true, |
85 | + "path": "gitlab", | |
86 | + "path_with_namespace": "randx/gitlab", | |
81 | 87 | "issues_enabled": true, |
82 | 88 | "merge_requests_enabled": true, |
83 | 89 | "wall_enabled": true, | ... | ... |
doc/api/repositories.md
... | ... | @@ -33,7 +33,8 @@ Parameters: |
33 | 33 | }, |
34 | 34 | "authored_date": "2012-06-27T05:51:39-07:00", |
35 | 35 | "committed_date": "2012-06-28T03:44:20-07:00" |
36 | - } | |
36 | + }, | |
37 | + "protected": true | |
37 | 38 | } |
38 | 39 | ] |
39 | 40 | ``` |
... | ... | @@ -73,7 +74,88 @@ Parameters: |
73 | 74 | }, |
74 | 75 | "authored_date": "2012-06-27T05:51:39-07:00", |
75 | 76 | "committed_date": "2012-06-28T03:44:20-07:00" |
76 | - } | |
77 | + }, | |
78 | + "protected": true | |
79 | +} | |
80 | +``` | |
81 | + | |
82 | +## Protect a project repository branch | |
83 | + | |
84 | +Protect a single project repository branch. | |
85 | + | |
86 | +``` | |
87 | +PUT /projects/:id/repository/branches/:branch/protect | |
88 | +``` | |
89 | + | |
90 | +Parameters: | |
91 | + | |
92 | ++ `id` (required) - The ID of a project | |
93 | ++ `branch` (required) - The name of the branch | |
94 | + | |
95 | +```json | |
96 | +{ | |
97 | + "name": "master", | |
98 | + "commit": { | |
99 | + "id": "7b5c3cc8be40ee161ae89a06bba6229da1032a0c", | |
100 | + "parents": [ | |
101 | + { | |
102 | + "id": "4ad91d3c1144c406e50c7b33bae684bd6837faf8" | |
103 | + } | |
104 | + ], | |
105 | + "tree": "46e82de44b1061621357f24c05515327f2795a95", | |
106 | + "message": "add projects API", | |
107 | + "author": { | |
108 | + "name": "John Smith", | |
109 | + "email": "john@example.com" | |
110 | + }, | |
111 | + "committer": { | |
112 | + "name": "John Smith", | |
113 | + "email": "john@example.com" | |
114 | + }, | |
115 | + "authored_date": "2012-06-27T05:51:39-07:00", | |
116 | + "committed_date": "2012-06-28T03:44:20-07:00" | |
117 | + }, | |
118 | + "protected": true | |
119 | +} | |
120 | +``` | |
121 | + | |
122 | +## Unprotect a project repository branch | |
123 | + | |
124 | +Unprotect a single project repository branch. | |
125 | + | |
126 | +``` | |
127 | +PUT /projects/:id/repository/branches/:branch/unprotect | |
128 | +``` | |
129 | + | |
130 | +Parameters: | |
131 | + | |
132 | ++ `id` (required) - The ID of a project | |
133 | ++ `branch` (required) - The name of the branch | |
134 | + | |
135 | +```json | |
136 | +{ | |
137 | + "name": "master", | |
138 | + "commit": { | |
139 | + "id": "7b5c3cc8be40ee161ae89a06bba6229da1032a0c", | |
140 | + "parents": [ | |
141 | + { | |
142 | + "id": "4ad91d3c1144c406e50c7b33bae684bd6837faf8" | |
143 | + } | |
144 | + ], | |
145 | + "tree": "46e82de44b1061621357f24c05515327f2795a95", | |
146 | + "message": "add projects API", | |
147 | + "author": { | |
148 | + "name": "John Smith", | |
149 | + "email": "john@example.com" | |
150 | + }, | |
151 | + "committer": { | |
152 | + "name": "John Smith", | |
153 | + "email": "john@example.com" | |
154 | + }, | |
155 | + "authored_date": "2012-06-27T05:51:39-07:00", | |
156 | + "committed_date": "2012-06-28T03:44:20-07:00" | |
157 | + }, | |
158 | + "protected": false | |
77 | 159 | } |
78 | 160 | ``` |
79 | 161 | |
... | ... | @@ -110,7 +192,8 @@ Parameters: |
110 | 192 | }, |
111 | 193 | "authored_date": "2012-05-28T04:42:42-07:00", |
112 | 194 | "committed_date": "2012-05-28T04:42:42-07:00" |
113 | - } | |
195 | + }, | |
196 | + "protected": null | |
114 | 197 | } |
115 | 198 | ] |
116 | 199 | ``` | ... | ... |
doc/api/users.md
... | ... | @@ -20,6 +20,8 @@ GET /users |
20 | 20 | "linkedin": "", |
21 | 21 | "twitter": "", |
22 | 22 | "dark_scheme": false, |
23 | + "extern_uid": "john.smith", | |
24 | + "provider": "provider_name", | |
23 | 25 | "theme_id": 1 |
24 | 26 | }, |
25 | 27 | { |
... | ... | @@ -34,6 +36,8 @@ GET /users |
34 | 36 | "linkedin": "", |
35 | 37 | "twitter": "", |
36 | 38 | "dark_scheme": true, |
39 | + "extern_uid": "jack.smith", | |
40 | + "provider": "provider_name", | |
37 | 41 | "theme_id": 1 |
38 | 42 | } |
39 | 43 | ] |
... | ... | @@ -64,6 +68,8 @@ Parameters: |
64 | 68 | "linkedin": "", |
65 | 69 | "twitter": "", |
66 | 70 | "dark_scheme": false, |
71 | + "extern_uid": "john.smith", | |
72 | + "provider": "provider_name", | |
67 | 73 | "theme_id": 1 |
68 | 74 | } |
69 | 75 | ``` |
... | ... | @@ -84,10 +90,47 @@ Parameters: |
84 | 90 | + `linkedin` - Linkedin |
85 | 91 | + `twitter` - Twitter account |
86 | 92 | + `projects_limit` - Number of projects user can create |
93 | ++ `extern_uid` - External UID | |
94 | ++ `provider` - External provider name | |
95 | ++ `bio` - User's bio | |
87 | 96 | |
88 | 97 | Will return created user with status `201 Created` on success, or `404 Not |
89 | 98 | found` on fail. |
90 | 99 | |
100 | +## User modification | |
101 | +Modify user. Available only for admin | |
102 | + | |
103 | +``` | |
104 | +PUT /users/:id | |
105 | +``` | |
106 | + | |
107 | +Parameters: | |
108 | ++ `email` - Email | |
109 | ++ `username` - Username | |
110 | ++ `name` - Name | |
111 | ++ `password` - Password | |
112 | ++ `skype` - Skype ID | |
113 | ++ `linkedin` - Linkedin | |
114 | ++ `twitter` - Twitter account | |
115 | ++ `projects_limit` - Limit projects wich user can create | |
116 | ++ `extern_uid` - External UID | |
117 | ++ `provider` - External provider name | |
118 | ++ `bio` - User's bio | |
119 | + | |
120 | + | |
121 | +Will return created user with status `200 OK` on success, or `404 Not | |
122 | +found` on fail. | |
123 | + | |
124 | +## User deletion | |
125 | +Delete user. Available only for admin | |
126 | + | |
127 | +``` | |
128 | +DELETE /users/:id | |
129 | +``` | |
130 | + | |
131 | +Will return deleted user with status `200 OK` on success, or `404 Not | |
132 | +found` on fail. | |
133 | + | |
91 | 134 | ## Current user |
92 | 135 | |
93 | 136 | Get currently authenticated user. | ... | ... |
doc/install/installation.md
... | ... | @@ -90,134 +90,75 @@ Install the Bundler Gem: |
90 | 90 | |
91 | 91 | # 3. System Users |
92 | 92 | |
93 | -Create a user for Git and Gitolite: | |
93 | +Create a `git` user for Gitlab: | |
94 | 94 | |
95 | - sudo adduser \ | |
96 | - --system \ | |
97 | - --shell /bin/sh \ | |
98 | - --gecos 'Git Version Control' \ | |
99 | - --group \ | |
100 | - --disabled-password \ | |
101 | - --home /home/git \ | |
102 | - git | |
95 | + sudo adduser --disabled-login --gecos 'GitLab' git | |
103 | 96 | |
104 | -Create a user for GitLab: | |
97 | +# 4. GitLab shell | |
105 | 98 | |
106 | - sudo adduser --disabled-login --gecos 'GitLab' gitlab | |
107 | - | |
108 | - # Add it to the git group | |
109 | - sudo usermod -a -G git gitlab | |
110 | - | |
111 | - # Generate the SSH key | |
112 | - sudo -u gitlab -H ssh-keygen -q -N '' -t rsa -f /home/gitlab/.ssh/id_rsa | |
113 | - | |
114 | - | |
115 | -# 4. Gitolite | |
116 | - | |
117 | -Clone GitLab's fork of the Gitolite source code: | |
99 | + # login as git | |
100 | + sudo su git | |
118 | 101 | |
102 | + # go to home directory | |
119 | 103 | cd /home/git |
120 | - sudo -u git -H git clone -b gl-v320 https://github.com/gitlabhq/gitolite.git /home/git/gitolite | |
121 | - | |
122 | -Setup Gitolite with GitLab as its admin: | |
123 | - | |
124 | -**Important Note:** | |
125 | -GitLab assumes *full and unshared* control over this Gitolite installation. | |
126 | - | |
127 | - # Add Gitolite scripts to $PATH | |
128 | - sudo -u git -H mkdir /home/git/bin | |
129 | - sudo -u git -H sh -c 'printf "%b\n%b\n" "PATH=\$PATH:/home/git/bin" "export PATH" >> /home/git/.profile' | |
130 | - sudo -u git -H sh -c 'gitolite/install -ln /home/git/bin' | |
131 | - | |
132 | - # Copy the gitlab user's (public) SSH key ... | |
133 | - sudo cp /home/gitlab/.ssh/id_rsa.pub /home/git/gitlab.pub | |
134 | - sudo chmod 0444 /home/git/gitlab.pub | |
135 | - | |
136 | - # ... and use it as the admin key for the Gitolite setup | |
137 | - sudo -u git -H sh -c "PATH=/home/git/bin:$PATH; gitolite setup -pk /home/git/gitlab.pub" | |
138 | - | |
139 | -Fix the directory permissions for the configuration directory: | |
140 | - | |
141 | - # Make sure the Gitolite config dir is owned by git | |
142 | - sudo chmod 750 /home/git/.gitolite/ | |
143 | - sudo chown -R git:git /home/git/.gitolite/ | |
144 | 104 | |
145 | -Fix the directory permissions for the repositories: | |
105 | + # clone gitlab shell | |
106 | + git clone https://github.com/gitlabhq/gitlab-shell.git | |
146 | 107 | |
147 | - # Make sure the repositories dir is owned by git and it stays that way | |
148 | - sudo chmod -R ug+rwXs,o-rwx /home/git/repositories/ | |
149 | - sudo chown -R git:git /home/git/repositories/ | |
108 | + # setup | |
109 | + cd gitlab-shell | |
110 | + cp config.yml.example config.yml | |
111 | + ./bin/install | |
150 | 112 | |
151 | 113 | |
152 | -## Add domains to list to the list of known hosts | |
153 | - | |
154 | - sudo -u gitlab -H ssh git@localhost | |
155 | - sudo -u gitlab -H ssh git@YOUR_DOMAIN_NAME | |
156 | - sudo -u gitlab -H ssh git@YOUR_GITOLITE_DOMAIN_NAME | |
157 | - | |
158 | - | |
159 | -## Test if everything works so far | |
160 | - | |
161 | - # Clone the admin repo so SSH adds localhost to known_hosts ... | |
162 | - # ... and to be sure your users have access to Gitolite | |
163 | - sudo -u gitlab -H git clone git@localhost:gitolite-admin.git /tmp/gitolite-admin | |
164 | - | |
165 | - # If it succeeded without errors you can remove the cloned repo | |
166 | - sudo rm -rf /tmp/gitolite-admin | |
167 | - | |
168 | -**Important Note:** | |
169 | -If you can't clone the `gitolite-admin` repository: **DO NOT PROCEED WITH INSTALLATION**! | |
170 | -Check the [Trouble Shooting Guide](https://github.com/gitlabhq/gitlab-public-wiki/wiki/Trouble-Shooting-Guide) | |
171 | -and make sure you have followed all of the above steps carefully. | |
172 | - | |
173 | 114 | |
174 | 115 | # 5. Database |
175 | 116 | |
176 | -See `doc/install/databases.md` | |
117 | +To setup the MySQL/PostgreSQL database and dependencies please see [`doc/install/databases.md`](./databases.md) . | |
177 | 118 | |
178 | 119 | |
179 | 120 | # 6. GitLab |
180 | 121 | |
181 | - # We'll install GitLab into home directory of the user "gitlab" | |
182 | - cd /home/gitlab | |
122 | + # We'll install GitLab into home directory of the user "git" | |
123 | + cd /home/git | |
183 | 124 | |
184 | 125 | ## Clone the Source |
185 | 126 | |
186 | 127 | # Clone GitLab repository |
187 | - sudo -u gitlab -H git clone https://github.com/gitlabhq/gitlabhq.git gitlab | |
128 | + sudo -u git -H git clone https://github.com/gitlabhq/gitlabhq.git gitlab | |
188 | 129 | |
189 | 130 | # Go to gitlab dir |
190 | - cd /home/gitlab/gitlab | |
131 | + cd /home/git/gitlab | |
191 | 132 | |
192 | 133 | # Checkout to stable release |
193 | - sudo -u gitlab -H git checkout 4-1-stable | |
134 | + sudo -u git -H git checkout 5-0-stable | |
194 | 135 | |
195 | 136 | **Note:** |
196 | -You can change `4-1-stable` to `master` if you want the *bleeding edge* version, but | |
137 | +You can change `5-0-stable` to `master` if you want the *bleeding edge* version, but | |
197 | 138 | do so with caution! |
198 | 139 | |
199 | 140 | ## Configure it |
200 | 141 | |
201 | - cd /home/gitlab/gitlab | |
142 | + cd /home/git/gitlab | |
202 | 143 | |
203 | 144 | # Copy the example GitLab config |
204 | - sudo -u gitlab -H cp config/gitlab.yml.example config/gitlab.yml | |
145 | + sudo -u git -H cp config/gitlab.yml.example config/gitlab.yml | |
205 | 146 | |
206 | 147 | # Make sure to change "localhost" to the fully-qualified domain name of your |
207 | 148 | # host serving GitLab where necessary |
208 | - sudo -u gitlab -H vim config/gitlab.yml | |
149 | + sudo -u git -H vim config/gitlab.yml | |
209 | 150 | |
210 | 151 | # Make sure GitLab can write to the log/ and tmp/ directories |
211 | - sudo chown -R gitlab log/ | |
212 | - sudo chown -R gitlab tmp/ | |
152 | + sudo chown -R git log/ | |
153 | + sudo chown -R git tmp/ | |
213 | 154 | sudo chmod -R u+rwX log/ |
214 | 155 | sudo chmod -R u+rwX tmp/ |
215 | 156 | |
216 | 157 | # Make directory for satellites |
217 | - sudo -u gitlab -H mkdir /home/gitlab/gitlab-satellites | |
158 | + sudo -u git -H mkdir /home/git/gitlab-satellites | |
218 | 159 | |
219 | 160 | # Copy the example Unicorn config |
220 | - sudo -u gitlab -H cp config/unicorn.rb.example config/unicorn.rb | |
161 | + sudo -u git -H cp config/unicorn.rb.example config/unicorn.rb | |
221 | 162 | |
222 | 163 | **Important Note:** |
223 | 164 | Make sure to edit both files to match your setup. |
... | ... | @@ -225,42 +166,29 @@ Make sure to edit both files to match your setup. |
225 | 166 | ## Configure GitLab DB settings |
226 | 167 | |
227 | 168 | # Mysql |
228 | - sudo -u gitlab cp config/database.yml.mysql config/database.yml | |
169 | + sudo -u git cp config/database.yml.mysql config/database.yml | |
229 | 170 | |
230 | 171 | # PostgreSQL |
231 | - sudo -u gitlab cp config/database.yml.postgresql config/database.yml | |
172 | + sudo -u git cp config/database.yml.postgresql config/database.yml | |
232 | 173 | |
233 | 174 | Make sure to update username/password in config/database.yml. |
234 | 175 | |
235 | 176 | ## Install Gems |
236 | 177 | |
237 | - cd /home/gitlab/gitlab | |
178 | + cd /home/git/gitlab | |
238 | 179 | |
239 | 180 | sudo gem install charlock_holmes --version '0.6.9' |
240 | 181 | |
241 | 182 | # For MySQL (note, the option says "without") |
242 | - sudo -u gitlab -H bundle install --deployment --without development test postgres | |
183 | + sudo -u git -H bundle install --deployment --without development test postgres | |
243 | 184 | |
244 | 185 | # Or for PostgreSQL |
245 | - sudo -u gitlab -H bundle install --deployment --without development test mysql | |
246 | - | |
247 | -## Configure Git | |
248 | - | |
249 | -GitLab needs to be able to commit and push changes to Gitolite. In order to do | |
250 | -that Git requires a username and email. (We recommend using the same address | |
251 | -used for the `email.from` setting in `config/gitlab.yml`) | |
252 | - | |
253 | - sudo -u gitlab -H git config --global user.name "GitLab" | |
254 | - sudo -u gitlab -H git config --global user.email "gitlab@localhost" | |
255 | - | |
256 | -## Setup GitLab Hooks | |
186 | + sudo -u git -H bundle install --deployment --without development test mysql | |
257 | 187 | |
258 | - sudo cp ./lib/hooks/post-receive /home/git/.gitolite/hooks/common/post-receive | |
259 | - sudo chown git:git /home/git/.gitolite/hooks/common/post-receive | |
260 | 188 | |
261 | 189 | ## Initialise Database and Activate Advanced Features |
262 | 190 | |
263 | - sudo -u gitlab -H bundle exec rake gitlab:setup RAILS_ENV=production | |
191 | + sudo -u git -H bundle exec rake gitlab:setup RAILS_ENV=production | |
264 | 192 | |
265 | 193 | |
266 | 194 | ## Install Init Script |
... | ... | @@ -279,11 +207,11 @@ Make GitLab start on boot: |
279 | 207 | |
280 | 208 | Check if GitLab and its environment is configured correctly: |
281 | 209 | |
282 | - sudo -u gitlab -H bundle exec rake gitlab:env:info RAILS_ENV=production | |
210 | + sudo -u git -H bundle exec rake gitlab:env:info RAILS_ENV=production | |
283 | 211 | |
284 | 212 | To make sure you didn't miss anything run a more thorough check with: |
285 | 213 | |
286 | - sudo -u gitlab -H bundle exec rake gitlab:check RAILS_ENV=production | |
214 | + sudo -u git -H bundle exec rake gitlab:check RAILS_ENV=production | |
287 | 215 | |
288 | 216 | If all items are green, then congratulations on successfully installing GitLab! |
289 | 217 | However there are still a few steps left. |
... | ... | @@ -356,7 +284,7 @@ a different host, you can configure its connection string via the |
356 | 284 | |
357 | 285 | If you are running SSH on a non-standard port, you must change the gitlab user'S SSH config. |
358 | 286 | |
359 | - # Add to /home/gitlab/.ssh/config | |
287 | + # Add to /home/git/.ssh/config | |
360 | 288 | host localhost # Give your setup a name (here: override localhost) |
361 | 289 | user git # Your remote git user |
362 | 290 | port 2222 # Your port number | ... | ... |
doc/install/structure.md
... | ... | @@ -3,37 +3,23 @@ |
3 | 3 | This is the directory structure you will end up with following the instructions in the Installation Guide. |
4 | 4 | |
5 | 5 | |-- home |
6 | - | |-- gitlab | |
6 | + | |-- git | |
7 | 7 | | |-- .ssh |
8 | 8 | | |-- gitlab |
9 | 9 | | |-- gitlab-satellites |
10 | - | |-- git | |
11 | - | |-- .gitolite | |
12 | - | |-- .ssh | |
13 | - | |-- bin | |
14 | - | |-- gitolite | |
10 | + | |-- gitlab-shell | |
15 | 11 | | |-- repositories |
16 | 12 | |
17 | 13 | |
18 | -**/home/gitlab/.ssh** | |
19 | - Contains the Gitolite admin key GitLab uses to configure Gitolite. | |
14 | +**/home/git/.ssh** | |
20 | 15 | |
21 | -**/home/gitlab/gitlab** | |
16 | +**/home/git/gitlab** | |
22 | 17 | This is where GitLab lives. |
23 | 18 | |
24 | -**/home/gitlab/gitlab-satellites** | |
19 | +**/home/git/gitlab-satellites** | |
25 | 20 | Contains a copy of all repositories with a working tree. |
26 | 21 | It's used for merge requests, editing files, etc. |
27 | 22 | |
28 | -**/home/git/.ssh** | |
29 | - Contains the SSH access configuration managed by Gitolite. | |
30 | - | |
31 | -**/home/git/bin** | |
32 | - Contains Gitolite executables. | |
33 | - | |
34 | -**/home/git/gitolite** | |
35 | - This is where Gitolite lives. | |
36 | - | |
37 | 23 | **/home/git/repositories** |
38 | 24 | Holds all your repositories in bare format. |
39 | 25 | This is the place Git uses when you pull/push to your projects. | ... | ... |
doc/raketasks/maintenance.md
... | ... | @@ -81,7 +81,7 @@ Config directory owned by git:git? ... yes |
81 | 81 | Config directory access is drwxr-x---? ... yes |
82 | 82 | Repo base directory exists? ... yes |
83 | 83 | Repo base owned by git:git? ... yes |
84 | -Repo base access is drwsrws---? ... yes | |
84 | +Repo base access is drwxrws---? ... yes | |
85 | 85 | Can clone gitolite-admin? ... yes |
86 | 86 | Can commit to gitolite-admin? ... yes |
87 | 87 | post-receive hook exists? ... yes | ... | ... |
features/group/group.feature
... | ... | @@ -24,3 +24,9 @@ Feature: Groups |
24 | 24 | When I visit group people page |
25 | 25 | And I select user "John" from list with role "Reporter" |
26 | 26 | Then I should see user "John" in team list |
27 | + | |
28 | + Scenario: I should see edit group page | |
29 | + When I visit group settings page | |
30 | + And I change group name | |
31 | + Then I should see new group name | |
32 | + | ... | ... |
features/steps/admin/admin_active_tab.rb
features/steps/group/group.rb
... | ... | @@ -82,6 +82,17 @@ class Groups < Spinach::FeatureSteps |
82 | 82 | current_path.should == group_path(Group.last) |
83 | 83 | end |
84 | 84 | |
85 | + And 'I change group name' do | |
86 | + fill_in 'group_name', :with => 'new-name' | |
87 | + click_button "Save group" | |
88 | + end | |
89 | + | |
90 | + Then 'I should see new group name' do | |
91 | + within ".navbar-gitlab" do | |
92 | + page.should have_content "group: new-name" | |
93 | + end | |
94 | + end | |
95 | + | |
85 | 96 | protected |
86 | 97 | |
87 | 98 | def current_group | ... | ... |
features/steps/profile/profile_active_tab.rb
... | ... | @@ -4,7 +4,7 @@ class ProfileActiveTab < Spinach::FeatureSteps |
4 | 4 | include SharedActiveTab |
5 | 5 | |
6 | 6 | Then 'the active main tab should be Home' do |
7 | - ensure_active_main_tab('Profile') | |
7 | + ensure_active_main_tab('Home') | |
8 | 8 | end |
9 | 9 | |
10 | 10 | Then 'the active main tab should be Account' do | ... | ... |
features/steps/project/project_active_tab.rb
features/steps/project/project_network_graph.rb
features/steps/project/project_team_management.rb
... | ... | @@ -24,7 +24,7 @@ class ProjectTeamManagement < Spinach::FeatureSteps |
24 | 24 | select user.name, :from => "user_ids" |
25 | 25 | select "Reporter", :from => "project_access" |
26 | 26 | end |
27 | - click_button "Save" | |
27 | + click_button "Add users" | |
28 | 28 | end |
29 | 29 | |
30 | 30 | Then 'I should see "Mike" in team list as "Reporter"' do | ... | ... |
features/steps/shared/active_tab.rb
... | ... | @@ -2,7 +2,11 @@ module SharedActiveTab |
2 | 2 | include Spinach::DSL |
3 | 3 | |
4 | 4 | def ensure_active_main_tab(content) |
5 | - page.find('ul.main_menu li.active').should have_content(content) | |
5 | + if content == "Home" | |
6 | + page.find('ul.main_menu li.active').should have_css('i.icon-home') | |
7 | + else | |
8 | + page.find('ul.main_menu li.active').should have_content(content) | |
9 | + end | |
6 | 10 | end |
7 | 11 | |
8 | 12 | def ensure_active_sub_tab(content) | ... | ... |
features/steps/shared/paths.rb
... | ... | @@ -25,6 +25,10 @@ module SharedPaths |
25 | 25 | visit people_group_path(current_group) |
26 | 26 | end |
27 | 27 | |
28 | + When 'I visit group settings page' do | |
29 | + visit edit_group_path(current_group) | |
30 | + end | |
31 | + | |
28 | 32 | # ---------------------------------------- |
29 | 33 | # Dashboard |
30 | 34 | # ---------------------------------------- |
... | ... | @@ -141,7 +145,7 @@ module SharedPaths |
141 | 145 | # Stub Graph::JsonBuilder max_size to speed up test (10 commits vs. 650) |
142 | 146 | Gitlab::Graph::JsonBuilder.stub(max_count: 10) |
143 | 147 | |
144 | - visit graph_project_path(@project) | |
148 | + visit project_graph_path(@project, root_ref) | |
145 | 149 | end |
146 | 150 | |
147 | 151 | Given "I visit my project's issues page" do | ... | ... |
features/support/env.rb
... | ... | @@ -9,17 +9,12 @@ require 'spinach/capybara' |
9 | 9 | require 'sidekiq/testing/inline' |
10 | 10 | |
11 | 11 | |
12 | -%w(gitolite_stub stubbed_repository valid_commit).each do |f| | |
12 | +%w(stubbed_repository valid_commit).each do |f| | |
13 | 13 | require Rails.root.join('spec', 'support', f) |
14 | 14 | end |
15 | 15 | |
16 | 16 | Dir["#{Rails.root}/features/steps/shared/*.rb"].each {|file| require file} |
17 | 17 | |
18 | -# | |
19 | -# Stub gitolite | |
20 | -# | |
21 | -include GitoliteStub | |
22 | - | |
23 | 18 | WebMock.allow_net_connect! |
24 | 19 | # |
25 | 20 | # JS driver |
... | ... | @@ -49,6 +44,4 @@ Spinach.hooks.before_run do |
49 | 44 | RSpec::Mocks::setup self |
50 | 45 | |
51 | 46 | include FactoryGirl::Syntax::Methods |
52 | - | |
53 | - stub_gitolite! | |
54 | 47 | end | ... | ... |
lib/api.rb
... | ... | @@ -24,7 +24,8 @@ module Gitlab |
24 | 24 | format :json |
25 | 25 | error_format :json |
26 | 26 | helpers APIHelpers |
27 | - | |
27 | + | |
28 | + mount Groups | |
28 | 29 | mount Users |
29 | 30 | mount Projects |
30 | 31 | mount Issues |
... | ... | @@ -32,5 +33,6 @@ module Gitlab |
32 | 33 | mount Session |
33 | 34 | mount MergeRequests |
34 | 35 | mount Notes |
36 | + mount Internal | |
35 | 37 | end |
36 | 38 | end | ... | ... |
lib/api/entities.rb
... | ... | @@ -2,7 +2,7 @@ module Gitlab |
2 | 2 | module Entities |
3 | 3 | class User < Grape::Entity |
4 | 4 | expose :id, :username, :email, :name, :bio, :skype, :linkedin, :twitter, |
5 | - :dark_scheme, :theme_id, :blocked, :created_at | |
5 | + :dark_scheme, :theme_id, :blocked, :created_at, :extern_uid, :provider | |
6 | 6 | end |
7 | 7 | |
8 | 8 | class UserBasic < Grape::Entity |
... | ... | @@ -21,6 +21,7 @@ module Gitlab |
21 | 21 | expose :id, :name, :description, :default_branch |
22 | 22 | expose :owner, using: Entities::UserBasic |
23 | 23 | expose :private_flag, as: :private |
24 | + expose :path, :path_with_namespace | |
24 | 25 | expose :issues_enabled, :merge_requests_enabled, :wall_enabled, :wiki_enabled, :created_at |
25 | 26 | expose :namespace |
26 | 27 | end |
... | ... | @@ -31,8 +32,22 @@ module Gitlab |
31 | 32 | end |
32 | 33 | end |
33 | 34 | |
35 | + class Group < Grape::Entity | |
36 | + expose :id, :name, :path, :owner_id | |
37 | + end | |
38 | + | |
39 | + class GroupDetail < Group | |
40 | + expose :projects, using: Entities::Project | |
41 | + end | |
42 | + | |
43 | + | |
34 | 44 | class RepoObject < Grape::Entity |
35 | 45 | expose :name, :commit |
46 | + expose :protected do |repo, options| | |
47 | + if options[:project] | |
48 | + options[:project].protected_branch? repo.name | |
49 | + end | |
50 | + end | |
36 | 51 | end |
37 | 52 | |
38 | 53 | class RepoCommit < Grape::Entity | ... | ... |
... | ... | @@ -0,0 +1,56 @@ |
1 | +module Gitlab | |
2 | + # groups API | |
3 | + class Groups < Grape::API | |
4 | + before { authenticate! } | |
5 | + | |
6 | + resource :groups do | |
7 | + # Get a groups list | |
8 | + # | |
9 | + # Example Request: | |
10 | + # GET /groups | |
11 | + get do | |
12 | + if current_user.admin | |
13 | + @groups = paginate Group | |
14 | + else | |
15 | + @groups = paginate current_user.groups | |
16 | + end | |
17 | + present @groups, with: Entities::Group | |
18 | + end | |
19 | + | |
20 | + # Create group. Available only for admin | |
21 | + # | |
22 | + # Parameters: | |
23 | + # name (required) - Name | |
24 | + # path (required) - Path | |
25 | + # Example Request: | |
26 | + # POST /groups | |
27 | + post do | |
28 | + authenticated_as_admin! | |
29 | + attrs = attributes_for_keys [:name, :path] | |
30 | + @group = Group.new(attrs) | |
31 | + @group.owner = current_user | |
32 | + | |
33 | + if @group.save | |
34 | + present @group, with: Entities::Group | |
35 | + else | |
36 | + not_found! | |
37 | + end | |
38 | + end | |
39 | + | |
40 | + # Get a single group, with containing projects | |
41 | + # | |
42 | + # Parameters: | |
43 | + # id (required) - The ID of a group | |
44 | + # Example Request: | |
45 | + # GET /groups/:id | |
46 | + get ":id" do | |
47 | + @group = Group.find(params[:id]) | |
48 | + if current_user.admin or current_user.groups.include? @group | |
49 | + present @group, with: Entities::GroupDetail | |
50 | + else | |
51 | + not_found! | |
52 | + end | |
53 | + end | |
54 | + end | |
55 | + end | |
56 | +end | ... | ... |
... | ... | @@ -0,0 +1,49 @@ |
1 | +module Gitlab | |
2 | + # Internal access API | |
3 | + class Internal < Grape::API | |
4 | + namespace 'internal' do | |
5 | + # | |
6 | + # Check if ssh key has access to project code | |
7 | + # | |
8 | + get "/allowed" do | |
9 | + key = Key.find(params[:key_id]) | |
10 | + project = Project.find_with_namespace(params[:project]) | |
11 | + git_cmd = params[:action] | |
12 | + | |
13 | + if key.is_deploy_key | |
14 | + project == key.project && git_cmd == 'git-upload-pack' | |
15 | + else | |
16 | + user = key.user | |
17 | + action = case git_cmd | |
18 | + when 'git-upload-pack' | |
19 | + then :download_code | |
20 | + when 'git-receive-pack' | |
21 | + then | |
22 | + if project.protected_branch?(params[:ref]) | |
23 | + :push_code_to_protected_branches | |
24 | + else | |
25 | + :push_code | |
26 | + end | |
27 | + end | |
28 | + | |
29 | + user.can?(action, project) | |
30 | + end | |
31 | + end | |
32 | + | |
33 | + # | |
34 | + # Discover user by ssh key | |
35 | + # | |
36 | + get "/discover" do | |
37 | + key = Key.find(params[:key_id]) | |
38 | + present key.user, with: Entities::User | |
39 | + end | |
40 | + | |
41 | + get "/check" do | |
42 | + { | |
43 | + api_version: '3' | |
44 | + } | |
45 | + end | |
46 | + end | |
47 | + end | |
48 | +end | |
49 | + | ... | ... |
lib/api/notes.rb
lib/api/projects.rb
... | ... | @@ -222,7 +222,7 @@ module Gitlab |
222 | 222 | # Example Request: |
223 | 223 | # GET /projects/:id/repository/branches |
224 | 224 | get ":id/repository/branches" do |
225 | - present user_project.repo.heads.sort_by(&:name), with: Entities::RepoObject | |
225 | + present user_project.repo.heads.sort_by(&:name), with: Entities::RepoObject, project: user_project | |
226 | 226 | end |
227 | 227 | |
228 | 228 | # Get a single branch |
... | ... | @@ -234,7 +234,43 @@ module Gitlab |
234 | 234 | # GET /projects/:id/repository/branches/:branch |
235 | 235 | get ":id/repository/branches/:branch" do |
236 | 236 | @branch = user_project.repo.heads.find { |item| item.name == params[:branch] } |
237 | - present @branch, with: Entities::RepoObject | |
237 | + present @branch, with: Entities::RepoObject, project: user_project | |
238 | + end | |
239 | + | |
240 | + # Protect a single branch | |
241 | + # | |
242 | + # Parameters: | |
243 | + # id (required) - The ID of a project | |
244 | + # branch (required) - The name of the branch | |
245 | + # Example Request: | |
246 | + # PUT /projects/:id/repository/branches/:branch/protect | |
247 | + put ":id/repository/branches/:branch/protect" do | |
248 | + @branch = user_project.repo.heads.find { |item| item.name == params[:branch] } | |
249 | + protected = user_project.protected_branches.find_by_name(@branch.name) | |
250 | + | |
251 | + unless protected | |
252 | + user_project.protected_branches.create(:name => @branch.name) | |
253 | + end | |
254 | + | |
255 | + present @branch, with: Entities::RepoObject, project: user_project | |
256 | + end | |
257 | + | |
258 | + # Unprotect a single branch | |
259 | + # | |
260 | + # Parameters: | |
261 | + # id (required) - The ID of a project | |
262 | + # branch (required) - The name of the branch | |
263 | + # Example Request: | |
264 | + # PUT /projects/:id/repository/branches/:branch/unprotect | |
265 | + put ":id/repository/branches/:branch/unprotect" do | |
266 | + @branch = user_project.repo.heads.find { |item| item.name == params[:branch] } | |
267 | + protected = user_project.protected_branches.find_by_name(@branch.name) | |
268 | + | |
269 | + if protected | |
270 | + protected.destroy | |
271 | + end | |
272 | + | |
273 | + present @branch, with: Entities::RepoObject, project: user_project | |
238 | 274 | end |
239 | 275 | |
240 | 276 | # Get a project repository tags | ... | ... |
lib/api/users.rb
... | ... | @@ -34,11 +34,14 @@ module Gitlab |
34 | 34 | # linkedin - Linkedin |
35 | 35 | # twitter - Twitter account |
36 | 36 | # projects_limit - Number of projects user can create |
37 | + # extern_uid - External authentication provider UID | |
38 | + # provider - External provider | |
39 | + # bio - Bio | |
37 | 40 | # Example Request: |
38 | 41 | # POST /users |
39 | 42 | post do |
40 | 43 | authenticated_as_admin! |
41 | - attrs = attributes_for_keys [:email, :name, :password, :skype, :linkedin, :twitter, :projects_limit, :username] | |
44 | + attrs = attributes_for_keys [:email, :name, :password, :skype, :linkedin, :twitter, :projects_limit, :username, :extern_uid, :provider, :bio] | |
42 | 45 | user = User.new attrs, as: :admin |
43 | 46 | if user.save |
44 | 47 | present user, with: Entities::User |
... | ... | @@ -46,6 +49,48 @@ module Gitlab |
46 | 49 | not_found! |
47 | 50 | end |
48 | 51 | end |
52 | + | |
53 | + # Update user. Available only for admin | |
54 | + # | |
55 | + # Parameters: | |
56 | + # email - Email | |
57 | + # name - Name | |
58 | + # password - Password | |
59 | + # skype - Skype ID | |
60 | + # linkedin - Linkedin | |
61 | + # twitter - Twitter account | |
62 | + # projects_limit - Limit projects wich user can create | |
63 | + # extern_uid - External authentication provider UID | |
64 | + # provider - External provider | |
65 | + # bio - Bio | |
66 | + # Example Request: | |
67 | + # PUT /users/:id | |
68 | + put ":id" do | |
69 | + authenticated_as_admin! | |
70 | + attrs = attributes_for_keys [:email, :name, :password, :skype, :linkedin, :twitter, :projects_limit, :username, :extern_uid, :provider, :bio] | |
71 | + user = User.find_by_id(params[:id]) | |
72 | + | |
73 | + if user && user.update_attributes(attrs) | |
74 | + present user, with: Entities::User | |
75 | + else | |
76 | + not_found! | |
77 | + end | |
78 | + end | |
79 | + | |
80 | + # Delete user. Available only for admin | |
81 | + # | |
82 | + # Example Request: | |
83 | + # DELETE /users/:id | |
84 | + delete ":id" do | |
85 | + authenticated_as_admin! | |
86 | + user = User.find_by_id(params[:id]) | |
87 | + | |
88 | + if user | |
89 | + user.destroy | |
90 | + else | |
91 | + not_found! | |
92 | + end | |
93 | + end | |
49 | 94 | end |
50 | 95 | |
51 | 96 | resource :user do | ... | ... |
lib/extracts_path.rb
... | ... | @@ -54,9 +54,10 @@ module ExtractsPath |
54 | 54 | input.gsub!(/^#{Gitlab.config.gitlab.relative_url_root}/, "") |
55 | 55 | # Remove project, actions and all other staff from path |
56 | 56 | input.gsub!(/^\/#{Regexp.escape(@project.path_with_namespace)}/, "") |
57 | - input.gsub!(/^\/(tree|commits|blame|blob|refs)\//, "") # remove actions | |
57 | + input.gsub!(/^\/(tree|commits|blame|blob|refs|graph)\//, "") # remove actions | |
58 | 58 | input.gsub!(/\?.*$/, "") # remove stamps suffix |
59 | 59 | input.gsub!(/.atom$/, "") # remove rss feed |
60 | + input.gsub!(/.json$/, "") # remove json suffix | |
60 | 61 | input.gsub!(/\/edit$/, "") # remove edit route part |
61 | 62 | |
62 | 63 | if input.match(/^([[:alnum:]]{40})(.+)/) | ... | ... |
lib/gitlab/backend/gitolite.rb
... | ... | @@ -1,90 +0,0 @@ |
1 | -require_relative 'gitolite_config' | |
2 | - | |
3 | -module Gitlab | |
4 | - class Gitolite | |
5 | - class AccessDenied < StandardError; end | |
6 | - | |
7 | - def config | |
8 | - Gitlab::GitoliteConfig.new | |
9 | - end | |
10 | - | |
11 | - # Update gitolite config with new key | |
12 | - # | |
13 | - # Ex. | |
14 | - # set_key("m_gitlab_com_12343", "sha-rsa ...", [2, 3, 6]) | |
15 | - # | |
16 | - def set_key(key_id, key_content, project_ids) | |
17 | - projects = Project.where(id: project_ids) | |
18 | - | |
19 | - config.apply do |config| | |
20 | - config.write_key(key_id, key_content) | |
21 | - config.update_projects(projects) | |
22 | - end | |
23 | - end | |
24 | - | |
25 | - # Remove ssh key from gitolite config | |
26 | - # | |
27 | - # Ex. | |
28 | - # remove_key("m_gitlab_com_12343", [2, 3, 6]) | |
29 | - # | |
30 | - def remove_key(key_id, project_ids) | |
31 | - projects = Project.where(id: project_ids) | |
32 | - | |
33 | - config.apply do |config| | |
34 | - config.rm_key(key_id) | |
35 | - config.update_projects(projects) | |
36 | - end | |
37 | - end | |
38 | - | |
39 | - # Update project config in gitolite by project id | |
40 | - # | |
41 | - # Ex. | |
42 | - # update_repository(23) | |
43 | - # | |
44 | - def update_repository(project_id) | |
45 | - project = Project.find(project_id) | |
46 | - config.update_project!(project) | |
47 | - end | |
48 | - | |
49 | - def move_repository(old_repo, project) | |
50 | - config.apply do |config| | |
51 | - config.clean_repo(old_repo) | |
52 | - config.update_project(project) | |
53 | - end | |
54 | - end | |
55 | - | |
56 | - # Remove repository from gitolite | |
57 | - # | |
58 | - # name - project path with namespace | |
59 | - # | |
60 | - # Ex. | |
61 | - # remove_repository("gitlab/gitlab-ci") | |
62 | - # | |
63 | - def remove_repository(name) | |
64 | - config.destroy_project!(name) | |
65 | - end | |
66 | - | |
67 | - # Update projects configs in gitolite by project ids | |
68 | - # | |
69 | - # Ex. | |
70 | - # update_repositories([1, 4, 6]) | |
71 | - # | |
72 | - def update_repositories(project_ids) | |
73 | - projects = Project.where(id: project_ids) | |
74 | - | |
75 | - config.apply do |config| | |
76 | - config.update_projects(projects) | |
77 | - end | |
78 | - end | |
79 | - | |
80 | - def url_to_repo path | |
81 | - Gitlab.config.gitolite.ssh_path_prefix + "#{path}.git" | |
82 | - end | |
83 | - | |
84 | - def enable_automerge | |
85 | - config.admin_all_repo! | |
86 | - end | |
87 | - | |
88 | - alias_method :create_repository, :update_repository | |
89 | - end | |
90 | -end |
lib/gitlab/backend/gitolite_config.rb
... | ... | @@ -1,241 +0,0 @@ |
1 | -require 'gitolite' | |
2 | -require 'timeout' | |
3 | -require 'fileutils' | |
4 | - | |
5 | -module Gitlab | |
6 | - class GitoliteConfig | |
7 | - include Gitlab::Popen | |
8 | - | |
9 | - class PullError < StandardError; end | |
10 | - class PushError < StandardError; end | |
11 | - class BrokenGitolite < StandardError; end | |
12 | - | |
13 | - attr_reader :config_tmp_dir, :tmp_dir, :ga_repo, :conf | |
14 | - | |
15 | - def initialize | |
16 | - @tmp_dir = Rails.root.join("tmp").to_s | |
17 | - @config_tmp_dir = File.join(@tmp_dir,"gitlabhq-gitolite-#{Time.now.to_i}") | |
18 | - end | |
19 | - | |
20 | - def ga_repo | |
21 | - @ga_repo ||= ::Gitolite::GitoliteAdmin.new( | |
22 | - File.join(config_tmp_dir,'gitolite'), | |
23 | - conf: Gitlab.config.gitolite.config_file | |
24 | - ) | |
25 | - end | |
26 | - | |
27 | - def apply | |
28 | - Timeout::timeout(30) do | |
29 | - File.open(File.join(tmp_dir, "gitlabhq-gitolite.lock"), "w+") do |f| | |
30 | - begin | |
31 | - # Set exclusive lock | |
32 | - # to prevent race condition | |
33 | - f.flock(File::LOCK_EX) | |
34 | - | |
35 | - # Pull gitolite-admin repo | |
36 | - # in tmp dir before do any changes | |
37 | - pull | |
38 | - | |
39 | - # Build ga_repo object and @conf | |
40 | - # to access gitolite-admin configuration | |
41 | - @conf = ga_repo.config | |
42 | - | |
43 | - # Do any changes | |
44 | - # in gitolite-admin | |
45 | - # config here | |
46 | - yield(self) | |
47 | - | |
48 | - # Save changes in | |
49 | - # gitolite-admin repo | |
50 | - # before push it | |
51 | - ga_repo.save | |
52 | - | |
53 | - # Push gitolite-admin repo | |
54 | - # to apply all changes | |
55 | - push | |
56 | - ensure | |
57 | - # Remove tmp dir | |
58 | - # removing the gitolite folder first is important to avoid | |
59 | - # NFS issues. | |
60 | - FileUtils.rm_rf(File.join(config_tmp_dir, 'gitolite')) | |
61 | - | |
62 | - # Remove parent tmp dir | |
63 | - FileUtils.rm_rf(config_tmp_dir) | |
64 | - | |
65 | - # Unlock so other task can access | |
66 | - # gitolite configuration | |
67 | - f.flock(File::LOCK_UN) | |
68 | - end | |
69 | - end | |
70 | - end | |
71 | - rescue PullError => ex | |
72 | - log("Pull error -> " + ex.message) | |
73 | - raise Gitolite::AccessDenied, ex.message | |
74 | - | |
75 | - rescue PushError => ex | |
76 | - log("Push error -> " + " " + ex.message) | |
77 | - raise Gitolite::AccessDenied, ex.message | |
78 | - | |
79 | - rescue BrokenGitolite => ex | |
80 | - log("Gitolite error -> " + " " + ex.message) | |
81 | - raise Gitolite::AccessDenied, ex.message | |
82 | - | |
83 | - rescue Exception => ex | |
84 | - log(ex.class.name + " " + ex.message) | |
85 | - raise Gitolite::AccessDenied.new("gitolite timeout") | |
86 | - end | |
87 | - | |
88 | - def log message | |
89 | - Gitlab::GitLogger.error(message) | |
90 | - end | |
91 | - | |
92 | - def path_to_repo(name) | |
93 | - File.join(Gitlab.config.gitolite.repos_path, "#{name}.git") | |
94 | - end | |
95 | - | |
96 | - def destroy_project(name) | |
97 | - full_path = path_to_repo(name) | |
98 | - FileUtils.rm_rf(full_path) if File.exists?(full_path) | |
99 | - conf.rm_repo(name) | |
100 | - end | |
101 | - | |
102 | - def clean_repo repo_name | |
103 | - conf.rm_repo(repo_name) | |
104 | - end | |
105 | - | |
106 | - def destroy_project!(project) | |
107 | - apply do |config| | |
108 | - config.destroy_project(project) | |
109 | - end | |
110 | - end | |
111 | - | |
112 | - def write_key(id, key) | |
113 | - File.open(File.join(config_tmp_dir, 'gitolite/keydir',"#{id}.pub"), 'w') do |f| | |
114 | - f.write(key.gsub(/\n/,'')) | |
115 | - end | |
116 | - end | |
117 | - | |
118 | - def rm_key(user) | |
119 | - key_path = File.join(config_tmp_dir, 'gitolite/keydir', "#{user}.pub") | |
120 | - ga_key = ::Gitolite::SSHKey.from_file(key_path) | |
121 | - ga_repo.rm_key(ga_key) | |
122 | - end | |
123 | - | |
124 | - # update or create | |
125 | - def update_project(project) | |
126 | - repo = update_project_config(project, conf) | |
127 | - conf.add_repo(repo, true) | |
128 | - end | |
129 | - | |
130 | - def update_project!( project) | |
131 | - apply do |config| | |
132 | - config.update_project(project) | |
133 | - end | |
134 | - end | |
135 | - | |
136 | - # Updates many projects and uses project.path_with_namespace as the repo path | |
137 | - # An order of magnitude faster than update_project | |
138 | - def update_projects(projects) | |
139 | - projects.each do |project| | |
140 | - repo = update_project_config(project, conf) | |
141 | - conf.add_repo(repo, true) | |
142 | - end | |
143 | - end | |
144 | - | |
145 | - def update_project_config(project, conf) | |
146 | - repo_name = project.path_with_namespace | |
147 | - | |
148 | - repo = if conf.has_repo?(repo_name) | |
149 | - conf.get_repo(repo_name) | |
150 | - else | |
151 | - ::Gitolite::Config::Repo.new(repo_name) | |
152 | - end | |
153 | - | |
154 | - name_readers = project.team.repository_readers | |
155 | - name_writers = project.team.repository_writers | |
156 | - name_masters = project.team.repository_masters | |
157 | - | |
158 | - pr_br = project.protected_branches.map(&:name).join("$ ") | |
159 | - | |
160 | - repo.clean_permissions | |
161 | - | |
162 | - # Deny access to protected branches for writers | |
163 | - unless name_writers.blank? || pr_br.blank? | |
164 | - repo.add_permission("-", pr_br.strip + "$ ", name_writers) | |
165 | - end | |
166 | - | |
167 | - # Add read permissions | |
168 | - repo.add_permission("R", "", name_readers) unless name_readers.blank? | |
169 | - | |
170 | - # Add write permissions | |
171 | - repo.add_permission("RW+", "", name_writers) unless name_writers.blank? | |
172 | - repo.add_permission("RW+", "", name_masters) unless name_masters.blank? | |
173 | - | |
174 | - # Add sharedRepository config | |
175 | - repo.set_git_config("core.sharedRepository", "0660") | |
176 | - | |
177 | - repo | |
178 | - end | |
179 | - | |
180 | - # Enable access to all repos for gitolite admin. | |
181 | - # We use it for accept merge request feature | |
182 | - def admin_all_repo | |
183 | - owner_name = Gitlab.config.gitolite.admin_key | |
184 | - | |
185 | - # @ALL repos premission for gitolite owner | |
186 | - repo_name = "@all" | |
187 | - repo = if conf.has_repo?(repo_name) | |
188 | - conf.get_repo(repo_name) | |
189 | - else | |
190 | - ::Gitolite::Config::Repo.new(repo_name) | |
191 | - end | |
192 | - | |
193 | - repo.add_permission("RW+", "", owner_name) | |
194 | - conf.add_repo(repo, true) | |
195 | - end | |
196 | - | |
197 | - def admin_all_repo! | |
198 | - apply { |config| config.admin_all_repo } | |
199 | - end | |
200 | - | |
201 | - private | |
202 | - | |
203 | - def pull | |
204 | - # Create config tmp dir like "RAILS_ROOT/tmp/gitlabhq-gitolite-132545" | |
205 | - Dir.mkdir config_tmp_dir | |
206 | - | |
207 | - # Clone gitolite-admin repo into tmp dir | |
208 | - popen("git clone #{Gitlab.config.gitolite.admin_uri} #{config_tmp_dir}/gitolite", tmp_dir) | |
209 | - | |
210 | - # Ensure file with config presents after cloning | |
211 | - unless File.exists?(File.join(config_tmp_dir, 'gitolite', 'conf', 'gitolite.conf')) | |
212 | - raise PullError, "unable to clone gitolite-admin repo" | |
213 | - end | |
214 | - end | |
215 | - | |
216 | - def push | |
217 | - output, status = popen('git add -A', tmp_conf_path) | |
218 | - raise "Git add failed." unless status.zero? | |
219 | - | |
220 | - # git commit returns 0 on success, and 1 if there is nothing to commit | |
221 | - output, status = popen('git commit -m "GitLab"', tmp_conf_path) | |
222 | - raise "Git add failed." unless [0,1].include?(status) | |
223 | - | |
224 | - output, status = popen('git push', tmp_conf_path) | |
225 | - | |
226 | - if output =~ /remote\: FATAL/ | |
227 | - raise BrokenGitolite, output | |
228 | - end | |
229 | - | |
230 | - if status.zero? || output =~ /Everything up\-to\-date/ | |
231 | - return true | |
232 | - else | |
233 | - raise PushError, "unable to push gitolite-admin repo" | |
234 | - end | |
235 | - end | |
236 | - | |
237 | - def tmp_conf_path | |
238 | - File.join(config_tmp_dir,'gitolite') | |
239 | - end | |
240 | - end | |
241 | -end |
... | ... | @@ -0,0 +1,50 @@ |
1 | +module Gitlab | |
2 | + class Shell | |
3 | + class AccessDenied < StandardError; end | |
4 | + | |
5 | + # Init new repository | |
6 | + # | |
7 | + # name - project path with namespace | |
8 | + # | |
9 | + # Ex. | |
10 | + # add_repository("gitlab/gitlab-ci") | |
11 | + # | |
12 | + def add_repository(name) | |
13 | + system("/home/git/gitlab-shell/bin/gitlab-projects add-project #{name}.git") | |
14 | + end | |
15 | + | |
16 | + # Remove repository from file system | |
17 | + # | |
18 | + # name - project path with namespace | |
19 | + # | |
20 | + # Ex. | |
21 | + # remove_repository("gitlab/gitlab-ci") | |
22 | + # | |
23 | + def remove_repository(name) | |
24 | + system("/home/git/gitlab-shell/bin/gitlab-projects rm-project #{name}.git") | |
25 | + end | |
26 | + | |
27 | + # Add new key to gitlab-shell | |
28 | + # | |
29 | + # Ex. | |
30 | + # add_key("key-42", "sha-rsa ...") | |
31 | + # | |
32 | + def add_key(key_id, key_content) | |
33 | + system("/home/git/gitlab-shell/bin/gitlab-keys add-key #{key_id} \"#{key_content}\"") | |
34 | + end | |
35 | + | |
36 | + # Remove ssh key from gitlab shell | |
37 | + # | |
38 | + # Ex. | |
39 | + # remove_key("key-342", "sha-rsa ...") | |
40 | + # | |
41 | + def remove_key(key_id, key_content) | |
42 | + system("/home/git/gitlab-shell/bin/gitlab-keys rm-key #{key_id} \"#{key_content}\"") | |
43 | + end | |
44 | + | |
45 | + | |
46 | + def url_to_repo path | |
47 | + Gitlab.config.gitolite.ssh_path_prefix + "#{path}.git" | |
48 | + end | |
49 | + end | |
50 | +end | ... | ... |
lib/gitlab/graph/commit.rb
... | ... | @@ -5,12 +5,13 @@ module Gitlab |
5 | 5 | class Commit |
6 | 6 | include ActionView::Helpers::TagHelper |
7 | 7 | |
8 | - attr_accessor :time, :space, :refs | |
8 | + attr_accessor :time, :space, :refs, :parent_spaces | |
9 | 9 | |
10 | 10 | def initialize(commit) |
11 | 11 | @_commit = commit |
12 | 12 | @time = -1 |
13 | 13 | @space = 0 |
14 | + @parent_spaces = [] | |
14 | 15 | end |
15 | 16 | |
16 | 17 | def method_missing(m, *args, &block) |
... | ... | @@ -28,6 +29,7 @@ module Gitlab |
28 | 29 | } |
29 | 30 | h[:time] = time |
30 | 31 | h[:space] = space |
32 | + h[:parent_spaces] = parent_spaces | |
31 | 33 | h[:refs] = refs.collect{|r|r.name}.join(" ") unless refs.nil? |
32 | 34 | h[:id] = sha |
33 | 35 | h[:date] = date | ... | ... |
lib/gitlab/graph/json_builder.rb
... | ... | @@ -9,14 +9,14 @@ module Gitlab |
9 | 9 | @max_count ||= 650 |
10 | 10 | end |
11 | 11 | |
12 | - def initialize project | |
12 | + def initialize project, ref | |
13 | 13 | @project = project |
14 | + @ref = ref | |
14 | 15 | @repo = project.repo |
15 | 16 | @ref_cache = {} |
16 | 17 | |
17 | 18 | @commits = collect_commits |
18 | 19 | @days = index_commits |
19 | - @space = 0 | |
20 | 20 | end |
21 | 21 | |
22 | 22 | def to_json(*args) |
... | ... | @@ -53,7 +53,7 @@ module Gitlab |
53 | 53 | # |
54 | 54 | # @return [Array<TimeDate>] list of commit dates corelated with time on commits |
55 | 55 | def index_commits |
56 | - days, heads = [], [] | |
56 | + days, heads, times = [], [], [] | |
57 | 57 | map = {} |
58 | 58 | |
59 | 59 | commits.reverse.each_with_index do |c,i| |
... | ... | @@ -61,14 +61,15 @@ module Gitlab |
61 | 61 | days[i] = c.committed_date |
62 | 62 | map[c.id] = c |
63 | 63 | heads += c.refs unless c.refs.nil? |
64 | + times[i] = c | |
64 | 65 | end |
65 | 66 | |
66 | 67 | heads.select!{|h| h.is_a? Grit::Head or h.is_a? Grit::Remote} |
67 | 68 | # sort heads so the master is top and current branches are closer |
68 | 69 | heads.sort! do |a,b| |
69 | - if a.name == "master" | |
70 | + if a.name == @ref | |
70 | 71 | -1 |
71 | - elsif b.name == "master" | |
72 | + elsif b.name == @ref | |
72 | 73 | 1 |
73 | 74 | else |
74 | 75 | b.commit.committed_date <=> a.commit.committed_date |
... | ... | @@ -86,9 +87,62 @@ module Gitlab |
86 | 87 | end |
87 | 88 | end |
88 | 89 | |
90 | + # find parent spaces for not overlap lines | |
91 | + times.each do |c| | |
92 | + c.parent_spaces.concat(find_free_parent_spaces(c, map, times)) | |
93 | + end | |
94 | + | |
89 | 95 | days |
90 | 96 | end |
91 | 97 | |
98 | + def find_free_parent_spaces(commit, map, times) | |
99 | + spaces = [] | |
100 | + | |
101 | + commit.parents.each do |p| | |
102 | + if map.include?(p.id) then | |
103 | + parent = map[p.id] | |
104 | + | |
105 | + range = if commit.time < parent.time then | |
106 | + commit.time..parent.time | |
107 | + else | |
108 | + parent.time..commit.time | |
109 | + end | |
110 | + | |
111 | + space = if commit.space >= parent.space then | |
112 | + find_free_parent_space(range, parent.space, 1, commit.space, times) | |
113 | + else | |
114 | + find_free_parent_space(range, parent.space, -1, parent.space, times) | |
115 | + end | |
116 | + | |
117 | + mark_reserved(range, space) | |
118 | + spaces << space | |
119 | + end | |
120 | + end | |
121 | + | |
122 | + spaces | |
123 | + end | |
124 | + | |
125 | + def find_free_parent_space(range, space_base, space_step, space_default, times) | |
126 | + if is_overlap?(range, times, space_default) then | |
127 | + find_free_space(range, space_base, space_step) | |
128 | + else | |
129 | + space_default | |
130 | + end | |
131 | + end | |
132 | + | |
133 | + def is_overlap?(range, times, overlap_space) | |
134 | + range.each do |i| | |
135 | + if i != range.first && | |
136 | + i != range.last && | |
137 | + times[i].space == overlap_space then | |
138 | + | |
139 | + return true; | |
140 | + end | |
141 | + end | |
142 | + | |
143 | + false | |
144 | + end | |
145 | + | |
92 | 146 | # Add space mark on commit and its parents |
93 | 147 | # |
94 | 148 | # @param [Graph::Commit] the commit object. |
... | ... | @@ -98,10 +152,9 @@ module Gitlab |
98 | 152 | if leaves.empty? |
99 | 153 | return |
100 | 154 | end |
101 | - @space = find_free_space(leaves, map) | |
102 | - leaves.each{|l| l.space = @space} | |
103 | 155 | # and mark it as reserved |
104 | 156 | min_time = leaves.last.time |
157 | + max_space = 1 | |
105 | 158 | parents = leaves.last.parents.collect |
106 | 159 | parents.each do |p| |
107 | 160 | if map.include? p.id |
... | ... | @@ -109,6 +162,9 @@ module Gitlab |
109 | 162 | if parent.time < min_time |
110 | 163 | min_time = parent.time |
111 | 164 | end |
165 | + if max_space < parent.space then | |
166 | + max_space = parent.space | |
167 | + end | |
112 | 168 | end |
113 | 169 | end |
114 | 170 | if parent_time.nil? |
... | ... | @@ -116,7 +172,12 @@ module Gitlab |
116 | 172 | else |
117 | 173 | max_time = parent_time - 1 |
118 | 174 | end |
119 | - mark_reserved(min_time..max_time, @space) | |
175 | + | |
176 | + time_range = leaves.last.time..leaves.first.time | |
177 | + space = find_free_space(time_range, max_space, 2) | |
178 | + leaves.each{|l| l.space = space} | |
179 | + | |
180 | + mark_reserved(min_time..max_time, space) | |
120 | 181 | |
121 | 182 | # Visit branching chains |
122 | 183 | leaves.each do |l| |
... | ... | @@ -133,30 +194,25 @@ module Gitlab |
133 | 194 | end |
134 | 195 | end |
135 | 196 | |
136 | - def find_free_space(leaves, map) | |
137 | - time_range = leaves.last.time..leaves.first.time | |
197 | + def find_free_space(time_range, space_base, space_step) | |
138 | 198 | reserved = [] |
139 | 199 | for day in time_range |
140 | 200 | reserved += @_reserved[day] |
141 | 201 | end |
142 | - space = base_space(leaves, map) | |
143 | - while (reserved.include? space) || (space == @space) do | |
144 | - space += 1 | |
202 | + reserved.uniq! | |
203 | + | |
204 | + space = space_base | |
205 | + while reserved.include?(space) do | |
206 | + space += space_step | |
207 | + if space <= 0 then | |
208 | + space_step *= -1 | |
209 | + space = space_base + space_step | |
210 | + end | |
145 | 211 | end |
146 | 212 | |
147 | 213 | space |
148 | 214 | end |
149 | 215 | |
150 | - def base_space(leaves, map) | |
151 | - parents = [] | |
152 | - leaves.each do |l| | |
153 | - parents.concat l.parents.collect.select{|p| map.include? p.id and map[p.id].space.nonzero?} | |
154 | - end | |
155 | - | |
156 | - space = parents.map{|p| map[p.id].space}.max || 0 | |
157 | - space += 1 | |
158 | - end | |
159 | - | |
160 | 216 | # Takes most left subtree branch of commits |
161 | 217 | # which don't have space mark yet. |
162 | 218 | # | ... | ... |
lib/gitlab/satellite/satellite.rb
... | ... | @@ -30,10 +30,10 @@ module Gitlab |
30 | 30 | end |
31 | 31 | |
32 | 32 | def create |
33 | - output, status = popen("git clone #{project.url_to_repo} #{path}", | |
33 | + output, status = popen("git clone #{project.repository.path_to_repo} #{path}", | |
34 | 34 | Gitlab.config.satellites.path) |
35 | 35 | |
36 | - log("PID: #{project.id}: git clone #{project.url_to_repo} #{path}") | |
36 | + log("PID: #{project.id}: git clone #{project.repository.path_to_repo} #{path}") | |
37 | 37 | log("PID: #{project.id}: -> #{output}") |
38 | 38 | |
39 | 39 | if status.zero? | ... | ... |
lib/gitolited.rb
lib/hooks/post-receive
... | ... | @@ -1,12 +0,0 @@ |
1 | -#!/usr/bin/env bash | |
2 | - | |
3 | -# Version 4.1 | |
4 | -# This file was placed here by GitLab. It makes sure that your pushed commits | |
5 | -# will be processed properly. | |
6 | - | |
7 | -while read oldrev newrev ref | |
8 | -do | |
9 | - # For every branch or tag that was pushed, create a Resque job in redis. | |
10 | - repo_path=`pwd` | |
11 | - env -i redis-cli rpush "resque:gitlab:queue:post_receive" "{\"class\":\"PostReceive\",\"args\":[\"$repo_path\",\"$oldrev\",\"$newrev\",\"$ref\",\"$GL_USER\"]}" > /dev/null 2>&1 | |
12 | -done |
lib/support/rewrite-hooks.sh
... | ... | @@ -1,32 +0,0 @@ |
1 | -#!/bin/bash | |
2 | - | |
3 | -src="/home/git/repositories" | |
4 | - | |
5 | -for dir in `ls "$src/"` | |
6 | -do | |
7 | - if [ -d "$src/$dir" ]; then | |
8 | - | |
9 | - if [ "$dir" = "gitolite-admin.git" ] | |
10 | - then | |
11 | - continue | |
12 | - fi | |
13 | - | |
14 | - if [[ "$dir" =~ ^.*.git$ ]] | |
15 | - then | |
16 | - project_hook="$src/$dir/hooks/post-receive" | |
17 | - gitolite_hook="/home/git/.gitolite/hooks/common/post-receive" | |
18 | - | |
19 | - ln -s -f $gitolite_hook $project_hook | |
20 | - else | |
21 | - for subdir in `ls "$src/$dir/"` | |
22 | - do | |
23 | - if [ -d "$src/$dir/$subdir" ] && [[ "$subdir" =~ ^.*.git$ ]]; then | |
24 | - project_hook="$src/$dir/$subdir/hooks/post-receive" | |
25 | - gitolite_hook="/home/git/.gitolite/hooks/common/post-receive" | |
26 | - | |
27 | - ln -s -f $gitolite_hook $project_hook | |
28 | - fi | |
29 | - done | |
30 | - fi | |
31 | - fi | |
32 | -done |
lib/support/truncate_repositories.sh
... | ... | @@ -1,11 +0,0 @@ |
1 | -#!/bin/bash | |
2 | - | |
3 | -echo "Danger!!! Data Loss" | |
4 | -while true; do | |
5 | - read -p "Do you wish to all directories except gitolite-admin.git from /home/git/repositories/ (y/n) ?: " yn | |
6 | - case $yn in | |
7 | - [Yy]* ) sh -c "find /home/git/repositories/. -maxdepth 1 -not -name 'gitolite-admin.git' -not -name '.' | xargs sudo rm -rf"; break;; | |
8 | - [Nn]* ) exit;; | |
9 | - * ) echo "Please answer yes or no.";; | |
10 | - esac | |
11 | -done |
lib/tasks/gitlab/check.rake
... | ... | @@ -716,7 +716,7 @@ namespace :gitlab do |
716 | 716 | end |
717 | 717 | |
718 | 718 | def check_repo_base_permissions |
719 | - print "Repo base access is drwsrws---? ... " | |
719 | + print "Repo base access is drwxrws---? ... " | |
720 | 720 | |
721 | 721 | repo_base_path = Gitlab.config.gitolite.repos_path |
722 | 722 | unless File.exists?(repo_base_path) |
... | ... | @@ -724,12 +724,14 @@ namespace :gitlab do |
724 | 724 | return |
725 | 725 | end |
726 | 726 | |
727 | - if File.stat(repo_base_path).mode.to_s(8).ends_with?("6770") | |
727 | + if File.stat(repo_base_path).mode.to_s(8).ends_with?("2770") | |
728 | 728 | puts "yes".green |
729 | 729 | else |
730 | 730 | puts "no".red |
731 | 731 | try_fixing_it( |
732 | - "sudo chmod -R ug+rwXs,o-rwx #{repo_base_path}" | |
732 | + "sudo chmod -R ug+rwX,o-rwx #{repo_base_path}", | |
733 | + "sudo chmod -R ug-s #{repo_base_path}", | |
734 | + "find #{repo_base_path} -type d -print0 | sudo xargs -0 chmod g+s" | |
733 | 735 | ) |
734 | 736 | for_more_information( |
735 | 737 | see_installation_guide_section "Gitolite" |
... | ... | @@ -780,21 +782,25 @@ namespace :gitlab do |
780 | 782 | Project.find_each(batch_size: 100) do |project| |
781 | 783 | print "#{project.name_with_namespace.yellow} ... " |
782 | 784 | |
783 | - correct_options = options.map do |name, value| | |
784 | - run("git --git-dir=\"#{project.repository.path_to_repo}\" config --get #{name}").try(:chomp) == value | |
785 | - end | |
786 | - | |
787 | - if correct_options.all? | |
788 | - puts "ok".green | |
785 | + if project.empty_repo? | |
786 | + puts "repository is empty".magenta | |
789 | 787 | else |
790 | - puts "wrong or missing".red | |
791 | - try_fixing_it( | |
792 | - sudo_gitlab("bundle exec rake gitlab:gitolite:update_repos RAILS_ENV=production") | |
793 | - ) | |
794 | - for_more_information( | |
795 | - "doc/raketasks/maintenance.md" | |
796 | - ) | |
797 | - fix_and_rerun | |
788 | + correct_options = options.map do |name, value| | |
789 | + run("git --git-dir=\"#{project.repository.path_to_repo}\" config --get #{name}").try(:chomp) == value | |
790 | + end | |
791 | + | |
792 | + if correct_options.all? | |
793 | + puts "ok".green | |
794 | + else | |
795 | + puts "wrong or missing".red | |
796 | + try_fixing_it( | |
797 | + sudo_gitlab("bundle exec rake gitlab:gitolite:update_repos RAILS_ENV=production") | |
798 | + ) | |
799 | + for_more_information( | |
800 | + "doc/raketasks/maintenance.md" | |
801 | + ) | |
802 | + fix_and_rerun | |
803 | + end | |
798 | 804 | end |
799 | 805 | end |
800 | 806 | end |
... | ... | @@ -820,32 +826,37 @@ namespace :gitlab do |
820 | 826 | |
821 | 827 | Project.find_each(batch_size: 100) do |project| |
822 | 828 | print "#{project.name_with_namespace.yellow} ... " |
823 | - project_hook_file = File.join(project.repository.path_to_repo, "hooks", hook_file) | |
824 | 829 | |
825 | - unless File.exists?(project_hook_file) | |
826 | - puts "missing".red | |
827 | - try_fixing_it( | |
828 | - "sudo -u #{gitolite_ssh_user} ln -sf #{gitolite_hook_file} #{project_hook_file}" | |
829 | - ) | |
830 | - for_more_information( | |
831 | - "lib/support/rewrite-hooks.sh" | |
832 | - ) | |
833 | - fix_and_rerun | |
834 | - next | |
835 | - end | |
836 | - | |
837 | - if File.lstat(project_hook_file).symlink? && | |
838 | - File.realpath(project_hook_file) == File.realpath(gitolite_hook_file) | |
839 | - puts "ok".green | |
830 | + if project.empty_repo? | |
831 | + puts "repository is empty".magenta | |
840 | 832 | else |
841 | - puts "not a link to Gitolite's hook".red | |
842 | - try_fixing_it( | |
843 | - "sudo -u #{gitolite_ssh_user} ln -sf #{gitolite_hook_file} #{project_hook_file}" | |
844 | - ) | |
845 | - for_more_information( | |
846 | - "lib/support/rewrite-hooks.sh" | |
847 | - ) | |
848 | - fix_and_rerun | |
833 | + project_hook_file = File.join(project.repository.path_to_repo, "hooks", hook_file) | |
834 | + | |
835 | + unless File.exists?(project_hook_file) | |
836 | + puts "missing".red | |
837 | + try_fixing_it( | |
838 | + "sudo -u #{gitolite_ssh_user} ln -sf #{gitolite_hook_file} #{project_hook_file}" | |
839 | + ) | |
840 | + for_more_information( | |
841 | + "lib/support/rewrite-hooks.sh" | |
842 | + ) | |
843 | + fix_and_rerun | |
844 | + next | |
845 | + end | |
846 | + | |
847 | + if File.lstat(project_hook_file).symlink? && | |
848 | + File.realpath(project_hook_file) == File.realpath(gitolite_hook_file) | |
849 | + puts "ok".green | |
850 | + else | |
851 | + puts "not a link to Gitolite's hook".red | |
852 | + try_fixing_it( | |
853 | + "sudo -u #{gitolite_ssh_user} ln -sf #{gitolite_hook_file} #{project_hook_file}" | |
854 | + ) | |
855 | + for_more_information( | |
856 | + "lib/support/rewrite-hooks.sh" | |
857 | + ) | |
858 | + fix_and_rerun | |
859 | + end | |
849 | 860 | end |
850 | 861 | end |
851 | 862 | end | ... | ... |
lib/tasks/gitlab/enable_automerge.rake
... | ... | @@ -3,11 +3,6 @@ namespace :gitlab do |
3 | 3 | task :enable_automerge => :environment do |
4 | 4 | warn_user_is_not_gitlab |
5 | 5 | |
6 | - puts "Updating repo permissions ..." | |
7 | - Gitlab::Gitolite.new.enable_automerge | |
8 | - puts "... #{"done".green}" | |
9 | - puts "" | |
10 | - | |
11 | 6 | print "Creating satellites for ..." |
12 | 7 | unless Project.count > 0 |
13 | 8 | puts "skipping, because you have no projects".magenta | ... | ... |
... | ... | @@ -0,0 +1,32 @@ |
1 | +namespace :gitlab do | |
2 | + namespace :shell do | |
3 | + desc "GITLAB | Setup gitlab-shell" | |
4 | + task :setup => :environment do | |
5 | + setup | |
6 | + end | |
7 | + end | |
8 | + | |
9 | + def setup | |
10 | + warn_user_is_not_gitlab | |
11 | + | |
12 | + puts "This will rebuild an authorized_keys file." | |
13 | + puts "You will lose any data stored in /home/git/.ssh/authorized_keys." | |
14 | + ask_to_continue | |
15 | + puts "" | |
16 | + | |
17 | + system("echo '# Managed by gitlab-shell' > /home/git/.ssh/authorized_keys") | |
18 | + | |
19 | + Key.find_each(:batch_size => 1000) do |key| | |
20 | + if Gitlab::Shell.new.add_key(key.shell_id, key.key) | |
21 | + print '.' | |
22 | + else | |
23 | + print 'F' | |
24 | + end | |
25 | + end | |
26 | + | |
27 | + rescue Gitlab::TaskAbortedByUserError | |
28 | + puts "Quitting...".red | |
29 | + exit 1 | |
30 | + end | |
31 | +end | |
32 | + | ... | ... |
spec/factories/user_team_project_relationships.rb
1 | +# == Schema Information | |
2 | +# | |
3 | +# Table name: user_team_project_relationships | |
4 | +# | |
5 | +# id :integer not null, primary key | |
6 | +# project_id :integer | |
7 | +# user_team_id :integer | |
8 | +# greatest_access :integer | |
9 | +# created_at :datetime not null | |
10 | +# updated_at :datetime not null | |
11 | +# | |
12 | + | |
1 | 13 | # Read about factories at https://github.com/thoughtbot/factory_girl |
2 | 14 | |
3 | 15 | FactoryGirl.define do | ... | ... |
spec/factories/user_team_user_relationships.rb
1 | +# == Schema Information | |
2 | +# | |
3 | +# Table name: user_team_user_relationships | |
4 | +# | |
5 | +# id :integer not null, primary key | |
6 | +# user_id :integer | |
7 | +# user_team_id :integer | |
8 | +# group_admin :boolean | |
9 | +# permission :integer | |
10 | +# created_at :datetime not null | |
11 | +# updated_at :datetime not null | |
12 | +# | |
13 | + | |
1 | 14 | # Read about factories at https://github.com/thoughtbot/factory_girl |
2 | 15 | |
3 | 16 | FactoryGirl.define do | ... | ... |
spec/factories/user_teams.rb
1 | +# == Schema Information | |
2 | +# | |
3 | +# Table name: user_teams | |
4 | +# | |
5 | +# id :integer not null, primary key | |
6 | +# name :string(255) | |
7 | +# path :string(255) | |
8 | +# owner_id :integer | |
9 | +# created_at :datetime not null | |
10 | +# updated_at :datetime not null | |
11 | +# | |
12 | + | |
1 | 13 | # Read about factories at https://github.com/thoughtbot/factory_girl |
2 | 14 | |
3 | 15 | FactoryGirl.define do | ... | ... |
spec/lib/gitolite_config_spec.rb
... | ... | @@ -1,16 +0,0 @@ |
1 | -require 'spec_helper' | |
2 | - | |
3 | -describe Gitlab::GitoliteConfig do | |
4 | - let(:gitolite) { Gitlab::GitoliteConfig.new } | |
5 | - | |
6 | - it { should respond_to :write_key } | |
7 | - it { should respond_to :rm_key } | |
8 | - it { should respond_to :update_project } | |
9 | - it { should respond_to :update_project! } | |
10 | - it { should respond_to :update_projects } | |
11 | - it { should respond_to :destroy_project } | |
12 | - it { should respond_to :destroy_project! } | |
13 | - it { should respond_to :apply } | |
14 | - it { should respond_to :admin_all_repo } | |
15 | - it { should respond_to :admin_all_repo! } | |
16 | -end |
spec/lib/gitolite_spec.rb
... | ... | @@ -1,26 +0,0 @@ |
1 | -require 'spec_helper' | |
2 | - | |
3 | -describe Gitlab::Gitolite do | |
4 | - let(:project) { double('Project', id: 7, path: 'diaspora') } | |
5 | - let(:gitolite_config) { double('Gitlab::GitoliteConfig') } | |
6 | - let(:gitolite) { Gitlab::Gitolite.new } | |
7 | - | |
8 | - before do | |
9 | - gitolite.stub(config: gitolite_config) | |
10 | - Project.stub(find: project) | |
11 | - end | |
12 | - | |
13 | - it { should respond_to :set_key } | |
14 | - it { should respond_to :remove_key } | |
15 | - | |
16 | - it { should respond_to :update_repository } | |
17 | - it { should respond_to :create_repository } | |
18 | - it { should respond_to :remove_repository } | |
19 | - | |
20 | - it { gitolite.url_to_repo('diaspora').should == Gitlab.config.gitolite.ssh_path_prefix + "diaspora.git" } | |
21 | - | |
22 | - it "should call config update" do | |
23 | - gitolite_config.should_receive(:update_project!) | |
24 | - gitolite.update_repository(project.id) | |
25 | - end | |
26 | -end |
... | ... | @@ -0,0 +1,17 @@ |
1 | +require 'spec_helper' | |
2 | + | |
3 | +describe Gitlab::Shell do | |
4 | + let(:project) { double('Project', id: 7, path: 'diaspora') } | |
5 | + let(:gitolite) { Gitlab::Shell.new } | |
6 | + | |
7 | + before do | |
8 | + Project.stub(find: project) | |
9 | + end | |
10 | + | |
11 | + it { should respond_to :add_key } | |
12 | + it { should respond_to :remove_key } | |
13 | + it { should respond_to :add_repository } | |
14 | + it { should respond_to :remove_repository } | |
15 | + | |
16 | + it { gitolite.url_to_repo('diaspora').should == Gitlab.config.gitolite.ssh_path_prefix + "diaspora.git" } | |
17 | +end | ... | ... |
spec/mailers/notify_spec.rb
... | ... | @@ -266,7 +266,7 @@ describe Notify do |
266 | 266 | |
267 | 267 | before(:each) { note.stub(:noteable).and_return(commit) } |
268 | 268 | |
269 | - subject { Notify.note_commit_email(recipient.email, note.id) } | |
269 | + subject { Notify.note_commit_email(recipient.id, note.id) } | |
270 | 270 | |
271 | 271 | it_behaves_like 'a note email' |
272 | 272 | ... | ... |
spec/models/key_spec.rb
... | ... | @@ -46,9 +46,9 @@ describe Key do |
46 | 46 | key.should_not be_valid |
47 | 47 | end |
48 | 48 | |
49 | - it "does accept the same key for another project" do | |
49 | + it "does not accept the same key for another project" do | |
50 | 50 | key = build(:key, project_id: 0) |
51 | - key.should be_valid | |
51 | + key.should_not be_valid | |
52 | 52 | end |
53 | 53 | end |
54 | 54 | ... | ... |
spec/models/project_spec.rb
... | ... | @@ -8,7 +8,6 @@ |
8 | 8 | # description :text |
9 | 9 | # created_at :datetime not null |
10 | 10 | # updated_at :datetime not null |
11 | -# private_flag :boolean default(TRUE), not null | |
12 | 11 | # creator_id :integer |
13 | 12 | # default_branch :string(255) |
14 | 13 | # issues_enabled :boolean default(TRUE), not null |
... | ... | @@ -16,6 +15,7 @@ |
16 | 15 | # merge_requests_enabled :boolean default(TRUE), not null |
17 | 16 | # wiki_enabled :boolean default(TRUE), not null |
18 | 17 | # namespace_id :integer |
18 | +# public :boolean default(FALSE), not null | |
19 | 19 | # |
20 | 20 | |
21 | 21 | require 'spec_helper' |
... | ... | @@ -42,7 +42,6 @@ describe Project do |
42 | 42 | describe "Mass assignment" do |
43 | 43 | it { should_not allow_mass_assignment_of(:namespace_id) } |
44 | 44 | it { should_not allow_mass_assignment_of(:creator_id) } |
45 | - it { should_not allow_mass_assignment_of(:private_flag) } | |
46 | 45 | end |
47 | 46 | |
48 | 47 | describe "Validation" do |
... | ... | @@ -78,8 +77,6 @@ describe Project do |
78 | 77 | it { should respond_to(:url_to_repo) } |
79 | 78 | it { should respond_to(:repo_exists?) } |
80 | 79 | it { should respond_to(:satellite) } |
81 | - it { should respond_to(:update_repository) } | |
82 | - it { should respond_to(:destroy_repository) } | |
83 | 80 | it { should respond_to(:observe_push) } |
84 | 81 | it { should respond_to(:update_merge_requests) } |
85 | 82 | it { should respond_to(:execute_hooks) } | ... | ... |
spec/models/protected_branch_spec.rb
... | ... | @@ -24,19 +24,4 @@ describe ProtectedBranch do |
24 | 24 | it { should validate_presence_of(:project) } |
25 | 25 | it { should validate_presence_of(:name) } |
26 | 26 | end |
27 | - | |
28 | - describe 'Callbacks' do | |
29 | - let(:branch) { build(:protected_branch) } | |
30 | - | |
31 | - it 'call update_repository after save' do | |
32 | - branch.should_receive(:update_repository) | |
33 | - branch.save | |
34 | - end | |
35 | - | |
36 | - it 'call update_repository after destroy' do | |
37 | - branch.save | |
38 | - branch.should_receive(:update_repository) | |
39 | - branch.destroy | |
40 | - end | |
41 | - end | |
42 | 27 | end | ... | ... |
spec/models/user_spec.rb
spec/models/user_team_project_relationship_spec.rb
1 | +# == Schema Information | |
2 | +# | |
3 | +# Table name: user_team_project_relationships | |
4 | +# | |
5 | +# id :integer not null, primary key | |
6 | +# project_id :integer | |
7 | +# user_team_id :integer | |
8 | +# greatest_access :integer | |
9 | +# created_at :datetime not null | |
10 | +# updated_at :datetime not null | |
11 | +# | |
12 | + | |
1 | 13 | require 'spec_helper' |
2 | 14 | |
3 | 15 | describe UserTeamProjectRelationship do | ... | ... |
spec/models/user_team_spec.rb
1 | +# == Schema Information | |
2 | +# | |
3 | +# Table name: user_teams | |
4 | +# | |
5 | +# id :integer not null, primary key | |
6 | +# name :string(255) | |
7 | +# path :string(255) | |
8 | +# owner_id :integer | |
9 | +# created_at :datetime not null | |
10 | +# updated_at :datetime not null | |
11 | +# | |
12 | + | |
1 | 13 | require 'spec_helper' |
2 | 14 | |
3 | 15 | describe UserTeam do | ... | ... |
spec/models/user_team_user_relationship_spec.rb
1 | +# == Schema Information | |
2 | +# | |
3 | +# Table name: user_team_user_relationships | |
4 | +# | |
5 | +# id :integer not null, primary key | |
6 | +# user_id :integer | |
7 | +# user_team_id :integer | |
8 | +# group_admin :boolean | |
9 | +# permission :integer | |
10 | +# created_at :datetime not null | |
11 | +# updated_at :datetime not null | |
12 | +# | |
13 | + | |
1 | 14 | require 'spec_helper' |
2 | 15 | |
3 | 16 | describe UserTeamUserRelationship do | ... | ... |
spec/observers/key_observer_spec.rb
... | ... | @@ -3,7 +3,7 @@ require 'spec_helper' |
3 | 3 | describe KeyObserver do |
4 | 4 | before do |
5 | 5 | @key = double('Key', |
6 | - identifier: 'admin_654654', | |
6 | + shell_id: 'key-32', | |
7 | 7 | key: '== a vaild ssh key', |
8 | 8 | projects: [], |
9 | 9 | is_deploy_key: false |
... | ... | @@ -14,14 +14,14 @@ describe KeyObserver do |
14 | 14 | |
15 | 15 | context :after_save do |
16 | 16 | it do |
17 | - GitoliteWorker.should_receive(:perform_async).with(:set_key, @key.identifier, @key.key, @key.projects.map(&:id)) | |
17 | + GitoliteWorker.should_receive(:perform_async).with(:add_key, @key.shell_id, @key.key) | |
18 | 18 | @observer.after_save(@key) |
19 | 19 | end |
20 | 20 | end |
21 | 21 | |
22 | 22 | context :after_destroy do |
23 | 23 | it do |
24 | - GitoliteWorker.should_receive(:perform_async).with(:remove_key, @key.identifier, @key.projects.map(&:id)) | |
24 | + GitoliteWorker.should_receive(:perform_async).with(:remove_key, @key.shell_id, @key.key) | |
25 | 25 | @observer.after_destroy(@key) |
26 | 26 | end |
27 | 27 | end | ... | ... |
... | ... | @@ -0,0 +1,93 @@ |
1 | +require 'spec_helper' | |
2 | + | |
3 | +describe Gitlab::API do | |
4 | + include ApiHelpers | |
5 | + | |
6 | + let(:user1) { create(:user) } | |
7 | + let(:user2) { create(:user) } | |
8 | + let(:admin) { create(:admin) } | |
9 | + let!(:group1) { create(:group, owner: user1) } | |
10 | + let!(:group2) { create(:group, owner: user2) } | |
11 | + | |
12 | + describe "GET /groups" do | |
13 | + context "when unauthenticated" do | |
14 | + it "should return authentication error" do | |
15 | + get api("/groups") | |
16 | + response.status.should == 401 | |
17 | + end | |
18 | + end | |
19 | + | |
20 | + context "when authenticated as user" do | |
21 | + it "normal user: should return an array of groups of user1" do | |
22 | + get api("/groups", user1) | |
23 | + response.status.should == 200 | |
24 | + json_response.should be_an Array | |
25 | + json_response.length.should == 1 | |
26 | + json_response.first['name'].should == group1.name | |
27 | + end | |
28 | + end | |
29 | + | |
30 | + context "when authenticated as admin" do | |
31 | + it "admin: should return an array of all groups" do | |
32 | + get api("/groups", admin) | |
33 | + response.status.should == 200 | |
34 | + json_response.should be_an Array | |
35 | + json_response.length.should == 2 | |
36 | + end | |
37 | + end | |
38 | + end | |
39 | + | |
40 | + describe "GET /groups/:id" do | |
41 | + context "when authenticated as user" do | |
42 | + it "should return one of user1's groups" do | |
43 | + get api("/groups/#{group1.id}", user1) | |
44 | + response.status.should == 200 | |
45 | + json_response['name'] == group1.name | |
46 | + end | |
47 | + | |
48 | + it "should not return a non existing group" do | |
49 | + get api("/groups/1328", user1) | |
50 | + response.status.should == 404 | |
51 | + end | |
52 | + | |
53 | + it "should not return a group not attached to user1" do | |
54 | + get api("/groups/#{group2.id}", user1) | |
55 | + response.status.should == 404 | |
56 | + end | |
57 | + end | |
58 | + | |
59 | + context "when authenticated as admin" do | |
60 | + it "should return any existing group" do | |
61 | + get api("/groups/#{group2.id}", admin) | |
62 | + response.status.should == 200 | |
63 | + json_response['name'] == group2.name | |
64 | + end | |
65 | + | |
66 | + it "should not return a non existing group" do | |
67 | + get api("/groups/1328", admin) | |
68 | + response.status.should == 404 | |
69 | + end | |
70 | + end | |
71 | + end | |
72 | + | |
73 | + describe "POST /groups" do | |
74 | + context "when authenticated as user" do | |
75 | + it "should not create group" do | |
76 | + post api("/groups", user1), attributes_for(:group) | |
77 | + response.status.should == 403 | |
78 | + end | |
79 | + end | |
80 | + | |
81 | + context "when authenticated as admin" do | |
82 | + it "should create group" do | |
83 | + post api("/groups", admin), attributes_for(:group) | |
84 | + response.status.should == 201 | |
85 | + end | |
86 | + | |
87 | + it "should not create group, duplicate" do | |
88 | + post api("/groups", admin), {:name => "Duplicate Test", :path => group2.path} | |
89 | + response.status.should == 404 | |
90 | + end | |
91 | + end | |
92 | + end | |
93 | +end | ... | ... |
spec/requests/api/notes_spec.rb
... | ... | @@ -6,8 +6,10 @@ describe Gitlab::API do |
6 | 6 | let(:user) { create(:user) } |
7 | 7 | let!(:project) { create(:project, namespace: user.namespace ) } |
8 | 8 | let!(:issue) { create(:issue, project: project, author: user) } |
9 | + let!(:merge_request) { create(:merge_request, project: project, author: user) } | |
9 | 10 | let!(:snippet) { create(:snippet, project: project, author: user) } |
10 | 11 | let!(:issue_note) { create(:note, noteable: issue, project: project, author: user) } |
12 | + let!(:merge_request_note) { create(:note, noteable: merge_request, project: project, author: user) } | |
11 | 13 | let!(:snippet_note) { create(:note, noteable: snippet, project: project, author: user) } |
12 | 14 | let!(:wall_note) { create(:note, project: project, author: user) } |
13 | 15 | before { project.team << [user, :reporter] } |
... | ... | @@ -84,6 +86,15 @@ describe Gitlab::API do |
84 | 86 | response.status.should == 404 |
85 | 87 | end |
86 | 88 | end |
89 | + | |
90 | + context "when noteable is a Merge Request" do | |
91 | + it "should return an array of merge_requests notes" do | |
92 | + get api("/projects/#{project.id}/merge_requests/#{merge_request.id}/notes", user) | |
93 | + response.status.should == 200 | |
94 | + json_response.should be_an Array | |
95 | + json_response.first['body'].should == merge_request_note.note | |
96 | + end | |
97 | + end | |
87 | 98 | end |
88 | 99 | |
89 | 100 | describe "GET /projects/:id/noteable/:noteable_id/notes/:note_id" do | ... | ... |
spec/requests/api/projects_spec.rb
... | ... | @@ -113,6 +113,29 @@ describe Gitlab::API do |
113 | 113 | |
114 | 114 | json_response['name'].should == 'new_design' |
115 | 115 | json_response['commit']['id'].should == '621491c677087aa243f165eab467bfdfbee00be1' |
116 | + json_response['protected'].should == false | |
117 | + end | |
118 | + end | |
119 | + | |
120 | + describe "PUT /projects/:id/repository/branches/:branch/protect" do | |
121 | + it "should protect a single branch" do | |
122 | + put api("/projects/#{project.id}/repository/branches/new_design/protect", user) | |
123 | + response.status.should == 200 | |
124 | + | |
125 | + json_response['name'].should == 'new_design' | |
126 | + json_response['commit']['id'].should == '621491c677087aa243f165eab467bfdfbee00be1' | |
127 | + json_response['protected'].should == true | |
128 | + end | |
129 | + end | |
130 | + | |
131 | + describe "PUT /projects/:id/repository/branches/:branch/unprotect" do | |
132 | + it "should unprotect a single branch" do | |
133 | + put api("/projects/#{project.id}/repository/branches/new_design/unprotect", user) | |
134 | + response.status.should == 200 | |
135 | + | |
136 | + json_response['name'].should == 'new_design' | |
137 | + json_response['commit']['id'].should == '621491c677087aa243f165eab467bfdfbee00be1' | |
138 | + json_response['protected'].should == false | |
116 | 139 | end |
117 | 140 | end |
118 | 141 | ... | ... |
spec/requests/api/users_spec.rb
... | ... | @@ -83,6 +83,54 @@ describe Gitlab::API do |
83 | 83 | end |
84 | 84 | end |
85 | 85 | |
86 | + describe "PUT /users/:id" do | |
87 | + before { admin } | |
88 | + | |
89 | + it "should update user" do | |
90 | + put api("/users/#{user.id}", admin), {bio: 'new test bio'} | |
91 | + response.status.should == 200 | |
92 | + json_response['bio'].should == 'new test bio' | |
93 | + user.reload.bio.should == 'new test bio' | |
94 | + end | |
95 | + | |
96 | + it "should not allow invalid update" do | |
97 | + put api("/users/#{user.id}", admin), {email: 'invalid email'} | |
98 | + response.status.should == 404 | |
99 | + user.reload.email.should_not == 'invalid email' | |
100 | + end | |
101 | + | |
102 | + it "shouldn't available for non admin users" do | |
103 | + put api("/users/#{user.id}", user), attributes_for(:user) | |
104 | + response.status.should == 403 | |
105 | + end | |
106 | + | |
107 | + it "should return 404 for non-existing user" do | |
108 | + put api("/users/999999", admin), {bio: 'update should fail'} | |
109 | + response.status.should == 404 | |
110 | + end | |
111 | + end | |
112 | + | |
113 | + describe "DELETE /users/:id" do | |
114 | + before { admin } | |
115 | + | |
116 | + it "should delete user" do | |
117 | + delete api("/users/#{user.id}", admin) | |
118 | + response.status.should == 200 | |
119 | + expect { User.find(user.id) }.to raise_error ActiveRecord::RecordNotFound | |
120 | + json_response['email'].should == user.email | |
121 | + end | |
122 | + | |
123 | + it "shouldn't available for non admin users" do | |
124 | + delete api("/users/#{user.id}", user) | |
125 | + response.status.should == 403 | |
126 | + end | |
127 | + | |
128 | + it "should return 404 for non-existing user" do | |
129 | + delete api("/users/999999", admin) | |
130 | + response.status.should == 404 | |
131 | + end | |
132 | + end | |
133 | + | |
86 | 134 | describe "GET /user" do |
87 | 135 | it "should return current user" do |
88 | 136 | get api("/user", user) | ... | ... |
spec/requests/notes_on_merge_requests_spec.rb
... | ... | @@ -22,9 +22,9 @@ describe "On a merge request", js: true do |
22 | 22 | it { within(".js-main-target-form") { should_not have_link("Cancel") } } |
23 | 23 | |
24 | 24 | # notifiactions |
25 | - it { within(".js-main-target-form") { should have_checked_field("Project team") } } | |
26 | - it { within(".js-main-target-form") { should_not have_checked_field("Commit author") } } | |
27 | - it { within(".js-main-target-form") { should_not have_unchecked_field("Commit author") } } | |
25 | + it { within(".js-main-target-form") { should have_checked_field("Notify team via email") } } | |
26 | + it { within(".js-main-target-form") { should_not have_checked_field("Notify commit author") } } | |
27 | + it { within(".js-main-target-form") { should_not have_unchecked_field("Notify commit author") } } | |
28 | 28 | |
29 | 29 | describe "without text" do |
30 | 30 | it { within(".js-main-target-form") { should have_css(".js-note-preview-button", visible: false) } } |
... | ... | @@ -125,7 +125,7 @@ describe "On a merge request diff", js: true, focus: true do |
125 | 125 | it { should have_css(".js-close-discussion-note-form", text: "Cancel") } |
126 | 126 | |
127 | 127 | # notification options |
128 | - it { should have_checked_field("Project team") } | |
128 | + it { should have_checked_field("Notify team via email") } | |
129 | 129 | |
130 | 130 | it "shouldn't add a second form for same row" do |
131 | 131 | find("#4735dfc552ad7bf15ca468adc3cad9d05b624490_185_185.line_holder .js-add-diff-note-button").trigger("click") | ... | ... |
spec/requests/notes_on_wall_spec.rb
... | ... | @@ -21,9 +21,9 @@ describe "On the project wall", js: true do |
21 | 21 | it { within(".js-main-target-form") { should_not have_link("Cancel") } } |
22 | 22 | |
23 | 23 | # notifiactions |
24 | - it { within(".js-main-target-form") { should have_checked_field("Project team") } } | |
25 | - it { within(".js-main-target-form") { should_not have_checked_field("Commit author") } } | |
26 | - it { within(".js-main-target-form") { should_not have_unchecked_field("Commit author") } } | |
24 | + it { within(".js-main-target-form") { should have_checked_field("Notify team via email") } } | |
25 | + it { within(".js-main-target-form") { should_not have_checked_field("Notify commit author") } } | |
26 | + it { within(".js-main-target-form") { should_not have_unchecked_field("Notify commit author") } } | |
27 | 27 | |
28 | 28 | describe "without text" do |
29 | 29 | it { within(".js-main-target-form") { should have_css(".js-note-preview-button", visible: false) } } | ... | ... |
spec/routing/project_routing_spec.rb
... | ... | @@ -76,7 +76,7 @@ describe ProjectsController, "routing" do |
76 | 76 | end |
77 | 77 | |
78 | 78 | it "to #graph" do |
79 | - get("/gitlabhq/graph").should route_to('projects#graph', id: 'gitlabhq') | |
79 | + get("/gitlabhq/graph/master").should route_to('graph#show', project_id: 'gitlabhq', id: 'master') | |
80 | 80 | end |
81 | 81 | |
82 | 82 | it "to #files" do | ... | ... |
spec/spec_helper.rb
... | ... | @@ -24,7 +24,6 @@ RSpec.configure do |config| |
24 | 24 | config.mock_with :rspec |
25 | 25 | |
26 | 26 | config.include LoginHelpers, type: :request |
27 | - config.include GitoliteStub | |
28 | 27 | config.include FactoryGirl::Syntax::Methods |
29 | 28 | config.include Devise::TestHelpers, type: :controller |
30 | 29 | |
... | ... | @@ -34,8 +33,6 @@ RSpec.configure do |config| |
34 | 33 | config.use_transactional_fixtures = false |
35 | 34 | |
36 | 35 | config.before do |
37 | - stub_gitolite! | |
38 | - | |
39 | 36 | # Use tmp dir for FS manipulations |
40 | 37 | temp_repos_path = Rails.root.join('tmp', 'test-git-base-path') |
41 | 38 | Gitlab.config.gitolite.stub(repos_path: temp_repos_path) | ... | ... |
spec/support/gitolite_stub.rb
... | ... | @@ -1,21 +0,0 @@ |
1 | -module GitoliteStub | |
2 | - def stub_gitolite! | |
3 | - stub_gitlab_gitolite | |
4 | - stub_gitolite_admin | |
5 | - end | |
6 | - | |
7 | - def stub_gitolite_admin | |
8 | - gitolite_admin = double('Gitolite::GitoliteAdmin') | |
9 | - gitolite_admin.as_null_object | |
10 | - | |
11 | - Gitolite::GitoliteAdmin.stub(new: gitolite_admin) | |
12 | - end | |
13 | - | |
14 | - def stub_gitlab_gitolite | |
15 | - gitolite_config = double('Gitlab::GitoliteConfig') | |
16 | - gitolite_config.stub(apply: ->() { yield(self) }) | |
17 | - gitolite_config.as_null_object | |
18 | - | |
19 | - Gitlab::GitoliteConfig.stub(new: gitolite_config) | |
20 | - end | |
21 | -end |
spec/support/stubbed_repository.rb
1 | 1 | require "repository" |
2 | 2 | require "project" |
3 | +require "shell" | |
3 | 4 | |
4 | 5 | # Stubs out all Git repository access done by models so that specs can run |
5 | 6 | # against fake repositories without Grit complaining that they don't exist. |
... | ... | @@ -36,3 +37,23 @@ class GitLabTestRepo < Repository |
36 | 37 | @repo ||= Grit::Repo.new(Rails.root.join('tmp', 'repositories', 'gitlabhq')) |
37 | 38 | end |
38 | 39 | end |
40 | + | |
41 | +module Gitlab | |
42 | + class Shell | |
43 | + def add_repository name | |
44 | + true | |
45 | + end | |
46 | + | |
47 | + def remove_repository name | |
48 | + true | |
49 | + end | |
50 | + | |
51 | + def add_key id, key | |
52 | + true | |
53 | + end | |
54 | + | |
55 | + def remove_key id, key | |
56 | + true | |
57 | + end | |
58 | + end | |
59 | +end | ... | ... |
spec/workers/post_receive_spec.rb
... | ... | @@ -11,7 +11,7 @@ describe PostReceive do |
11 | 11 | context "web hook" do |
12 | 12 | let(:project) { create(:project) } |
13 | 13 | let(:key) { create(:key, user: project.owner) } |
14 | - let(:key_id) { key.identifier } | |
14 | + let(:key_id) { key.shell_id } | |
15 | 15 | |
16 | 16 | it "fetches the correct project" do |
17 | 17 | Project.should_receive(:find_with_namespace).with(project.path_with_namespace).and_return(project) |
... | ... | @@ -19,7 +19,7 @@ describe PostReceive do |
19 | 19 | end |
20 | 20 | |
21 | 21 | it "does not run if the author is not in the project" do |
22 | - Key.stub(find_by_identifier: nil) | |
22 | + Key.stub(find_by_id: nil) | |
23 | 23 | |
24 | 24 | project.should_not_receive(:observe_push) |
25 | 25 | project.should_not_receive(:execute_hooks) | ... | ... |
vendor/assets/javascripts/branch-graph.js
... | ... | @@ -73,7 +73,8 @@ |
73 | 73 | , cumonth = "" |
74 | 74 | , offsetX = 20 |
75 | 75 | , offsetY = 60 |
76 | - , barWidth = Math.max(graphWidth, this.dayCount * 20 + 320); | |
76 | + , barWidth = Math.max(graphWidth, this.dayCount * 20 + 320) | |
77 | + , scrollLeft = cw; | |
77 | 78 | |
78 | 79 | this.raphael = r; |
79 | 80 | |
... | ... | @@ -103,8 +104,9 @@ |
103 | 104 | |
104 | 105 | for (i = 0; i < this.commitCount; i++) { |
105 | 106 | var x = offsetX + 20 * this.commits[i].time |
106 | - , y = offsetY + 20 * this.commits[i].space | |
107 | - , c; | |
107 | + , y = offsetY + 10 * this.commits[i].space | |
108 | + , c | |
109 | + , ps; | |
108 | 110 | |
109 | 111 | // Draw dot |
110 | 112 | r.circle(x, y, 3).attr({ |
... | ... | @@ -115,10 +117,12 @@ |
115 | 117 | // Draw lines |
116 | 118 | for (var j = 0, jj = this.commits[i].parents.length; j < jj; j++) { |
117 | 119 | c = this.preparedCommits[this.commits[i].parents[j][0]]; |
120 | + ps = this.commits[i].parent_spaces[j]; | |
118 | 121 | if (c) { |
119 | 122 | var cx = offsetX + 20 * c.time |
120 | - , cy = offsetY + 20 * c.space; | |
121 | - if (c.space == this.commits[i].space) { | |
123 | + , cy = offsetY + 10 * c.space | |
124 | + , psy = offsetY + 10 * ps; | |
125 | + if (c.space == this.commits[i].space && c.space == ps) { | |
122 | 126 | r.path([ |
123 | 127 | "M", x, y, |
124 | 128 | "L", cx, cy |
... | ... | @@ -128,13 +132,25 @@ |
128 | 132 | }); |
129 | 133 | |
130 | 134 | } else if (c.space < this.commits[i].space) { |
131 | - r.path(["M", x - 5, y + .0001, "l-5-2,0,4,5,-2C", x - 5, y, x - 17, y + 2, x - 20, y - 5, "L", cx, y - 5, cx, cy]) | |
135 | + r.path([ | |
136 | + "M", x - 5, y, | |
137 | + "l-5-2,0,4,5,-2", | |
138 | + "L", x - 10, y, | |
139 | + "L", x - 15, psy, | |
140 | + "L", cx + 5, psy, | |
141 | + "L", cx, cy]) | |
132 | 142 | .attr({ |
133 | 143 | stroke: this.colors[this.commits[i].space], |
134 | 144 | "stroke-width": 2 |
135 | 145 | }); |
136 | 146 | } else { |
137 | - r.path(["M", x - 3, y + 6, "l-4,3,4,2,0,-5L", x - 10, y + 20, "L", x - 10, cy, cx, cy]) | |
147 | + r.path([ | |
148 | + "M", x - 3, y + 6, | |
149 | + "l-4,3,4,2,0,-5", | |
150 | + "L", x - 5, y + 10, | |
151 | + "L", x - 10, psy, | |
152 | + "L", cx + 5, psy, | |
153 | + "L", cx, cy]) | |
138 | 154 | .attr({ |
139 | 155 | stroke: this.colors[c.space], |
140 | 156 | "stroke-width": 2 |
... | ... | @@ -145,12 +161,18 @@ |
145 | 161 | |
146 | 162 | if (this.commits[i].refs) { |
147 | 163 | this.appendLabel(x, y, this.commits[i].refs); |
164 | + | |
165 | + // The main branch is displayed in the center. | |
166 | + re = new RegExp('(^| )' + this.options.ref + '( |$)'); | |
167 | + if (this.commits[i].refs.match(re)) { | |
168 | + scrollLeft = x - graphWidth / 2; | |
169 | + } | |
148 | 170 | } |
149 | 171 | |
150 | 172 | this.appendAnchor(top, this.commits[i], x, y); |
151 | 173 | } |
152 | 174 | top.toFront(); |
153 | - this.element.scrollLeft(cw); | |
175 | + this.element.scrollLeft(scrollLeft); | |
154 | 176 | this.bindEvents(); |
155 | 177 | }; |
156 | 178 | |
... | ... | @@ -260,7 +282,7 @@ |
260 | 282 | cursor: "pointer" |
261 | 283 | }) |
262 | 284 | .click(function(){ |
263 | - window.location = options.commit_url.replace('%s', commit.id); | |
285 | + window.open(options.commit_url.replace('%s', commit.id), '_blank'); | |
264 | 286 | }) |
265 | 287 | .hover(function(){ |
266 | 288 | this.tooltip = r.commitTooltip(x, y + 5, commit); | ... | ... |