Commit 8045a81b authored by Sebastian Ziebell's avatar Sebastian Ziebell

Merge branch 'master' into fixes/api

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