Commit 635ebac6 authored by Dmitriy Zaporozhets's avatar Dmitriy Zaporozhets

Merge branch 'master' into mwessel/gitlab-ce-configure-protection

parents ac7af45d 704922c8
This diff is collapsed.
...@@ -25,10 +25,10 @@ v 7.8.0 ...@@ -25,10 +25,10 @@ v 7.8.0
- Upgrade Sidekiq gem to version 3.3.0 - Upgrade Sidekiq gem to version 3.3.0
- Stop git zombie creation during force push check - Stop git zombie creation during force push check
- Show success/error messages for test setting button in services - Show success/error messages for test setting button in services
- - Added Rubocop for code style checks
- Fix commits pagination - Fix commits pagination
- -
- - Async load a branch information at the commit page
- -
- Allow configuring protection of the default branch upon first push (Marco Wessel) - Allow configuring protection of the default branch upon first push (Marco Wessel)
- -
...@@ -55,15 +55,20 @@ v 7.8.0 ...@@ -55,15 +55,20 @@ v 7.8.0
- Add a new API function that retrieves all issues assigned to a single milestone (Justin Whear and Hannes Rosenögger) - Add a new API function that retrieves all issues assigned to a single milestone (Justin Whear and Hannes Rosenögger)
- -
- -
- - API: Access groups with their path (Julien Bianchi)
- - Added link to milestone and keeping resource context on smaller viewports for issues and merge requests (Jason Blanchard)
- -
- -
- API: Add support for editing an existing project (Mika Mäenpää and Hannes Rosenögger) - API: Add support for editing an existing project (Mika Mäenpää and Hannes Rosenögger)
- -
- -
- - When test web hook - show error message instead of 500 error page if connection to hook url was reset
- Added support for firing system hooks on group create/destroy and adding/removing users to group (Boyan Tabakov) - Added support for firing system hooks on group create/destroy and adding/removing users to group (Boyan Tabakov)
- Added persistent collapse button for left side nav bar (Jason Blanchard)
v 7.7.2
- Update GitLab Shell to version 2.4.2 that fixes a bug when developers can push to protected branch
- Fix issue when LDAP user can't login with existing GitLab account
v 7.7.1 v 7.7.1
- Improve mention autocomplete performance - Improve mention autocomplete performance
......
...@@ -206,8 +206,6 @@ group :development do ...@@ -206,8 +206,6 @@ group :development do
gem 'better_errors' gem 'better_errors'
gem 'binding_of_caller' gem 'binding_of_caller'
gem 'rails_best_practices'
# Docs generator # Docs generator
gem "sdoc" gem "sdoc"
...@@ -217,11 +215,12 @@ end ...@@ -217,11 +215,12 @@ end
group :development, :test do group :development, :test do
gem 'coveralls', require: false gem 'coveralls', require: false
gem 'rubocop', '0.28.0', require: false
# gem 'rails-dev-tweaks' # gem 'rails-dev-tweaks'
gem 'spinach-rails' gem 'spinach-rails'
gem "rspec-rails" gem "rspec-rails"
gem "capybara", '~> 2.2.1' gem "capybara", '~> 2.2.1'
gem "pry" gem "pry-rails"
gem "awesome_print" gem "awesome_print"
gem "database_cleaner" gem "database_cleaner"
gem "launchy" gem "launchy"
...@@ -254,7 +253,7 @@ end ...@@ -254,7 +253,7 @@ end
group :test do group :test do
gem "simplecov", require: false gem "simplecov", require: false
gem "shoulda-matchers", "~> 2.1.0" gem "shoulda-matchers", "~> 2.7.0"
gem 'email_spec' gem 'email_spec'
gem "webmock" gem "webmock"
gem 'test_after_commit' gem 'test_after_commit'
......
...@@ -37,6 +37,9 @@ GEM ...@@ -37,6 +37,9 @@ GEM
rake (>= 0.8.7) rake (>= 0.8.7)
arel (5.0.1.20140414130214) arel (5.0.1.20140414130214)
asciidoctor (0.1.4) asciidoctor (0.1.4)
ast (2.0.0)
astrolabe (1.3.0)
parser (>= 2.2.0.pre.3, < 3.0)
attr_required (1.0.0) attr_required (1.0.0)
awesome_print (1.2.0) awesome_print (1.2.0)
axiom-types (0.0.5) axiom-types (0.0.5)
...@@ -67,8 +70,6 @@ GEM ...@@ -67,8 +70,6 @@ GEM
timers (~> 4.0.0) timers (~> 4.0.0)
charlock_holmes (0.6.9.4) charlock_holmes (0.6.9.4)
cliver (0.3.2) cliver (0.3.2)
code_analyzer (0.4.3)
sexp_processor
coderay (1.1.0) coderay (1.1.0)
coercible (1.0.0) coercible (1.0.0)
descendants_tracker (~> 0.0.1) descendants_tracker (~> 0.0.1)
...@@ -260,7 +261,7 @@ GEM ...@@ -260,7 +261,7 @@ GEM
multi_xml (>= 0.5.2) multi_xml (>= 0.5.2)
httpauth (0.2.1) httpauth (0.2.1)
httpclient (2.5.3.3) httpclient (2.5.3.3)
i18n (0.6.11) i18n (0.7.0)
ice_nine (0.10.0) ice_nine (0.10.0)
jasmine (2.0.2) jasmine (2.0.2)
jasmine-core (~> 2.0.0) jasmine-core (~> 2.0.0)
...@@ -279,7 +280,7 @@ GEM ...@@ -279,7 +280,7 @@ GEM
turbolinks turbolinks
jquery-ui-rails (4.2.1) jquery-ui-rails (4.2.1)
railties (>= 3.2.16) railties (>= 3.2.16)
json (1.8.1) json (1.8.2)
jwt (0.1.13) jwt (0.1.13)
multi_json (>= 1.5) multi_json (>= 1.5)
kaminari (0.15.1) kaminari (0.15.1)
...@@ -353,6 +354,8 @@ GEM ...@@ -353,6 +354,8 @@ GEM
org-ruby (0.9.12) org-ruby (0.9.12)
rubypants (~> 0.2) rubypants (~> 0.2)
orm_adapter (0.5.0) orm_adapter (0.5.0)
parser (2.2.0.2)
ast (>= 1.1, < 3.0)
pg (0.15.1) pg (0.15.1)
phantomjs (1.9.2.0) phantomjs (1.9.2.0)
poltergeist (1.5.1) poltergeist (1.5.1)
...@@ -362,10 +365,13 @@ GEM ...@@ -362,10 +365,13 @@ GEM
websocket-driver (>= 0.2.0) websocket-driver (>= 0.2.0)
polyglot (0.3.4) polyglot (0.3.4)
posix-spawn (0.3.9) posix-spawn (0.3.9)
powerpack (0.0.9)
pry (0.9.12.4) pry (0.9.12.4)
coderay (~> 1.0) coderay (~> 1.0)
method_source (~> 0.8) method_source (~> 0.8)
slop (~> 3.4) slop (~> 3.4)
pry-rails (0.3.2)
pry (>= 0.9.10)
pyu-ruby-sasl (0.0.3.3) pyu-ruby-sasl (0.0.3.3)
quiet_assets (1.0.2) quiet_assets (1.0.2)
railties (>= 3.1, < 5.0) railties (>= 3.1, < 5.0)
...@@ -402,20 +408,12 @@ GEM ...@@ -402,20 +408,12 @@ GEM
sprockets-rails (~> 2.0) sprockets-rails (~> 2.0)
rails_autolink (1.1.6) rails_autolink (1.1.6)
rails (> 3.1) rails (> 3.1)
rails_best_practices (1.14.4)
activesupport
awesome_print
code_analyzer (>= 0.4.3)
colored
erubis
i18n
require_all
ruby-progressbar
railties (4.1.1) railties (4.1.1)
actionpack (= 4.1.1) actionpack (= 4.1.1)
activesupport (= 4.1.1) activesupport (= 4.1.1)
rake (>= 0.8.7) rake (>= 0.8.7)
thor (>= 0.18.1, < 2.0) thor (>= 0.18.1, < 2.0)
rainbow (2.0.0)
raindrops (0.13.0) raindrops (0.13.0)
rake (10.3.2) rake (10.3.2)
raphael-rails (2.1.2) raphael-rails (2.1.2)
...@@ -446,7 +444,6 @@ GEM ...@@ -446,7 +444,6 @@ GEM
redis (>= 2.2) redis (>= 2.2)
ref (1.0.5) ref (1.0.5)
request_store (1.0.5) request_store (1.0.5)
require_all (1.3.2)
rest-client (1.6.7) rest-client (1.6.7)
mime-types (>= 1.16) mime-types (>= 1.16)
rinku (1.7.3) rinku (1.7.3)
...@@ -466,7 +463,13 @@ GEM ...@@ -466,7 +463,13 @@ GEM
rspec-core (~> 2.14.0) rspec-core (~> 2.14.0)
rspec-expectations (~> 2.14.0) rspec-expectations (~> 2.14.0)
rspec-mocks (~> 2.14.0) rspec-mocks (~> 2.14.0)
ruby-progressbar (1.2.0) rubocop (0.28.0)
astrolabe (~> 1.3)
parser (>= 2.2.0.pre.7, < 3.0)
powerpack (~> 0.0.6)
rainbow (>= 1.99.1, < 3.0)
ruby-progressbar (~> 1.4)
ruby-progressbar (1.7.1)
rubyntlm (0.4.0) rubyntlm (0.4.0)
rubypants (0.2.0) rubypants (0.2.0)
rugged (0.21.2) rugged (0.21.2)
...@@ -494,8 +497,7 @@ GEM ...@@ -494,8 +497,7 @@ GEM
semantic-ui-sass (1.8.0.0) semantic-ui-sass (1.8.0.0)
sass (~> 3.2) sass (~> 3.2)
settingslogic (2.0.9) settingslogic (2.0.9)
sexp_processor (4.4.0) shoulda-matchers (2.7.0)
shoulda-matchers (2.1.0)
activesupport (>= 3.0.0) activesupport (>= 3.0.0)
sidekiq (3.3.0) sidekiq (3.3.0)
celluloid (>= 0.16.0) celluloid (>= 0.16.0)
...@@ -518,7 +520,7 @@ GEM ...@@ -518,7 +520,7 @@ GEM
slim (2.0.2) slim (2.0.2)
temple (~> 0.6.6) temple (~> 0.6.6)
tilt (>= 1.3.3, < 2.1) tilt (>= 1.3.3, < 2.1)
slop (3.4.7) slop (3.6.0)
spinach (0.8.7) spinach (0.8.7)
colorize (= 0.5.8) colorize (= 0.5.8)
gherkin-ruby (>= 0.3.1) gherkin-ruby (>= 0.3.1)
...@@ -694,7 +696,7 @@ DEPENDENCIES ...@@ -694,7 +696,7 @@ DEPENDENCIES
org-ruby (= 0.9.12) org-ruby (= 0.9.12)
pg pg
poltergeist (~> 1.5.1) poltergeist (~> 1.5.1)
pry pry-rails
quiet_assets (~> 1.0.1) quiet_assets (~> 1.0.1)
rack-attack rack-attack
rack-cors rack-cors
...@@ -702,7 +704,6 @@ DEPENDENCIES ...@@ -702,7 +704,6 @@ DEPENDENCIES
rack-oauth2 (~> 1.0.5) rack-oauth2 (~> 1.0.5)
rails (~> 4.1.0) rails (~> 4.1.0)
rails_autolink (~> 1.1) rails_autolink (~> 1.1)
rails_best_practices
raphael-rails (~> 2.1.2) raphael-rails (~> 2.1.2)
rb-fsevent rb-fsevent
rb-inotify rb-inotify
...@@ -711,6 +712,7 @@ DEPENDENCIES ...@@ -711,6 +712,7 @@ DEPENDENCIES
redis-rails redis-rails
request_store request_store
rspec-rails rspec-rails
rubocop (= 0.28.0)
rugments rugments
sanitize (~> 2.0) sanitize (~> 2.0)
sass-rails (~> 4.0.2) sass-rails (~> 4.0.2)
...@@ -719,7 +721,7 @@ DEPENDENCIES ...@@ -719,7 +721,7 @@ DEPENDENCIES
select2-rails select2-rails
semantic-ui-sass (~> 1.8.0) semantic-ui-sass (~> 1.8.0)
settingslogic settingslogic
shoulda-matchers (~> 2.1.0) shoulda-matchers (~> 2.7.0)
sidekiq (~> 3.3) sidekiq (~> 3.3)
simplecov simplecov
sinatra sinatra
......
...@@ -9,8 +9,6 @@ class @calendar ...@@ -9,8 +9,6 @@ class @calendar
cal.init cal.init
itemName: ["commit"] itemName: ["commit"]
data: timestamps data: timestamps
domain: "year"
subDomain: "month"
start: new Date(starting_year, starting_month) start: new Date(starting_year, starting_month)
domainLabelFormat: "%b" domainLabelFormat: "%b"
id: "cal-heatmap" id: "cal-heatmap"
......
...@@ -24,3 +24,18 @@ $ -> ...@@ -24,3 +24,18 @@ $ ->
$(window).resize -> $(window).resize ->
responsive_resize() responsive_resize()
return return
$(document).on("click", '.toggle-nav-collapse', (e) ->
e.preventDefault()
collapsed = 'page-sidebar-collapsed'
expanded = 'page-sidebar-expanded'
if $('.page-with-sidebar').hasClass(collapsed)
$('.page-with-sidebar').removeClass(collapsed).addClass(expanded)
$('.toggle-nav-collapse i').removeClass('fa-angle-right').addClass('fa-angle-left')
$.cookie("collapsed_nav", "false", { path: '/' })
else
$('.page-with-sidebar').removeClass(expanded).addClass(collapsed)
$('.toggle-nav-collapse i').removeClass('fa-angle-left').addClass('fa-angle-right')
$.cookie("collapsed_nav", "true", { path: '/' })
)
...@@ -15,6 +15,10 @@ ...@@ -15,6 +15,10 @@
&.s24 { margin-right: 4px; } &.s24 { margin-right: 4px; }
} }
&.avatar-tile {
@include border-radius(0px);
}
&.s16 { width: 16px; height: 16px; margin-right: 6px; } &.s16 { width: 16px; height: 16px; margin-right: 6px; }
&.s24 { width: 24px; height: 24px; margin-right: 8px; } &.s24 { width: 24px; height: 24px; margin-right: 8px; }
&.s26 { width: 26px; height: 26px; margin-right: 8px; } &.s26 { width: 26px; height: 26px; margin-right: 8px; }
......
...@@ -97,7 +97,17 @@ ...@@ -97,7 +97,17 @@
.dash-project-avatar { .dash-project-avatar {
float: left; float: left;
.avatar {
margin-top: -8px;
margin-left: -15px;
@include border-radius(0px);
}
.identicon {
line-height: 40px;
}
} }
.dash-project-access-icon { .dash-project-access-icon {
float: left; float: left;
margin-right: 5px; margin-right: 5px;
......
...@@ -40,12 +40,12 @@ ...@@ -40,12 +40,12 @@
font-size: $code_font_size; font-size: $code_font_size;
.old { .old {
span.idiff { span.idiff {
background-color: #F99; background-color: #f8cbcb;
} }
} }
.new { .new {
span.idiff { span.idiff {
background-color: #8F8; background-color: #a6f3a6;
} }
} }
.unfold { .unfold {
...@@ -84,7 +84,7 @@ ...@@ -84,7 +84,7 @@
padding: 0px; padding: 0px;
border: none; border: none;
background: #F5F5F5; background: #F5F5F5;
color: #666; color: rgba(0,0,0,0.3);
padding: 0px 5px; padding: 0px 5px;
border-right: 1px solid #ccc; border-right: 1px solid #ccc;
text-align: right; text-align: right;
...@@ -96,7 +96,7 @@ ...@@ -96,7 +96,7 @@
float: left; float: left;
width: 35px; width: 35px;
font-weight: normal; font-weight: normal;
color: #666; color: rgba(0,0,0,0.3);
&:hover { &:hover {
text-decoration: underline; text-decoration: underline;
} }
...@@ -114,13 +114,13 @@ ...@@ -114,13 +114,13 @@
.line_holder { .line_holder {
&.old .old_line, &.old .old_line,
&.old .new_line { &.old .new_line {
background: #FCC; background: #ffdddd;
border-color: #E7BABA; border-color: #f1c0c0;
} }
&.new .old_line, &.new .old_line,
&.new .new_line { &.new .new_line {
background: #CFC; background: #dbffdb;
border-color: #B9ECB9; border-color: #c1e9c1;
} }
} }
.line_content { .line_content {
...@@ -129,10 +129,10 @@ ...@@ -129,10 +129,10 @@
padding: 0px 0.5em; padding: 0px 0.5em;
border: none; border: none;
&.new { &.new {
background: #CFD; background: #eaffea;
} }
&.old { &.old {
background: #FDD; background: #ffecec;
} }
&.matched { &.matched {
color: #ccc; color: #ccc;
......
.page-with-sidebar { .page-with-sidebar {
background: #F5F5F5; background: #F5F5F5;
...@@ -101,9 +99,7 @@ ...@@ -101,9 +99,7 @@
} }
@mixin expanded-sidebar { @mixin expanded-sidebar {
.page-with-sidebar {
padding-left: $sidebar_width; padding-left: $sidebar_width;
}
.sidebar-wrapper { .sidebar-wrapper {
width: $sidebar_width; width: $sidebar_width;
...@@ -122,9 +118,7 @@ ...@@ -122,9 +118,7 @@
} }
@mixin folded-sidebar { @mixin folded-sidebar {
.page-with-sidebar {
padding-left: 50px; padding-left: 50px;
}
.sidebar-wrapper { .sidebar-wrapper {
width: 52px; width: 52px;
...@@ -150,10 +144,33 @@ ...@@ -150,10 +144,33 @@
} }
} }
.collapse-nav a {
position: fixed;
bottom: 15px;
padding: 10px;
background: #DDD;
}
@media (max-width: $screen-md-max) { @media (max-width: $screen-md-max) {
.page-sidebar-collapsed {
@include folded-sidebar; @include folded-sidebar;
}
.page-sidebar-expanded {
@include folded-sidebar;
}
.collapse-nav {
display: none;
}
} }
@media(min-width: $screen-md-max) { @media(min-width: $screen-md-max) {
.page-sidebar-collapsed {
@include folded-sidebar;
}
.page-sidebar-expanded {
@include expanded-sidebar; @include expanded-sidebar;
}
} }
...@@ -23,7 +23,7 @@ class GithubImportsController < ApplicationController ...@@ -23,7 +23,7 @@ class GithubImportsController < ApplicationController
end end
def jobs def jobs
jobs = current_user.created_projects.where(import_type: "github").to_json(:only => [:id, :import_status]) jobs = current_user.created_projects.where(import_type: "github").to_json(only: [:id, :import_status])
render json: jobs render json: jobs
end end
...@@ -58,7 +58,7 @@ class GithubImportsController < ApplicationController ...@@ -58,7 +58,7 @@ class GithubImportsController < ApplicationController
def octo_client def octo_client
Octokit.auto_paginate = true Octokit.auto_paginate = true
@octo_client ||= Octokit::Client.new(:access_token => current_user.github_access_token) @octo_client ||= Octokit::Client.new(access_token: current_user.github_access_token)
end end
def github_auth def github_auth
......
...@@ -15,4 +15,3 @@ class NamespacesController < ApplicationController ...@@ -15,4 +15,3 @@ class NamespacesController < ApplicationController
end end
end end
end end
...@@ -59,8 +59,7 @@ class Projects::BlobController < Projects::ApplicationController ...@@ -59,8 +59,7 @@ class Projects::BlobController < Projects::ApplicationController
def preview def preview
@content = params[:content] @content = params[:content]
diffy = Diffy::Diff.new(@blob.data, @content, diff: '-U 3', diffy = Diffy::Diff.new(@blob.data, @content, diff: '-U 3', include_diff_info: true)
include_diff_info: true)
@diff_lines = Gitlab::Diff::Parser.new.parse(diffy.diff.scan(/.*\n/)) @diff_lines = Gitlab::Diff::Parser.new.parse(diffy.diff.scan(/.*\n/))
render layout: false render layout: false
......
...@@ -11,8 +11,6 @@ class Projects::CommitController < Projects::ApplicationController ...@@ -11,8 +11,6 @@ class Projects::CommitController < Projects::ApplicationController
return git_not_found! unless @commit return git_not_found! unless @commit
@line_notes = @project.notes.for_commit_id(commit.id).inline @line_notes = @project.notes.for_commit_id(commit.id).inline
@branches = @project.repository.branch_names_contains(commit.id)
@tags = @project.repository.tag_names_contains(commit.id)
@diffs = @commit.diffs @diffs = @commit.diffs
@note = @project.build_commit_note(commit) @note = @project.build_commit_note(commit)
@notes_count = @project.notes.for_commit_id(commit.id).count @notes_count = @project.notes.for_commit_id(commit.id).count
...@@ -31,6 +29,12 @@ class Projects::CommitController < Projects::ApplicationController ...@@ -31,6 +29,12 @@ class Projects::CommitController < Projects::ApplicationController
end end
end end
def branches
@branches = @project.repository.branch_names_contains(commit.id)
@tags = @project.repository.tag_names_contains(commit.id)
render layout: false
end
def commit def commit
@commit ||= @project.repository.commit(params[:id]) @commit ||= @project.repository.commit(params[:id])
end end
......
...@@ -35,4 +35,3 @@ class Projects::RawController < Projects::ApplicationController ...@@ -35,4 +35,3 @@ class Projects::RawController < Projects::ApplicationController
end end
end end
end end
...@@ -27,7 +27,7 @@ class SnippetsController < ApplicationController ...@@ -27,7 +27,7 @@ class SnippetsController < ApplicationController
@snippets = SnippetsFinder.new.execute(current_user, { @snippets = SnippetsFinder.new.execute(current_user, {
filter: :by_user, filter: :by_user,
user: @user, user: @user,
scope: params[:scope]}). scope: params[:scope] }).
page(params[:page]).per(20) page(params[:page]).per(20)
if @user == current_user if @user == current_user
......
...@@ -28,13 +28,10 @@ class UsersController < ApplicationController ...@@ -28,13 +28,10 @@ class UsersController < ApplicationController
def calendar def calendar
visible_projects = ProjectsFinder.new.execute(current_user) visible_projects = ProjectsFinder.new.execute(current_user)
calendar = Gitlab::CommitsCalendar.new(visible_projects, @user)
# Get user repositories and collect timestamps for commits
user_repositories = visible_projects.map(&:repository)
calendar = Gitlab::CommitsCalendar.new(user_repositories, @user)
@timestamps = calendar.timestamps @timestamps = calendar.timestamps
@starting_year = (Time.now - 1.year).strftime("%Y") @starting_year = calendar.starting_year
@starting_month = Date.today.strftime("%m").to_i @starting_month = calendar.starting_month
render 'calendar', layout: false render 'calendar', layout: false
end end
......
...@@ -7,7 +7,8 @@ class NotesFinder ...@@ -7,7 +7,8 @@ class NotesFinder
# Default to 0 to remain compatible with old clients # Default to 0 to remain compatible with old clients
last_fetched_at = Time.at(params.fetch(:last_fetched_at, 0).to_i) last_fetched_at = Time.at(params.fetch(:last_fetched_at, 0).to_i)
notes = case target_type notes =
case target_type
when "commit" when "commit"
project.notes.for_commit_id(target_id).not_inline.fresh project.notes.for_commit_id(target_id).not_inline.fresh
when "issue" when "issue"
......
...@@ -75,9 +75,9 @@ module ApplicationHelper ...@@ -75,9 +75,9 @@ module ApplicationHelper
options[:class] ||= '' options[:class] ||= ''
options[:class] << ' identicon' options[:class] << ' identicon'
bg_key = project.id % 7 bg_key = project.id % 7
style = "background-color: ##{ allowed_colors.values[bg_key] }; color: #555"
content_tag(:div, class: options[:class], content_tag(:div, class: options[:class], style: style) do
style: "background-color: ##{ allowed_colors.values[bg_key] }; color: #555") do
project.name[0, 1].upcase project.name[0, 1].upcase
end end
end end
...@@ -247,15 +247,6 @@ module ApplicationHelper ...@@ -247,15 +247,6 @@ module ApplicationHelper
Gitlab::MarkdownHelper.gitlab_markdown?(filename) Gitlab::MarkdownHelper.gitlab_markdown?(filename)
end end
def spinner(text = nil, visible = false)
css_class = 'loading'
css_class << ' hide' unless visible
content_tag :div, class: css_class do
content_tag(:i, nil, class: 'fa fa-spinner fa-spin') + text
end
end
def link_to(name = nil, options = nil, html_options = nil, &block) def link_to(name = nil, options = nil, html_options = nil, &block)
begin begin
uri = URI(options) uri = URI(options)
...@@ -324,4 +315,12 @@ module ApplicationHelper ...@@ -324,4 +315,12 @@ module ApplicationHelper
profile_key_path(key) profile_key_path(key)
end end
end end
def nav_sidebar_class
if nav_menu_collapsed?
"page-sidebar-collapsed"
else
"page-sidebar-expanded"
end
end
end end
...@@ -65,8 +65,7 @@ module CommitsHelper ...@@ -65,8 +65,7 @@ module CommitsHelper
branches.sort.map do |branch| branches.sort.map do |branch|
link_to(project_tree_path(project, branch)) do link_to(project_tree_path(project, branch)) do
content_tag :span, class: 'label label-gray' do content_tag :span, class: 'label label-gray' do
content_tag(:i, nil, class: 'fa fa-code-fork') + ' ' + icon('code-fork') + ' ' + branch
branch
end end
end end
end.join(" ").html_safe end.join(" ").html_safe
...@@ -78,8 +77,7 @@ module CommitsHelper ...@@ -78,8 +77,7 @@ module CommitsHelper
sorted.map do |tag| sorted.map do |tag|
link_to(project_commits_path(project, project.repository.find_tag(tag).name)) do link_to(project_commits_path(project, project.repository.find_tag(tag).name)) do
content_tag :span, class: 'label label-gray' do content_tag :span, class: 'label label-gray' do
content_tag(:i, nil, class: 'fa fa-tag') + ' ' + icon('tag') + ' ' + tag
tag
end end
end end
end.join(" ").html_safe end.join(" ").html_safe
...@@ -114,7 +112,8 @@ module CommitsHelper ...@@ -114,7 +112,8 @@ module CommitsHelper
person_name = user.nil? ? source_name : user.name person_name = user.nil? ? source_name : user.name
person_email = user.nil? ? source_email : user.email person_email = user.nil? ? source_email : user.email
text = if options[:avatar] text =
if options[:avatar]
avatar = image_tag(avatar_icon(person_email, options[:size]), class: "avatar #{"s#{options[:size]}" if options[:size]}", width: options[:size], alt: "") avatar = image_tag(avatar_icon(person_email, options[:size]), class: "avatar #{"s#{options[:size]}" if options[:size]}", width: options[:size], alt: "")
%Q{#{avatar} <span class="commit-#{options[:source]}-name">#{person_name}</span>} %Q{#{avatar} <span class="commit-#{options[:source]}-name">#{person_name}</span>}
else else
......
...@@ -10,6 +10,6 @@ module CompareHelper ...@@ -10,6 +10,6 @@ module CompareHelper
end end
def compare_mr_path def compare_mr_path
new_project_merge_request_path(@project, merge_request: {source_branch: params[:to], target_branch: params[:from]}) new_project_merge_request_path(@project, merge_request: { source_branch: params[:to], target_branch: params[:from] })
end end
end end
...@@ -31,7 +31,7 @@ module EmailsHelper ...@@ -31,7 +31,7 @@ module EmailsHelper
end end
def add_email_highlight_css def add_email_highlight_css
Rugments::Themes::Github.render(:scope => '.highlight') Rugments::Themes::Github.render(scope: '.highlight')
end end
def color_email_diff(diffcontent) def color_email_diff(diffcontent)
......
...@@ -27,18 +27,17 @@ module EventsHelper ...@@ -27,18 +27,17 @@ module EventsHelper
content_tag :li, class: "filter_icon #{active}" do content_tag :li, class: "filter_icon #{active}" do
link_to request.path, class: 'has_tooltip event_filter_link', id: "#{key}_event_filter", 'data-original-title' => tooltip do link_to request.path, class: 'has_tooltip event_filter_link', id: "#{key}_event_filter", 'data-original-title' => tooltip do
content_tag(:i, nil, class: icon_for_event[key]) + icon(icon_for_event[key]) + content_tag(:span, ' ' + tooltip)
content_tag(:span, ' ' + tooltip)
end end
end end
end end
def icon_for_event def icon_for_event
{ {
EventFilter.push => 'fa fa-upload', EventFilter.push => 'upload',
EventFilter.merged => 'fa fa-check-square-o', EventFilter.merged => 'check-square-o',
EventFilter.comments => 'fa fa-comments', EventFilter.comments => 'comments',
EventFilter.team => 'fa fa-user', EventFilter.team => 'user',
} }
end end
......
module IconsHelper module IconsHelper
# Creates an icon tag given icon name(s) and possible icon modifiers.
#
# Right now this method simply delegates directly to `fa_icon` from the
# font-awesome-rails gem, but should we ever use a different icon pack in the
# future we won't have to change hundreds of method calls.
def icon(names, options = {})
fa_icon(names, options)
end
def spinner(text = nil, visible = false)
css_class = 'loading'
css_class << ' hide' unless visible
content_tag :div, class: css_class do
icon('spinner spin') + text
end
end
def boolean_to_icon(value) def boolean_to_icon(value)
if value.to_s == "true" if value.to_s == "true"
content_tag :i, nil, class: 'fa fa-circle cgreen' icon('circle', class: 'cgreen')
else else
content_tag :i, nil, class: 'fa fa-power-off clgray' icon('power-off', class: 'clgray')
end end
end end
def public_icon def public_icon
content_tag :i, nil, class: 'fa fa-globe' icon('globe')
end end
def internal_icon def internal_icon
content_tag :i, nil, class: 'fa fa-shield' icon('shield')
end end
def private_icon def private_icon
content_tag :i, nil, class: 'fa fa-lock' icon('lock')
end end
end end
...@@ -49,7 +49,7 @@ module IssuesHelper ...@@ -49,7 +49,7 @@ module IssuesHelper
ts << capture_haml do ts << capture_haml do
haml_tag :span do haml_tag :span do
haml_concat '&middot;' haml_concat '&middot;'
haml_concat '<i class="fa fa-edit" title="edited"></i> ' haml_concat icon('edit', title: 'edited')
haml_concat time_ago_with_tooltip(issue.updated_at, 'bottom', 'issue_edited_ago') haml_concat time_ago_with_tooltip(issue.updated_at, 'bottom', 'issue_edited_ago')
end end
end end
......
...@@ -15,12 +15,14 @@ module MergeRequestsHelper ...@@ -15,12 +15,14 @@ module MergeRequestsHelper
end end
def new_mr_from_push_event(event, target_project) def new_mr_from_push_event(event, target_project)
return :merge_request => { return {
merge_request: {
source_project_id: event.project.id, source_project_id: event.project.id,
target_project_id: target_project.id, target_project_id: target_project.id,
source_branch: event.branch_name, source_branch: event.branch_name,
target_branch: target_project.repository.root_ref target_branch: target_project.repository.root_ref
} }
}
end end
def mr_css_classes(mr) def mr_css_classes(mr)
......
module NavHelper
def nav_menu_collapsed?
cookies[:collapsed_nav] == 'true'
end
end
...@@ -22,7 +22,7 @@ module NotesHelper ...@@ -22,7 +22,7 @@ module NotesHelper
ts << capture_haml do ts << capture_haml do
haml_tag :span do haml_tag :span do
haml_concat '&middot;' haml_concat '&middot;'
haml_concat '<i class="fa fa-edit" title="edited"></i> ' haml_concat icon('edit', title: 'edited')
haml_concat time_ago_with_tooltip(note.updated_at, 'bottom', 'note_edited_ago') haml_concat time_ago_with_tooltip(note.updated_at, 'bottom', 'note_edited_ago')
end end
end end
...@@ -57,7 +57,7 @@ module NotesHelper ...@@ -57,7 +57,7 @@ module NotesHelper
button_tag(class: 'btn add-diff-note js-add-diff-note-button', button_tag(class: 'btn add-diff-note js-add-diff-note-button',
data: data, data: data,
title: 'Add a comment to this line') do title: 'Add a comment to this line') do
content_tag :i, nil, class: 'fa fa-comment-o' icon('comment-o')
end end
end end
...@@ -74,7 +74,7 @@ module NotesHelper ...@@ -74,7 +74,7 @@ module NotesHelper
button_tag class: 'btn reply-btn js-discussion-reply-button', button_tag class: 'btn reply-btn js-discussion-reply-button',
data: data, title: 'Add a reply' do data: data, title: 'Add a reply' do
link_text = content_tag(:i, nil, class: 'fa fa-comment') link_text = icon('comment')
link_text << ' Reply' link_text << ' Reply'
end end
end end
......
module NotificationsHelper module NotificationsHelper
def notification_icon(notification) def notification_icon(notification)
if notification.disabled? if notification.disabled?
content_tag :i, nil, class: 'fa fa-volume-off ns-mute' icon('volume-off', class: 'ns-mute')
elsif notification.participating? elsif notification.participating?
content_tag :i, nil, class: 'fa fa-volume-down ns-part' icon('volume-down', class: 'ns-part')
elsif notification.watch? elsif notification.watch?
content_tag :i, nil, class: 'fa fa-volume-up ns-watch' icon('volume-up', class: 'ns-watch')
else else
content_tag :i, nil, class: 'fa fa-circle-o ns-default' icon('circle-o', class: 'ns-default')
end end
end end
end end
...@@ -83,7 +83,7 @@ module ProjectsHelper ...@@ -83,7 +83,7 @@ module ProjectsHelper
' Star' ' Star'
end end
content_tag('i', ' ', class: 'fa fa-star') + toggle_text icon('star') + toggle_text
end end
count_html = content_tag('span', class: 'count') do count_html = content_tag('span', class: 'count') do
...@@ -95,7 +95,7 @@ module ProjectsHelper ...@@ -95,7 +95,7 @@ module ProjectsHelper
class: cls, class: cls,
method: :post, method: :post,
remote: true, remote: true,
data: {type: 'json'} data: { type: 'json' }
} }
...@@ -107,7 +107,7 @@ module ProjectsHelper ...@@ -107,7 +107,7 @@ module ProjectsHelper
end end
def link_to_toggle_fork def link_to_toggle_fork
out = content_tag(:i, '', class: 'fa fa-code-fork') out = icon('code-fork')
out << ' Fork' out << ' Fork'
out << content_tag(:span, class: 'count') do out << content_tag(:span, class: 'count') do
@project.forks_count.to_s @project.forks_count.to_s
...@@ -254,4 +254,3 @@ module ProjectsHelper ...@@ -254,4 +254,3 @@ module ProjectsHelper
enabled_oauth_providers.include?(:github) enabled_oauth_providers.include?(:github)
end end
end end
...@@ -38,13 +38,8 @@ module TreeHelper ...@@ -38,13 +38,8 @@ module TreeHelper
# #
# type - String type of the tree item; either 'folder' or 'file' # type - String type of the tree item; either 'folder' or 'file'
def tree_icon(type) def tree_icon(type)
icon_class = if type == 'folder' icon_class = type == 'folder' ? 'folder' : 'file-o'
'fa fa-folder' icon(icon_class)
else
'fa fa-file-o'
end
content_tag :i, nil, class: icon_class
end end
def tree_hex_class(content) def tree_hex_class(content)
......
...@@ -15,7 +15,8 @@ ...@@ -15,7 +15,8 @@
# #
class ApplicationSetting < ActiveRecord::Base class ApplicationSetting < ActiveRecord::Base
validates :home_page_url, allow_blank: true, validates :home_page_url,
allow_blank: true,
format: { with: URI::regexp(%w(http https)), message: "should be a valid url" }, format: { with: URI::regexp(%w(http https)), message: "should be a valid url" },
if: :home_page_url_column_exist if: :home_page_url_column_exist
......
...@@ -88,7 +88,8 @@ class Commit ...@@ -88,7 +88,8 @@ class Commit
# cut off, ellipses (`&hellp;`) are prepended to the commit message. # cut off, ellipses (`&hellp;`) are prepended to the commit message.
def description def description
title_end = safe_message.index("\n") title_end = safe_message.index("\n")
@description ||= if (!title_end && safe_message.length > 100) || (title_end && title_end > 100) @description ||=
if (!title_end && safe_message.length > 100) || (title_end && title_end > 100)
"&hellip;".html_safe << safe_message[80..-1] "&hellip;".html_safe << safe_message[80..-1]
else else
safe_message.split("\n", 2)[1].try(:chomp) safe_message.split("\n", 2)[1].try(:chomp)
......
...@@ -44,11 +44,11 @@ class WebHook < ActiveRecord::Base ...@@ -44,11 +44,11 @@ class WebHook < ActiveRecord::Base
} }
WebHook.post(post_url, WebHook.post(post_url,
body: data.to_json, body: data.to_json,
headers: {"Content-Type" => "application/json"}, headers: { "Content-Type" => "application/json" },
verify: false, verify: false,
basic_auth: auth) basic_auth: auth)
end end
rescue SocketError, Errno::ECONNREFUSED, Net::OpenTimeout => e rescue SocketError, Errno::ECONNRESET, Errno::ECONNREFUSED, Net::OpenTimeout => e
logger.error("WebHook Error => #{e}") logger.error("WebHook Error => #{e}")
false false
end end
......
...@@ -11,5 +11,5 @@ ...@@ -11,5 +11,5 @@
class Identity < ActiveRecord::Base class Identity < ActiveRecord::Base
belongs_to :user belongs_to :user
validates :extern_uid, allow_blank: true, uniqueness: {scope: :provider} validates :extern_uid, allow_blank: true, uniqueness: { scope: :provider }
end end
...@@ -76,7 +76,7 @@ class MergeRequest < ActiveRecord::Base ...@@ -76,7 +76,7 @@ class MergeRequest < ActiveRecord::Base
merge_request.save merge_request.save
end end
after_transition :locked => (any - :locked) do |merge_request, transition| after_transition locked: (any - :locked) do |merge_request, transition|
merge_request.locked_at = nil merge_request.locked_at = nil
merge_request.save merge_request.save
end end
......
...@@ -20,12 +20,17 @@ class Namespace < ActiveRecord::Base ...@@ -20,12 +20,17 @@ class Namespace < ActiveRecord::Base
belongs_to :owner, class_name: "User" belongs_to :owner, class_name: "User"
validates :owner, presence: true, unless: ->(n) { n.type == "Group" } validates :owner, presence: true, unless: ->(n) { n.type == "Group" }
validates :name, presence: true, uniqueness: true, validates :name,
presence: true, uniqueness: true,
length: { within: 0..255 }, length: { within: 0..255 },
format: { with: Gitlab::Regex.name_regex, format: { with: Gitlab::Regex.name_regex,
message: Gitlab::Regex.name_regex_message } message: Gitlab::Regex.name_regex_message }
validates :description, length: { within: 0..255 } validates :description, length: { within: 0..255 }
validates :path, uniqueness: { case_sensitive: false }, presence: true, length: { within: 1..255 }, validates :path,
uniqueness: { case_sensitive: false },
presence: true,
length: { within: 1..255 },
exclusion: { in: Gitlab::Blacklist.path }, exclusion: { in: Gitlab::Blacklist.path },
format: { with: Gitlab::Regex.path_regex, format: { with: Gitlab::Regex.path_regex,
message: Gitlab::Regex.path_regex_message } message: Gitlab::Regex.path_regex_message }
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,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
# issues_tracker :string(255) default('gitlab'), not null # issues_tracker :string(255) default("gitlab"), not null
# issues_tracker_id :string(255) # issues_tracker_id :string(255)
# snippets_enabled :boolean default(TRUE), not null # snippets_enabled :boolean default(TRUE), not null
# last_activity_at :datetime # last_activity_at :datetime
...@@ -108,10 +108,14 @@ class Project < ActiveRecord::Base ...@@ -108,10 +108,14 @@ class Project < ActiveRecord::Base
# Validations # Validations
validates :creator, presence: true, on: :create validates :creator, presence: true, on: :create
validates :description, length: { maximum: 2000 }, allow_blank: true validates :description, length: { maximum: 2000 }, allow_blank: true
validates :name, presence: true, length: { within: 0..255 }, validates :name,
presence: true,
length: { within: 0..255 },
format: { with: Gitlab::Regex.project_name_regex, format: { with: Gitlab::Regex.project_name_regex,
message: Gitlab::Regex.project_regex_message } message: Gitlab::Regex.project_regex_message }
validates :path, presence: true, length: { within: 0..255 }, validates :path,
presence: true,
length: { within: 0..255 },
exclusion: { in: Gitlab::Blacklist.path }, exclusion: { in: Gitlab::Blacklist.path },
format: { with: Gitlab::Regex.path_regex, format: { with: Gitlab::Regex.path_regex,
message: Gitlab::Regex.path_regex_message } message: Gitlab::Regex.path_regex_message }
...@@ -156,22 +160,22 @@ class Project < ActiveRecord::Base ...@@ -156,22 +160,22 @@ class Project < ActiveRecord::Base
end end
event :import_finish do event :import_finish do
transition :started => :finished transition started: :finished
end end
event :import_fail do event :import_fail do
transition :started => :failed transition started: :failed
end end
event :import_retry do event :import_retry do
transition :failed => :started transition failed: :started
end end
state :started state :started
state :finished state :finished
state :failed state :failed
after_transition any => :started, :do => :add_import_job after_transition any => :started, do: :add_import_job
end end
class << self class << self
......
class ProjectContributions
attr_reader :project, :user
def initialize(project, user)
@project, @user = project, user
end
def commits_log
repository = project.repository
if !repository.exists? || repository.empty?
return {}
end
Rails.cache.fetch(cache_key) do
repository.commits_per_day_for_user(user)
end
end
def cache_key
"#{Date.today.to_s}-commits-log-#{project.id}-#{user.email}"
end
end
...@@ -17,13 +17,19 @@ class BambooService < CiService ...@@ -17,13 +17,19 @@ class BambooService < CiService
prop_accessor :bamboo_url, :build_key, :username, :password prop_accessor :bamboo_url, :build_key, :username, :password
validates :bamboo_url, presence: true, validates :bamboo_url,
format: { with: URI::regexp }, if: :activated? presence: true,
format: { with: URI::regexp },
if: :activated?
validates :build_key, presence: true, if: :activated? validates :build_key, presence: true, if: :activated?
validates :username, presence: true, validates :username,
if: ->(service) { service.password? }, if: :activated? presence: true,
validates :password, presence: true, if: ->(service) { service.password? },
if: ->(service) { service.username? }, if: :activated? if: :activated?
validates :password,
presence: true,
if: ->(service) { service.username? },
if: :activated?
attr_accessor :response attr_accessor :response
......
# == Schema Information
#
# Table name: services
#
# id :integer not null, primary key
# type :string(255)
# title :string(255)
# project_id :integer not null
# created_at :datetime
# updated_at :datetime
# active :boolean default(FALSE), not null
# properties :text
#
class CustomIssueTrackerService < IssueTrackerService class CustomIssueTrackerService < IssueTrackerService
prop_accessor :title, :description, :project_url, :issues_url, :new_issue_url prop_accessor :title, :description, :project_url, :issues_url, :new_issue_url
...@@ -27,8 +41,8 @@ class CustomIssueTrackerService < IssueTrackerService ...@@ -27,8 +41,8 @@ class CustomIssueTrackerService < IssueTrackerService
{ type: 'text', name: 'title', placeholder: title }, { type: 'text', name: 'title', placeholder: title },
{ type: 'text', name: 'description', placeholder: description }, { type: 'text', name: 'description', placeholder: description },
{ type: 'text', name: 'project_url', placeholder: 'Project url' }, { type: 'text', name: 'project_url', placeholder: 'Project url' },
{ type: 'text', name: 'issues_url', placeholder: 'Issue url'}, { type: 'text', name: 'issues_url', placeholder: 'Issue url' },
{ type: 'text', name: 'new_issue_url', placeholder: 'New Issue url'} { type: 'text', name: 'new_issue_url', placeholder: 'New Issue url' }
] ]
end end
......
...@@ -81,7 +81,7 @@ class GitlabCiService < CiService ...@@ -81,7 +81,7 @@ class GitlabCiService < CiService
def fields def fields
[ [
{ type: 'text', name: 'token', placeholder: 'GitLab CI project specific token' }, { type: 'text', name: 'token', placeholder: 'GitLab CI project specific token' },
{ type: 'text', name: 'project_url', placeholder: 'http://ci.gitlabhq.com/projects/3'} { type: 'text', name: 'project_url', placeholder: 'http://ci.gitlabhq.com/projects/3' }
] ]
end end
end end
# == Schema Information
#
# Table name: services
#
# id :integer not null, primary key
# type :string(255)
# title :string(255)
# project_id :integer not null
# created_at :datetime
# updated_at :datetime
# active :boolean default(FALSE), not null
# properties :text
#
class GitlabIssueTrackerService < IssueTrackerService class GitlabIssueTrackerService < IssueTrackerService
include Rails.application.routes.url_helpers include Rails.application.routes.url_helpers
prop_accessor :title, :description, :project_url, :issues_url, :new_issue_url prop_accessor :title, :description, :project_url, :issues_url, :new_issue_url
......
# == Schema Information
#
# Table name: services
#
# id :integer not null, primary key
# type :string(255)
# title :string(255)
# project_id :integer not null
# created_at :datetime
# updated_at :datetime
# active :boolean default(FALSE), not null
# properties :text
#
class IssueTrackerService < Service class IssueTrackerService < Service
validates :project_url, :issues_url, :new_issue_url, presence: true, if: :activated? validates :project_url, :issues_url, :new_issue_url, presence: true, if: :activated?
...@@ -30,8 +44,8 @@ class IssueTrackerService < Service ...@@ -30,8 +44,8 @@ class IssueTrackerService < Service
[ [
{ type: 'text', name: 'description', placeholder: description }, { type: 'text', name: 'description', placeholder: description },
{ type: 'text', name: 'project_url', placeholder: 'Project url' }, { type: 'text', name: 'project_url', placeholder: 'Project url' },
{ type: 'text', name: 'issues_url', placeholder: 'Issue url'}, { type: 'text', name: 'issues_url', placeholder: 'Issue url' },
{ type: 'text', name: 'new_issue_url', placeholder: 'New Issue url'} { type: 'text', name: 'new_issue_url', placeholder: 'New Issue url' }
] ]
end end
......
# == Schema Information
#
# Table name: services
#
# id :integer not null, primary key
# type :string(255)
# title :string(255)
# project_id :integer not null
# created_at :datetime
# updated_at :datetime
# active :boolean default(FALSE), not null
# properties :text
#
class JiraService < IssueTrackerService class JiraService < IssueTrackerService
prop_accessor :title, :description, :project_url, :issues_url, :new_issue_url prop_accessor :title, :description, :project_url, :issues_url, :new_issue_url
......
# == Schema Information
#
# Table name: services
#
# id :integer not null, primary key
# type :string(255)
# title :string(255)
# project_id :integer not null
# created_at :datetime
# updated_at :datetime
# active :boolean default(FALSE), not null
# properties :text
#
class RedmineService < IssueTrackerService class RedmineService < IssueTrackerService
prop_accessor :title, :description, :project_url, :issues_url, :new_issue_url prop_accessor :title, :description, :project_url, :issues_url, :new_issue_url
......
...@@ -17,12 +17,15 @@ class TeamcityService < CiService ...@@ -17,12 +17,15 @@ class TeamcityService < CiService
prop_accessor :teamcity_url, :build_type, :username, :password prop_accessor :teamcity_url, :build_type, :username, :password
validates :teamcity_url, presence: true, validates :teamcity_url,
presence: true,
format: { with: URI::regexp }, if: :activated? format: { with: URI::regexp }, if: :activated?
validates :build_type, presence: true, if: :activated? validates :build_type, presence: true, if: :activated?
validates :username, presence: true, validates :username,
presence: true,
if: ->(service) { service.password? }, if: :activated? if: ->(service) { service.password? }, if: :activated?
validates :password, presence: true, validates :password,
presence: true,
if: ->(service) { service.username? }, if: :activated? if: ->(service) { service.username? }, if: :activated?
attr_accessor :response attr_accessor :response
......
...@@ -136,7 +136,7 @@ class ProjectWiki ...@@ -136,7 +136,7 @@ class ProjectWiki
def commit_details(action, message = nil, title = nil) def commit_details(action, message = nil, title = nil)
commit_message = message || default_message(action, title) commit_message = message || default_message(action, title)
{email: @user.email, name: @user.name, message: commit_message} { email: @user.email, name: @user.name, message: commit_message }
end end
def default_message(action, title) def default_message(action, title)
......
...@@ -30,7 +30,7 @@ class Repository ...@@ -30,7 +30,7 @@ class Repository
commit = Gitlab::Git::Commit.find(raw_repository, id) commit = Gitlab::Git::Commit.find(raw_repository, id)
commit = Commit.new(commit) if commit commit = Commit.new(commit) if commit
commit commit
rescue Rugged::OdbError => ex rescue Rugged::OdbError
nil nil
end end
...@@ -61,25 +61,25 @@ class Repository ...@@ -61,25 +61,25 @@ class Repository
end end
def add_branch(branch_name, ref) def add_branch(branch_name, ref)
Rails.cache.delete(cache_key(:branch_names)) cache.expire(:branch_names)
gitlab_shell.add_branch(path_with_namespace, branch_name, ref) gitlab_shell.add_branch(path_with_namespace, branch_name, ref)
end end
def add_tag(tag_name, ref, message = nil) def add_tag(tag_name, ref, message = nil)
Rails.cache.delete(cache_key(:tag_names)) cache.expire(:tag_names)
gitlab_shell.add_tag(path_with_namespace, tag_name, ref, message) gitlab_shell.add_tag(path_with_namespace, tag_name, ref, message)
end end
def rm_branch(branch_name) def rm_branch(branch_name)
Rails.cache.delete(cache_key(:branch_names)) cache.expire(:branch_names)
gitlab_shell.rm_branch(path_with_namespace, branch_name) gitlab_shell.rm_branch(path_with_namespace, branch_name)
end end
def rm_tag(tag_name) def rm_tag(tag_name)
Rails.cache.delete(cache_key(:tag_names)) cache.expire(:tag_names)
gitlab_shell.rm_tag(path_with_namespace, tag_name) gitlab_shell.rm_tag(path_with_namespace, tag_name)
end end
...@@ -97,19 +97,15 @@ class Repository ...@@ -97,19 +97,15 @@ class Repository
end end
def branch_names def branch_names
Rails.cache.fetch(cache_key(:branch_names)) do cache.fetch(:branch_names) { raw_repository.branch_names }
raw_repository.branch_names
end
end end
def tag_names def tag_names
Rails.cache.fetch(cache_key(:tag_names)) do cache.fetch(:tag_names) { raw_repository.tag_names }
raw_repository.tag_names
end
end end
def commit_count def commit_count
Rails.cache.fetch(cache_key(:commit_count)) do cache.fetch(:commit_count) do
begin begin
raw_repository.commit_count(self.root_ref) raw_repository.commit_count(self.root_ref)
rescue rescue
...@@ -121,26 +117,19 @@ class Repository ...@@ -121,26 +117,19 @@ class Repository
# Return repo size in megabytes # Return repo size in megabytes
# Cached in redis # Cached in redis
def size def size
Rails.cache.fetch(cache_key(:size)) do cache.fetch(:size) { raw_repository.size }
raw_repository.size
end
end end
def expire_cache def expire_cache
Rails.cache.delete(cache_key(:size)) %i(size branch_names tag_names commit_count graph_log
Rails.cache.delete(cache_key(:branch_names)) readme version contribution_guide).each do |key|
Rails.cache.delete(cache_key(:tag_names)) cache.expire(key)
Rails.cache.delete(cache_key(:commit_count)) end
Rails.cache.delete(cache_key(:graph_log))
Rails.cache.delete(cache_key(:readme))
Rails.cache.delete(cache_key(:version))
Rails.cache.delete(cache_key(:contribution_guide))
end end
def graph_log def graph_log
Rails.cache.fetch(cache_key(:graph_log)) do cache.fetch(:graph_log) do
commits = raw_repository.log(limit: 6000, commits = raw_repository.log(limit: 6000, skip_merges: true,
skip_merges: true,
ref: root_ref) ref: root_ref)
commits.map do |rugged_commit| commits.map do |rugged_commit|
...@@ -176,10 +165,6 @@ class Repository ...@@ -176,10 +165,6 @@ class Repository
end end
end end
def cache_key(type)
"#{type}:#{path_with_namespace}"
end
def method_missing(m, *args, &block) def method_missing(m, *args, &block)
raw_repository.send(m, *args, &block) raw_repository.send(m, *args, &block)
end end
...@@ -199,13 +184,11 @@ class Repository ...@@ -199,13 +184,11 @@ class Repository
end end
def readme def readme
Rails.cache.fetch(cache_key(:readme)) do cache.fetch(:readme) { tree(:head).readme }
tree(:head).readme
end
end end
def version def version
Rails.cache.fetch(cache_key(:version)) do cache.fetch(:version) do
tree(:head).blobs.find do |file| tree(:head).blobs.find do |file|
file.name.downcase == 'version' file.name.downcase == 'version'
end end
...@@ -213,9 +196,7 @@ class Repository ...@@ -213,9 +196,7 @@ class Repository
end end
def contribution_guide def contribution_guide
Rails.cache.fetch(cache_key(:contribution_guide)) do cache.fetch(:contribution_guide) { tree(:head).contribution_guide }
tree(:head).contribution_guide
end
end end
def head_commit def head_commit
...@@ -351,4 +332,10 @@ class Repository ...@@ -351,4 +332,10 @@ class Repository
[] []
end end
end end
private
def cache
@cache ||= RepositoryCache.new(path_with_namespace)
end
end end
...@@ -29,7 +29,9 @@ class Snippet < ActiveRecord::Base ...@@ -29,7 +29,9 @@ class Snippet < ActiveRecord::Base
validates :author, presence: true validates :author, presence: true
validates :title, presence: true, length: { within: 0..255 } validates :title, presence: true, length: { within: 0..255 }
validates :file_name, presence: true, length: { within: 0..255 }, validates :file_name,
presence: true,
length: { within: 0..255 },
format: { with: Gitlab::Regex.path_regex, format: { with: Gitlab::Regex.path_regex,
message: Gitlab::Regex.path_regex_message } message: Gitlab::Regex.path_regex_message }
validates :content, presence: true validates :content, presence: true
......
...@@ -113,10 +113,12 @@ class User < ActiveRecord::Base ...@@ -113,10 +113,12 @@ class User < ActiveRecord::Base
# Validations # Validations
# #
validates :name, presence: true validates :name, presence: true
validates :email, presence: true, email: {strict_mode: true}, uniqueness: true validates :email, presence: true, email: { strict_mode: true }, uniqueness: true
validates :bio, length: { maximum: 255 }, allow_blank: true validates :bio, length: { maximum: 255 }, allow_blank: true
validates :projects_limit, presence: true, numericality: {greater_than_or_equal_to: 0} validates :projects_limit, presence: true, numericality: { greater_than_or_equal_to: 0 }
validates :username, presence: true, uniqueness: { case_sensitive: false }, validates :username,
presence: true,
uniqueness: { case_sensitive: false },
exclusion: { in: Gitlab::Blacklist.path }, exclusion: { in: Gitlab::Blacklist.path },
format: { with: Gitlab::Regex.username_regex, format: { with: Gitlab::Regex.username_regex,
message: Gitlab::Regex.username_regex_message } message: Gitlab::Regex.username_regex_message }
......
...@@ -43,7 +43,7 @@ class WikiPage ...@@ -43,7 +43,7 @@ class WikiPage
@attributes[:slug] @attributes[:slug]
end end
alias :to_param :slug alias_method :to_param, :slug
# The formatted title of this page. # The formatted title of this page.
def title def title
......
...@@ -5,7 +5,8 @@ module Projects ...@@ -5,7 +5,8 @@ module Projects
end end
def execute(note_type, note_id) def execute(note_type, note_id)
participating = if note_type && note_id participating =
if note_type && note_id
participants_in(note_type, note_id) participants_in(note_type, note_id)
else else
[] []
......
...@@ -10,7 +10,8 @@ ...@@ -10,7 +10,8 @@
- groups.each do |group| - groups.each do |group|
%li.group-row %li.group-row
= link_to group_path(id: group.path), class: dom_class(group) do = link_to group_path(id: group.path), class: dom_class(group) do
= image_tag group_icon(group.path), class: "avatar s24" .dash-project-avatar
= image_tag group_icon(group.path), class: "avatar s40"
%span.group-name.filter-title %span.group-name.filter-title
= truncate(group.name, length: 35) = truncate(group.name, length: 35)
%span.arrow %span.arrow
......
= link_to project_path(project), class: dom_class(project) do = link_to project_path(project), class: dom_class(project) do
.dash-project-avatar
= project_icon(project.to_param, alt: '', class: 'avatar s40')
.dash-project-access-icon .dash-project-access-icon
= visibility_level_icon(project.visibility_level) = visibility_level_icon(project.visibility_level)
.dash-project-avatar
= project_icon(project.to_param, alt: '', class: 'avatar s24')
%span.str-truncated %span.str-truncated
%span.namespace-name %span.namespace-name
- if project.namespace - if project.namespace
......
...@@ -12,10 +12,10 @@ ...@@ -12,10 +12,10 @@
- projects.each do |project| - projects.each do |project|
%li.project-row %li.project-row
= link_to project_path(project), class: dom_class(project) do = link_to project_path(project), class: dom_class(project) do
.dash-project-avatar
= project_icon(project.to_param, alt: '', class: 'avatar s40')
.dash-project-access-icon .dash-project-access-icon
= visibility_level_icon(project.visibility_level) = visibility_level_icon(project.visibility_level)
.dash-project-avatar
= project_icon(project.to_param, alt: '', class: 'avatar s24')
%span.str-truncated %span.str-truncated
%span.project-name %span.project-name
= project.name = project.name
......
.dashboard .dashboard
%div %div
= image_tag group_icon(@group.path), class: "avatar s90" = image_tag group_icon(@group.path), class: "avatar avatar-tile s90"
.clearfix .clearfix
%h2 %h2
= @group.name = @group.name
......
- if nav_menu_collapsed?
= link_to icon('angle-right'), '#', class: 'toggle-nav-collapse'
- else
= link_to icon('angle-left'), '#', class: 'toggle-nav-collapse'
- if defined?(sidebar) - if defined?(sidebar)
.page-with-sidebar .page-with-sidebar{ class: nav_sidebar_class }
= render "layouts/broadcast" = render "layouts/broadcast"
.sidebar-wrapper .sidebar-wrapper
= render(sidebar) = render(sidebar)
.collapse-nav
= render partial: 'layouts/collapse_button'
.content-wrapper .content-wrapper
.container-fluid .container-fluid
.content .content
......
...@@ -37,23 +37,8 @@ ...@@ -37,23 +37,8 @@
- @commit.parents.each do |parent| - @commit.parents.each do |parent|
= link_to parent.short_id, project_commit_path(@project, parent) = link_to parent.short_id, project_commit_path(@project, parent)
.commit-info-row .commit-info-row.branches
- if @branches.any? %i.fa.fa-spinner.fa-spin
%span
- branch = commit_default_branch(@project, @branches)
= link_to(project_tree_path(@project, branch)) do
%span.label.label-gray
%i.fa.fa-code-fork
= branch
- if @branches.any? || @tags.any?
= link_to("#", class: "js-details-expand") do
%span.label.label-gray
\...
%span.js-details-content.hide
- if @branches.any?
= commit_branches_links(@project, @branches)
- if @tags.any?
= commit_tags_links(@project, @tags)
.commit-box .commit-box
%h3.commit-title %h3.commit-title
...@@ -61,3 +46,7 @@ ...@@ -61,3 +46,7 @@
- if @commit.description.present? - if @commit.description.present?
%pre.commit-description %pre.commit-description
= preserve(gfm(escape_once(@commit.description))) = preserve(gfm(escape_once(@commit.description)))
:coffeescript
$ ->
$(".commit-info-row.branches").load("#{branches_project_commit_path(@project, @commit.id)}")
\ No newline at end of file
- if @branches.any?
%span
- branch = commit_default_branch(@project, @branches)
= link_to(project_tree_path(@project, branch)) do
%span.label.label-gray
%i.fa.fa-code-fork
= branch
- if @branches.any? || @tags.any?
= link_to("#", class: "js-details-expand") do
%span.label.label-gray
\...
%span.js-details-content.hide
- if @branches.any?
= commit_branches_links(@project, @branches)
- if @tags.any?
= commit_tags_links(@project, @tags)
\ No newline at end of file
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
You can You can
= link_to project_new_blob_path(@project, 'master'), class: 'btn btn-new btn-lg' do = link_to project_new_blob_path(@project, 'master'), class: 'btn btn-new btn-lg' do
add a file add a file
&nbsp;or push it via command line. &nbsp;or do a push via the command line.
%h4 %h4
%strong Command line instructions %strong Command line instructions
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
= link_to_member(@project, participant, name: false, size: 24) = link_to_member(@project, participant, name: false, size: 24)
.voting_notes#notes= render "projects/notes/notes_with_form" .voting_notes#notes= render "projects/notes/notes_with_form"
.col-md-3.hidden-sm.hidden-xs .col-md-3
%div %div
.clearfix .clearfix
%span.slead.has_tooltip{:"data-original-title" => 'Cross-project reference'} %span.slead.has_tooltip{:"data-original-title" => 'Cross-project reference'}
......
...@@ -2,23 +2,21 @@ ...@@ -2,23 +2,21 @@
%div.prepend-top-20 %div.prepend-top-20
%p %p
Assignee: Assignee:
- if issue.assignee
- if can?(current_user, :modify_issue, @issue)
= project_users_select_tag('issue[assignee_id]', placeholder: 'Select assignee', class: 'custom-form-control js-select2 js-assignee', selected: @issue.assignee_id)
- elsif issue.assignee
= link_to_member(@project, @issue.assignee) = link_to_member(@project, @issue.assignee)
- else - else
None none
- if can?(current_user, :modify_issue, @issue)
= project_users_select_tag('issue[assignee_id]', placeholder: 'Select assignee', class: 'custom-form-control js-select2 js-assignee', selected: @issue.assignee_id)
%div.prepend-top-20 %div.prepend-top-20
%p %p
Milestone: Milestone:
- if issue.milestone
#{link_to @issue.milestone.title, project_milestone_path(@project, @issue.milestone)}
- else
none
- if can?(current_user, :modify_issue, @issue) - if can?(current_user, :modify_issue, @issue)
= f.select(:milestone_id, milestone_options(@issue), { include_blank: "Select milestone" }, {class: 'select2 select2-compact js-select2 js-milestone'}) = f.select(:milestone_id, milestone_options(@issue), { include_blank: "Select milestone" }, {class: 'select2 select2-compact js-select2 js-milestone'})
= hidden_field_tag :issue_context = hidden_field_tag :issue_context
= f.submit class: 'btn' = f.submit class: 'btn'
- elsif issue.milestone
= link_to project_milestone_path(@project, @issue.milestone) do
= @issue.milestone.title
- else
None
...@@ -3,8 +3,15 @@ ...@@ -3,8 +3,15 @@
:plain :plain
$("##{dom_id(@issue)}").fadeOut(); $("##{dom_id(@issue)}").fadeOut();
- elsif params[:issue_context] - elsif params[:issue_context]
$('.context').html("#{escape_javascript(render partial: 'issue_context', locals: { issue: @issue })}");
$('.context').effect('highlight'); $('.context').effect('highlight');
- if @issue.milestone - if @issue.milestone
$('.milestone-nav-link').replaceWith("<span class='milestone-nav-link'>| <span class='light'>Milestone</span> #{escape_javascript(link_to @issue.milestone.title, project_milestone_path(@issue.project, @issue.milestone))}</span>") $('.milestone-nav-link').replaceWith("<span class='milestone-nav-link'>| <span class='light'>Milestone</span> #{escape_javascript(link_to @issue.milestone.title, project_milestone_path(@issue.project, @issue.milestone))}</span>")
- else - else
$('.milestone-nav-link').html('') $('.milestone-nav-link').html('')
$('select.select2').select2({width: 'resolve', dropdownAutoWidth: true})
$('.edit-issue.inline-update input[type="submit"]').hide();
new ProjectUsersSelect();
new Issue();
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
.col-md-9 .col-md-9
= render "projects/merge_requests/show/participants" = render "projects/merge_requests/show/participants"
= render "projects/notes/notes_with_form" = render "projects/notes/notes_with_form"
.col-md-3.hidden-sm.hidden-xs .col-md-3
.clearfix .clearfix
%span.slead.has_tooltip{:"data-original-title" => 'Cross-project reference'} %span.slead.has_tooltip{:"data-original-title" => 'Cross-project reference'}
= cross_project_reference(@project, @merge_request) = cross_project_reference(@project, @merge_request)
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
%cite.cgray %cite.cgray
= render partial: 'projects/merge_requests/show/context', locals: { merge_request: @merge_request } = render partial: 'projects/merge_requests/show/context', locals: { merge_request: @merge_request }
%hr %hr
.votes-holder.hidden-sm.hidden-xs .votes-holder
%h6 Votes %h6 Votes
#votes= render 'votes/votes_block', votable: @merge_request #votes= render 'votes/votes_block', votable: @merge_request
......
...@@ -2,22 +2,22 @@ ...@@ -2,22 +2,22 @@
%div.prepend-top-20 %div.prepend-top-20
%p %p
Assignee: Assignee:
- if @merge_request.assignee
- if can?(current_user, :modify_merge_request, @merge_request)
= project_users_select_tag('merge_request[assignee_id]', placeholder: 'Select assignee', class: 'custom-form-control js-select2 js-assignee', selected: @merge_request.assignee_id)
- elsif merge_request.assignee
= link_to_member(@project, @merge_request.assignee) = link_to_member(@project, @merge_request.assignee)
- else - else
None none
- if can?(current_user, :modify_merge_request, @merge_request)
= project_users_select_tag('merge_request[assignee_id]', placeholder: 'Select assignee', class: 'custom-form-control js-select2 js-assignee', selected: @merge_request.assignee_id)
%div.prepend-top-20 %div.prepend-top-20
%p %p
Milestone: Milestone:
- if @merge_request.milestone
%span.back-to-milestone
#{link_to @merge_request.milestone.title, project_milestone_path(@project, @merge_request.milestone)}
- else
none
- if can?(current_user, :modify_merge_request, @merge_request) - if can?(current_user, :modify_merge_request, @merge_request)
= f.select(:milestone_id, milestone_options(@merge_request), { include_blank: "Select milestone" }, {class: 'select2 select2-compact js-select2 js-milestone'}) = f.select(:milestone_id, milestone_options(@merge_request), { include_blank: "Select milestone" }, {class: 'select2 select2-compact js-select2 js-milestone'})
= hidden_field_tag :merge_request_context = hidden_field_tag :merge_request_context
= f.submit class: 'btn' = f.submit class: 'btn'
- elsif merge_request.milestone
= link_to merge_request.milestone.title, project_milestone_path
- else
None
- if params[:merge_request_context] - if params[:merge_request_context]
$('.context').html("#{escape_javascript(render partial: 'projects/merge_requests/show/context', locals: { issue: @issue })}");
$('.context').effect('highlight'); $('.context').effect('highlight');
new ProjectUsersSelect();
$('select.select2').select2({width: 'resolve', dropdownAutoWidth: true});
merge_request = new MergeRequest();
.clearfix .clearfix
- groups.each do |group| - groups.each do |group|
= link_to group, class: 'profile-groups-avatars', title: group.name do = link_to group, class: 'profile-groups-avatars inline', title: group.name do
= image_tag group_icon(group.path), class: 'avatar avatar-inline s40' = image_tag group_icon(group.path), class: 'avatar avatar-tile s40'
%h4 Calendar: %h4 Calendar
#cal-heatmap.calendar #cal-heatmap.calendar
:javascript :javascript
new calendar( new calendar(
......
.row .row
.col-md-8 .col-md-8
%h3.page-title %h3.page-title
= image_tag avatar_icon(@user.email, 90), class: "avatar s90", alt: '' = image_tag avatar_icon(@user.email, 90), class: "avatar avatar-tile s90", alt: ''
= @user.name = @user.name
- if @user == current_user - if @user == current_user
.pull-right .pull-right
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
.clearfix .clearfix
- if @groups.any? - if @groups.any?
%h4 Groups: %h4 Groups
= render 'groups', groups: @groups = render 'groups', groups: @groups
%hr %hr
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
%i.fa.fa-spinner.fa-spin %i.fa.fa-spinner.fa-spin
%hr %hr
%h4 %h4
User Activity: User Activity
- if current_user - if current_user
%span.rss-icon.pull-right %span.rss-icon.pull-right
......
...@@ -70,7 +70,10 @@ module Gitlab ...@@ -70,7 +70,10 @@ module Gitlab
config.middleware.use Rack::Cors do config.middleware.use Rack::Cors do
allow do allow do
origins '*' origins '*'
resource '/api/*', headers: :any, methods: [:get, :post, :options, :put, :delete] resource '/api/*',
headers: :any,
methods: [:get, :post, :options, :put, :delete],
expose: ['Link']
end end
end end
......
...@@ -149,7 +149,7 @@ Settings.gitlab_shell['ssh_path_prefix'] ||= Settings.send(:build_gitlab_shell_s ...@@ -149,7 +149,7 @@ Settings.gitlab_shell['ssh_path_prefix'] ||= Settings.send(:build_gitlab_shell_s
Settings['backup'] ||= Settingslogic.new({}) Settings['backup'] ||= Settingslogic.new({})
Settings.backup['keep_time'] ||= 0 Settings.backup['keep_time'] ||= 0
Settings.backup['path'] = File.expand_path(Settings.backup['path'] || "tmp/backups/", Rails.root) Settings.backup['path'] = File.expand_path(Settings.backup['path'] || "tmp/backups/", Rails.root)
Settings.backup['upload'] ||= Settingslogic.new({'remote_directory' => nil, 'connection' => nil}) Settings.backup['upload'] ||= Settingslogic.new({ 'remote_directory' => nil, 'connection' => nil })
# Convert upload connection settings to use symbol keys, to make Fog happy # Convert upload connection settings to use symbol keys, to make Fog happy
if Settings.backup['upload']['connection'] if Settings.backup['upload']['connection']
Settings.backup['upload']['connection'] = Hash[Settings.backup['upload']['connection'].map { |k, v| [k.to_sym, v] }] Settings.backup['upload']['connection'] = Hash[Settings.backup['upload']['connection'].map { |k, v| [k.to_sym, v] }]
......
...@@ -42,7 +42,8 @@ module ActsAsTaggableOn::Taggable ...@@ -42,7 +42,8 @@ module ActsAsTaggableOn::Taggable
elsif options.delete(:any) elsif options.delete(:any)
# get tags, drop out if nothing returned (we need at least one) # get tags, drop out if nothing returned (we need at least one)
tags = if options.delete(:wild) tags =
if options.delete(:wild)
ActsAsTaggableOn::Tag.named_like_any(tag_list) ActsAsTaggableOn::Tag.named_like_any(tag_list)
else else
ActsAsTaggableOn::Tag.named_any(tag_list) ActsAsTaggableOn::Tag.named_any(tag_list)
......
...@@ -12,22 +12,30 @@ if File.exists?(aws_file) ...@@ -12,22 +12,30 @@ if File.exists?(aws_file)
aws_secret_access_key: AWS_CONFIG['secret_access_key'], # required aws_secret_access_key: AWS_CONFIG['secret_access_key'], # required
region: AWS_CONFIG['region'], # optional, defaults to 'us-east-1' region: AWS_CONFIG['region'], # optional, defaults to 'us-east-1'
} }
config.fog_directory = AWS_CONFIG['bucket'] # required
config.fog_public = false # optional, defaults to true # required
config.fog_attributes = {'Cache-Control'=>'max-age=315576000'} # optional, defaults to {} config.fog_directory = AWS_CONFIG['bucket']
config.fog_authenticated_url_expiration = 1 << 29 # optional time (in seconds) that authenticated urls will be valid.
# optional, defaults to true
config.fog_public = false
# optional, defaults to {}
config.fog_attributes = { 'Cache-Control'=>'max-age=315576000' }
# optional time (in seconds) that authenticated urls will be valid.
# when fog_public is false and provider is AWS or Google, defaults to 600 # when fog_public is false and provider is AWS or Google, defaults to 600
config.fog_authenticated_url_expiration = 1 << 29
end end
# Mocking Fog requests, based on: https://github.com/carrierwaveuploader/carrierwave/wiki/How-to%3A-Test-Fog-based-uploaders # Mocking Fog requests, based on: https://github.com/carrierwaveuploader/carrierwave/wiki/How-to%3A-Test-Fog-based-uploaders
if Rails.env.test? if Rails.env.test?
Fog.mock! Fog.mock!
connection = ::Fog::Storage.new( connection = ::Fog::Storage.new(
:aws_access_key_id => AWS_CONFIG['access_key_id'], aws_access_key_id: AWS_CONFIG['access_key_id'],
:aws_secret_access_key => AWS_CONFIG['secret_access_key'], aws_secret_access_key: AWS_CONFIG['secret_access_key'],
:provider => 'AWS', provider: 'AWS',
:region => AWS_CONFIG['region'] region: AWS_CONFIG['region']
) )
connection.directories.create(:key => AWS_CONFIG['bucket']) connection.directories.create(key: AWS_CONFIG['bucket'])
end end
end end
...@@ -43,10 +43,10 @@ Doorkeeper.configure do ...@@ -43,10 +43,10 @@ Doorkeeper.configure do
force_ssl_in_redirect_uri false force_ssl_in_redirect_uri false
# Provide support for an owner to be assigned to each registered application (disabled by default) # Provide support for an owner to be assigned to each registered application (disabled by default)
# Optional parameter :confirmation => true (default false) if you want to enforce ownership of # Optional parameter confirmation: true (default false) if you want to enforce ownership of
# a registered application # a registered application
# Note: you must also run the rails g doorkeeper:application_owner generator to provide the necessary support # Note: you must also run the rails g doorkeeper:application_owner generator to provide the necessary support
enable_application_owner :confirmation => false enable_application_owner confirmation: false
# Define access token scopes for your provider # Define access token scopes for your provider
# For more information go to # For more information go to
......
...@@ -3,9 +3,9 @@ require 'api/api' ...@@ -3,9 +3,9 @@ require 'api/api'
Gitlab::Application.routes.draw do Gitlab::Application.routes.draw do
use_doorkeeper do use_doorkeeper do
controllers :applications => 'oauth/applications', controllers applications: 'oauth/applications',
:authorized_applications => 'oauth/authorized_applications', authorized_applications: 'oauth/authorized_applications',
:authorizations => 'oauth/authorizations' authorizations: 'oauth/authorizations'
end end
# #
# Search # Search
...@@ -177,7 +177,7 @@ Gitlab::Application.routes.draw do ...@@ -177,7 +177,7 @@ Gitlab::Application.routes.draw do
# #
# Groups Area # Groups Area
# #
resources :groups, constraints: {id: /(?:[^.]|\.(?!atom$))+/, format: /atom/} do resources :groups, constraints: { id: /(?:[^.]|\.(?!atom$))+/, format: /atom/ } do
member do member do
get :issues get :issues
get :merge_requests get :merge_requests
...@@ -215,40 +215,44 @@ Gitlab::Application.routes.draw do ...@@ -215,40 +215,44 @@ Gitlab::Application.routes.draw do
scope module: :projects do scope module: :projects do
# Blob routes: # Blob routes:
get '/new/:id', to: 'blob#new', constraints: {id: /.+/}, as: 'new_blob' get '/new/:id', to: 'blob#new', constraints: { id: /.+/ }, as: 'new_blob'
post '/create/:id', to: 'blob#create', constraints: {id: /.+/}, as: 'create_blob' post '/create/:id', to: 'blob#create', constraints: { id: /.+/ }, as: 'create_blob'
get '/edit/:id', to: 'blob#edit', constraints: {id: /.+/}, as: 'edit_blob' get '/edit/:id', to: 'blob#edit', constraints: { id: /.+/ }, as: 'edit_blob'
put '/update/:id', to: 'blob#update', constraints: {id: /.+/}, as: 'update_blob' put '/update/:id', to: 'blob#update', constraints: { id: /.+/ }, as: 'update_blob'
post '/preview/:id', to: 'blob#preview', constraints: {id: /.+/}, as: 'preview_blob' post '/preview/:id', to: 'blob#preview', constraints: { id: /.+/ }, as: 'preview_blob'
resources :blob, only: [:show, :destroy], constraints: { id: /.+/, format: false } do resources :blob, only: [:show, :destroy], constraints: { id: /.+/, format: false } do
get :diff, on: :member get :diff, on: :member
end end
resources :raw, only: [:show], constraints: {id: /.+/} resources :raw, only: [:show], constraints: { id: /.+/ }
resources :tree, only: [:show], constraints: {id: /.+/, format: /(html|js)/ } resources :tree, only: [:show], constraints: { id: /.+/, format: /(html|js)/ }
resource :avatar, only: [:show, :destroy] resource :avatar, only: [:show, :destroy]
resources :commit, only: [:show], constraints: {id: /[[:alnum:]]{6,40}/}
resources :commits, only: [:show], constraints: {id: /(?:[^.]|\.(?!atom$))+/, format: /atom/} resources :commit, only: [:show], constraints: { id: /[[:alnum:]]{6,40}/ } do
get :branches, on: :member
end
resources :commits, only: [:show], constraints: { id: /(?:[^.]|\.(?!atom$))+/, format: /atom/ }
resources :compare, only: [:index, :create] resources :compare, only: [:index, :create]
resources :blame, only: [:show], constraints: {id: /.+/} resources :blame, only: [:show], constraints: { id: /.+/ }
resources :network, only: [:show], constraints: {id: /(?:[^.]|\.(?!json$))+/, format: /json/} resources :network, only: [:show], constraints: { id: /(?:[^.]|\.(?!json$))+/, format: /json/ }
resources :graphs, only: [:show], constraints: {id: /(?:[^.]|\.(?!json$))+/, format: /json/} do resources :graphs, only: [:show], constraints: { id: /(?:[^.]|\.(?!json$))+/, format: /json/ } do
member do member do
get :commits get :commits
end end
end end
get '/compare/:from...:to' => 'compare#show', :as => 'compare', get '/compare/:from...:to' => 'compare#show', :as => 'compare',
:constraints => {from: /.+/, to: /.+/} :constraints => { from: /.+/, to: /.+/ }
resources :snippets, constraints: {id: /\d+/} do resources :snippets, constraints: { id: /\d+/ } do
member do member do
get 'raw' get 'raw'
end end
end end
resources :wikis, only: [:show, :edit, :destroy, :create], constraints: {id: /[a-zA-Z.0-9_\-\/]+/} do resources :wikis, only: [:show, :edit, :destroy, :create], constraints: { id: /[a-zA-Z.0-9_\-\/]+/ } do
collection do collection do
get :pages get :pages
put ':id' => 'wikis#update' put ':id' => 'wikis#update'
...@@ -275,7 +279,7 @@ Gitlab::Application.routes.draw do ...@@ -275,7 +279,7 @@ Gitlab::Application.routes.draw do
end end
end end
resources :deploy_keys, constraints: {id: /\d+/} do resources :deploy_keys, constraints: { id: /\d+/ } do
member do member do
put :enable put :enable
put :disable put :disable
...@@ -294,16 +298,14 @@ Gitlab::Application.routes.draw do ...@@ -294,16 +298,14 @@ Gitlab::Application.routes.draw do
member do member do
# tree viewer logs # tree viewer logs
get 'logs_tree', constraints: { id: Gitlab::Regex.git_reference_regex } get 'logs_tree', constraints: { id: Gitlab::Regex.git_reference_regex }
get 'logs_tree/:path' => 'refs#logs_tree', get 'logs_tree/:path' => 'refs#logs_tree', as: :logs_file, constraints: {
as: :logs_file,
constraints: {
id: Gitlab::Regex.git_reference_regex, id: Gitlab::Regex.git_reference_regex,
path: /.*/ path: /.*/
} }
end end
end end
resources :merge_requests, constraints: {id: /\d+/}, except: [:destroy] do resources :merge_requests, constraints: { id: /\d+/ }, except: [:destroy] do
member do member do
get :diffs get :diffs
post :automerge post :automerge
...@@ -318,27 +320,27 @@ Gitlab::Application.routes.draw do ...@@ -318,27 +320,27 @@ Gitlab::Application.routes.draw do
end end
end end
resources :hooks, only: [:index, :create, :destroy], constraints: {id: /\d+/} do resources :hooks, only: [:index, :create, :destroy], constraints: { id: /\d+/ } do
member do member do
get :test get :test
end end
end end
resources :team, controller: 'team_members', only: [:index] resources :team, controller: 'team_members', only: [:index]
resources :milestones, except: [:destroy], constraints: {id: /\d+/} do resources :milestones, except: [:destroy], constraints: { id: /\d+/ } do
member do member do
put :sort_issues put :sort_issues
put :sort_merge_requests put :sort_merge_requests
end end
end end
resources :labels, constraints: {id: /\d+/} do resources :labels, constraints: { id: /\d+/ } do
collection do collection do
post :generate post :generate
end end
end end
resources :issues, constraints: {id: /\d+/}, except: [:destroy] do resources :issues, constraints: { id: /\d+/ }, except: [:destroy] do
collection do collection do
post :bulk_update post :bulk_update
end end
...@@ -355,7 +357,7 @@ Gitlab::Application.routes.draw do ...@@ -355,7 +357,7 @@ Gitlab::Application.routes.draw do
end end
end end
resources :notes, only: [:index, :create, :destroy, :update], constraints: {id: /\d+/} do resources :notes, only: [:index, :create, :destroy, :update], constraints: { id: /\d+/ } do
member do member do
delete :delete_attachment delete :delete_attachment
end end
...@@ -364,7 +366,7 @@ Gitlab::Application.routes.draw do ...@@ -364,7 +366,7 @@ Gitlab::Application.routes.draw do
end end
end end
get ':id' => 'namespaces#show', constraints: {id: /(?:[^.]|\.(?!atom$))+/, format: /atom/} get ':id' => 'namespaces#show', constraints: { id: /(?:[^.]|\.(?!atom$))+/, format: /atom/ }
root to: 'dashboard#show' root to: 'dashboard#show'
end end
...@@ -20,7 +20,7 @@ GET /groups ...@@ -20,7 +20,7 @@ GET /groups
] ]
``` ```
You can search for groups by name or path with: `/groups?search=Rails` You can search for groups by name or path, see below.
## Details of a group ## Details of a group
...@@ -32,7 +32,7 @@ GET /groups/:id ...@@ -32,7 +32,7 @@ GET /groups/:id
Parameters: Parameters:
- `id` (required) - The ID of a group - `id` (required) - The ID or path of a group
## New group ## New group
...@@ -58,7 +58,7 @@ POST /groups/:id/projects/:project_id ...@@ -58,7 +58,7 @@ POST /groups/:id/projects/:project_id
Parameters: Parameters:
- `id` (required) - The ID of a group - `id` (required) - The ID or path of a group
- `project_id` (required) - The ID of a project - `project_id` (required) - The ID of a project
## Remove group ## Remove group
...@@ -71,7 +71,27 @@ DELETE /groups/:id ...@@ -71,7 +71,27 @@ DELETE /groups/:id
Parameters: Parameters:
- `id` (required) - The ID of a user group - `id` (required) - The ID or path of a user group
## Search for group
Get all groups that match your string in their name or path.
```
GET /groups?search=foobar
```
```json
[
{
"id": 1,
"name": "Foobar Group",
"path": "foo-bar",
"owner_id": 18,
"description": "An interesting group"
}
]
```
## Group members ## Group members
...@@ -128,7 +148,7 @@ POST /groups/:id/members ...@@ -128,7 +148,7 @@ POST /groups/:id/members
Parameters: Parameters:
- `id` (required) - The ID of a group - `id` (required) - The ID or path of a group
- `user_id` (required) - The ID of a user to add - `user_id` (required) - The ID of a user to add
- `access_level` (required) - Project access level - `access_level` (required) - Project access level
...@@ -142,5 +162,5 @@ DELETE /groups/:id/members/:user_id ...@@ -142,5 +162,5 @@ DELETE /groups/:id/members/:user_id
Parameters: Parameters:
- `id` (required) - The ID of a user group - `id` (required) - The ID or path of a user group
- `user_id` (required) - The ID of a group member - `user_id` (required) - The ID of a group member
...@@ -278,7 +278,7 @@ We recommend using a PostgreSQL database. For MySQL check [MySQL setup guide](da ...@@ -278,7 +278,7 @@ We recommend using a PostgreSQL database. For MySQL check [MySQL setup guide](da
GitLab Shell is an SSH access and repository management software developed specially for GitLab. GitLab Shell is an SSH access and repository management software developed specially for GitLab.
# Run the installation task for gitlab-shell (replace `REDIS_URL` if needed): # Run the installation task for gitlab-shell (replace `REDIS_URL` if needed):
sudo -u git -H bundle exec rake gitlab:shell:install[v2.4.1] REDIS_URL=unix:/var/run/redis/redis.sock RAILS_ENV=production sudo -u git -H bundle exec rake gitlab:shell:install[v2.4.2] REDIS_URL=unix:/var/run/redis/redis.sock RAILS_ENV=production
# By default, the gitlab-shell config is generated from your main GitLab config. # By default, the gitlab-shell config is generated from your main GitLab config.
# You can review (and modify) the gitlab-shell config as follows: # You can review (and modify) the gitlab-shell config as follows:
......
...@@ -19,19 +19,26 @@ your repositories are located by looking at `config/gitlab.yml` under the `gitla ...@@ -19,19 +19,26 @@ your repositories are located by looking at `config/gitlab.yml` under the `gitla
New folder needs to have git user ownership and read/write/execute access for git user and its group: New folder needs to have git user ownership and read/write/execute access for git user and its group:
``` ```
$ mkdir new_group sudo -u git mkdir /var/opt/gitlab/git-data/repositories/new_group
$ chown git:git new_group
$ chmod 770 new_group
``` ```
If you are using an installation from source, replace `/var/opt/gitlab/git-data`
with `/home/git`.
### Copy your bare repositories inside this newly created folder: ### Copy your bare repositories inside this newly created folder:
``` ```
$ cp -r /old/git/foo.git/ /home/git/repositories/new_group/ sudo cp -r /old/git/foo.git /var/opt/gitlab/git-data/repositories/new_group/
# Do this once when you are done copying git repositories
sudo chown -R git:git /var/opt/gitlab/git-data/repositories/new_group/
``` ```
`foo.git` needs to be owned by the git user and git users group. `foo.git` needs to be owned by the git user and git users group.
If you are using an installation from source, replace `/var/opt/gitlab/git-data`
with `/home/git`.
### Run the command below depending on your type of installation: ### Run the command below depending on your type of installation:
#### Omnibus Installation #### Omnibus Installation
......
...@@ -89,6 +89,9 @@ sudo apt-get install logrotate ...@@ -89,6 +89,9 @@ sudo apt-get install logrotate
# Install pkg-config and cmake, which is needed for the latest versions of rugged # Install pkg-config and cmake, which is needed for the latest versions of rugged
sudo apt-get install pkg-config cmake sudo apt-get install pkg-config cmake
# Install Kerberos header files, which are needed for GitLab EE Kerberos support
sudo apt-get install libkrb5-dev
``` ```
## 5. Configure Redis to use sockets ## 5. Configure Redis to use sockets
......
...@@ -37,7 +37,7 @@ sudo -u git -H git checkout 7-7-stable-ee ...@@ -37,7 +37,7 @@ sudo -u git -H git checkout 7-7-stable-ee
```bash ```bash
cd /home/git/gitlab-shell cd /home/git/gitlab-shell
sudo -u git -H git fetch sudo -u git -H git fetch
sudo -u git -H git checkout v2.4.1 sudo -u git -H git checkout v2.4.2
``` ```
### 4. Install libs, migrations, etc. ### 4. Install libs, migrations, etc.
......
...@@ -10,3 +10,4 @@ ...@@ -10,3 +10,4 @@
- [Migrating from SVN to GitLab](migrating_from_svn.md) - [Migrating from SVN to GitLab](migrating_from_svn.md)
- [Project importing from GitHub to GitLab](import_projects_from_github.md) - [Project importing from GitHub to GitLab](import_projects_from_github.md)
- [Protected branches](protected_branches.md) - [Protected branches](protected_branches.md)
- [Web Editor](web_editor.md)
# GitLab Web Editor
In GitLab you can create new files and edit existing files using our web editor.
This is especially useful if you don't have access to a command line or you just want to do a quick fix.
You can easily access the web editor, depending on the context.
Let's start from newly created project.
Click on `Add a file`
to create the first file and open it in the web editor.
![web editor 1](web_editor/empty_project.png)
Fill in a file name, some content, a commit message and press the commit button.
The file will be saved to the repository.
![web editor 2](web_editor/new_file.png)
You can edit any text file in a repository by pressing the edit button, when
viewing the file.
![web editor 3](web_editor/show_file.png)
Editing a file is almost the same as creating a new file,
with as addition the ability to preview your changes in a separate tab.
![web editor 3](web_editor/edit_file.png)
...@@ -11,7 +11,7 @@ RUN apt-get update -q \ ...@@ -11,7 +11,7 @@ RUN apt-get update -q \
# If the Omnibus package version below is outdated please contribute a merge request to update it. # If the Omnibus package version below is outdated please contribute a merge request to update it.
# If you run GitLab Enterprise Edition point it to a location where you have downloaded it. # If you run GitLab Enterprise Edition point it to a location where you have downloaded it.
RUN TMP_FILE=$(mktemp); \ RUN TMP_FILE=$(mktemp); \
wget -q -O $TMP_FILE https://downloads-packages.s3.amazonaws.com/ubuntu-14.04/gitlab_7.7.1-omnibus.5.4.1.ci-1_amd64.deb \ wget -q -O $TMP_FILE https://downloads-packages.s3.amazonaws.com/ubuntu-14.04/gitlab_7.7.2-omnibus.5.4.2.ci-1_amd64.deb \
&& dpkg -i $TMP_FILE \ && dpkg -i $TMP_FILE \
&& rm -f $TMP_FILE && rm -f $TMP_FILE
......
...@@ -34,7 +34,7 @@ Feature: Project Source Browse Files ...@@ -34,7 +34,7 @@ Feature: Project Source Browse Files
Then I am redirected to the new file Then I am redirected to the new file
And I should see its new content And I should see its new content
@javascript @javascript @tricky
Scenario: I can create file in empty repo Scenario: I can create file in empty repo
Given I own an empty project Given I own an empty project
And I visit my empty project page And I visit my empty project page
......
...@@ -6,7 +6,7 @@ module API ...@@ -6,7 +6,7 @@ module API
version 'v3', using: :path version 'v3', using: :path
rescue_from ActiveRecord::RecordNotFound do rescue_from ActiveRecord::RecordNotFound do
rack_response({'message' => '404 Not found'}.to_json, 404) rack_response({ 'message' => '404 Not found' }.to_json, 404)
end end
rescue_from :all do |exception| rescue_from :all do |exception|
...@@ -19,7 +19,7 @@ module API ...@@ -19,7 +19,7 @@ module API
message << " " << trace.join("\n ") message << " " << trace.join("\n ")
API.logger.add Logger::FATAL, message API.logger.add Logger::FATAL, message
rack_response({'message' => '500 Internal Server Error'}, 500) rack_response({ 'message' => '500 Internal Server Error' }, 500)
end end
format :json format :json
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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