mirror of
https://github.com/wahyd4/gitlabhq.git
synced 2026-08-21 18:46:10 +10:00
Merge branch 'master' of dev.gitlab.org:gitlab/gitlabhq into ce-into-ee
Conflicts: Gemfile.lock app/helpers/tab_helper.rb config/routes.rb db/schema.rb
This commit is contained in:
+1006
File diff suppressed because it is too large
Load Diff
@@ -8,7 +8,7 @@ v 7.8.0
|
||||
- Better UI for project services page
|
||||
- Cleaner UI for web editor
|
||||
- Add diff syntax highlighting in email-on-push service notifications (Hannes Rosenögger)
|
||||
-
|
||||
- Add API endpoint to fetch all changes on a MergeRequest (Jeroen van Baarsen)
|
||||
-
|
||||
-
|
||||
- Allow more variations for commit messages closing issues (Julien Bianchi and Hannes Rosenögger)
|
||||
@@ -25,11 +25,13 @@ v 7.8.0
|
||||
- Upgrade Sidekiq gem to version 3.3.0
|
||||
- Stop git zombie creation during force push check
|
||||
- Show success/error messages for test setting button in services
|
||||
-
|
||||
- Added Rubocop for code style checks
|
||||
- Fix commits pagination
|
||||
-
|
||||
-
|
||||
-
|
||||
- Async load a branch information at the commit page
|
||||
- Disable blacklist validation for project names
|
||||
- Allow configuring protection of the default branch upon first push (Marco Wessel)
|
||||
-
|
||||
-
|
||||
- Add a commit calendar to the user profile (Hannes Rosenögger)
|
||||
-
|
||||
@@ -42,7 +44,7 @@ v 7.8.0
|
||||
- Password reset token validity increased from 2 hours to 2 days since it is also send on account creation.
|
||||
-
|
||||
-
|
||||
-
|
||||
- Enable raw image paste from clipboard, currently Chrome only (Marco Cyriacks)
|
||||
-
|
||||
-
|
||||
- Add action property to merge request hook (Julien Bianchi)
|
||||
@@ -53,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)
|
||||
-
|
||||
-
|
||||
-
|
||||
-
|
||||
- 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)
|
||||
-
|
||||
-
|
||||
-
|
||||
- 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 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
|
||||
- Improve mention autocomplete performance
|
||||
|
||||
@@ -1 +1 @@
|
||||
2.4.1
|
||||
2.4.2
|
||||
|
||||
@@ -208,8 +208,6 @@ group :development do
|
||||
gem 'better_errors'
|
||||
gem 'binding_of_caller'
|
||||
|
||||
gem 'rails_best_practices'
|
||||
|
||||
# Docs generator
|
||||
gem "sdoc"
|
||||
|
||||
@@ -219,11 +217,12 @@ end
|
||||
|
||||
group :development, :test do
|
||||
gem 'coveralls', require: false
|
||||
gem 'rubocop', '0.28.0', require: false
|
||||
# gem 'rails-dev-tweaks'
|
||||
gem 'spinach-rails'
|
||||
gem "rspec-rails"
|
||||
gem "capybara", '~> 2.2.1'
|
||||
gem "pry"
|
||||
gem "pry-rails"
|
||||
gem "awesome_print"
|
||||
gem "database_cleaner"
|
||||
gem "launchy"
|
||||
@@ -256,7 +255,7 @@ end
|
||||
|
||||
group :test do
|
||||
gem "simplecov", require: false
|
||||
gem "shoulda-matchers", "~> 2.1.0"
|
||||
gem "shoulda-matchers", "~> 2.7.0"
|
||||
gem 'email_spec'
|
||||
gem "webmock"
|
||||
gem 'test_after_commit'
|
||||
|
||||
+20
-18
@@ -37,6 +37,9 @@ GEM
|
||||
rake (>= 0.8.7)
|
||||
arel (5.0.1.20140414130214)
|
||||
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)
|
||||
awesome_print (1.2.0)
|
||||
axiom-types (0.0.5)
|
||||
@@ -67,8 +70,6 @@ GEM
|
||||
timers (~> 4.0.0)
|
||||
charlock_holmes (0.6.9.4)
|
||||
cliver (0.3.2)
|
||||
code_analyzer (0.4.3)
|
||||
sexp_processor
|
||||
coderay (1.1.0)
|
||||
coercible (1.0.0)
|
||||
descendants_tracker (~> 0.0.1)
|
||||
@@ -354,6 +355,8 @@ GEM
|
||||
org-ruby (0.9.12)
|
||||
rubypants (~> 0.2)
|
||||
orm_adapter (0.5.0)
|
||||
parser (2.2.0.2)
|
||||
ast (>= 1.1, < 3.0)
|
||||
pg (0.15.1)
|
||||
phantomjs (1.9.2.0)
|
||||
poltergeist (1.5.1)
|
||||
@@ -363,10 +366,13 @@ GEM
|
||||
websocket-driver (>= 0.2.0)
|
||||
polyglot (0.3.4)
|
||||
posix-spawn (0.3.9)
|
||||
powerpack (0.0.9)
|
||||
pry (0.9.12.4)
|
||||
coderay (~> 1.0)
|
||||
method_source (~> 0.8)
|
||||
slop (~> 3.4)
|
||||
pry-rails (0.3.2)
|
||||
pry (>= 0.9.10)
|
||||
pyu-ruby-sasl (0.0.3.3)
|
||||
quiet_assets (1.0.2)
|
||||
railties (>= 3.1, < 5.0)
|
||||
@@ -403,20 +409,12 @@ GEM
|
||||
sprockets-rails (~> 2.0)
|
||||
rails_autolink (1.1.6)
|
||||
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)
|
||||
actionpack (= 4.1.1)
|
||||
activesupport (= 4.1.1)
|
||||
rake (>= 0.8.7)
|
||||
thor (>= 0.18.1, < 2.0)
|
||||
rainbow (2.0.0)
|
||||
raindrops (0.13.0)
|
||||
rake (10.3.2)
|
||||
raphael-rails (2.1.2)
|
||||
@@ -447,7 +445,6 @@ GEM
|
||||
redis (>= 2.2)
|
||||
ref (1.0.5)
|
||||
request_store (1.0.5)
|
||||
require_all (1.3.2)
|
||||
rest-client (1.6.7)
|
||||
mime-types (>= 1.16)
|
||||
rinku (1.7.3)
|
||||
@@ -467,7 +464,13 @@ GEM
|
||||
rspec-core (~> 2.14.0)
|
||||
rspec-expectations (~> 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)
|
||||
rubypants (0.2.0)
|
||||
rugged (0.21.2)
|
||||
@@ -495,8 +498,7 @@ GEM
|
||||
semantic-ui-sass (1.8.0.0)
|
||||
sass (~> 3.2)
|
||||
settingslogic (2.0.9)
|
||||
sexp_processor (4.4.0)
|
||||
shoulda-matchers (2.1.0)
|
||||
shoulda-matchers (2.7.0)
|
||||
activesupport (>= 3.0.0)
|
||||
sidekiq (3.3.0)
|
||||
celluloid (>= 0.16.0)
|
||||
@@ -700,7 +702,7 @@ DEPENDENCIES
|
||||
org-ruby (= 0.9.12)
|
||||
pg
|
||||
poltergeist (~> 1.5.1)
|
||||
pry
|
||||
pry-rails
|
||||
quiet_assets (~> 1.0.1)
|
||||
rack-attack
|
||||
rack-cors
|
||||
@@ -708,7 +710,6 @@ DEPENDENCIES
|
||||
rack-oauth2 (~> 1.0.5)
|
||||
rails (~> 4.1.0)
|
||||
rails_autolink (~> 1.1)
|
||||
rails_best_practices
|
||||
raphael-rails (~> 2.1.2)
|
||||
rb-fsevent
|
||||
rb-inotify
|
||||
@@ -717,6 +718,7 @@ DEPENDENCIES
|
||||
redis-rails
|
||||
request_store
|
||||
rspec-rails
|
||||
rubocop (= 0.28.0)
|
||||
rugments
|
||||
sanitize (~> 2.0)
|
||||
sass-rails (~> 4.0.2)
|
||||
@@ -725,7 +727,7 @@ DEPENDENCIES
|
||||
select2-rails
|
||||
semantic-ui-sass (~> 1.8.0)
|
||||
settingslogic
|
||||
shoulda-matchers (~> 2.1.0)
|
||||
shoulda-matchers (~> 2.7.0)
|
||||
sidekiq (~> 3.3)
|
||||
sidetiq (= 0.6.3)
|
||||
simplecov
|
||||
|
||||
@@ -9,8 +9,6 @@ class @calendar
|
||||
cal.init
|
||||
itemName: ["commit"]
|
||||
data: timestamps
|
||||
domain: "year"
|
||||
subDomain: "month"
|
||||
start: new Date(starting_year, starting_month)
|
||||
domainLabelFormat: "%b"
|
||||
id: "cal-heatmap"
|
||||
|
||||
@@ -13,6 +13,8 @@ class @DropzoneInput
|
||||
|
||||
form_textarea = $(form).find("textarea.markdown-area")
|
||||
form_textarea.wrap "<div class=\"div-dropzone\"></div>"
|
||||
form_textarea.bind 'paste', (event) =>
|
||||
handlePaste(event)
|
||||
|
||||
form_dropzone = $(form).find('.div-dropzone')
|
||||
form_dropzone.parent().addClass "div-dropzone-wrapper"
|
||||
@@ -133,24 +135,17 @@ class @DropzoneInput
|
||||
formatLink = (str) ->
|
||||
""
|
||||
|
||||
handlePaste = (e) ->
|
||||
e.preventDefault()
|
||||
my_event = e.originalEvent
|
||||
handlePaste = (event) ->
|
||||
pasteEvent = event.originalEvent
|
||||
if pasteEvent.clipboardData and pasteEvent.clipboardData.items
|
||||
image = isImage(pasteEvent)
|
||||
if image
|
||||
event.preventDefault()
|
||||
|
||||
if my_event.clipboardData and my_event.clipboardData.items
|
||||
processItem(my_event)
|
||||
|
||||
processItem = (e) ->
|
||||
image = isImage(e)
|
||||
if image
|
||||
filename = getFilename(e) or "image.png"
|
||||
text = "{{" + filename + "}}"
|
||||
pasteText(text)
|
||||
uploadFile image.getAsFile(), filename
|
||||
|
||||
else
|
||||
text = e.clipboardData.getData("text/plain")
|
||||
pasteText(text)
|
||||
filename = getFilename(pasteEvent) or "image.png"
|
||||
text = "{{" + filename + "}}"
|
||||
pasteText(text)
|
||||
uploadFile image.getAsFile(), filename
|
||||
|
||||
isImage = (data) ->
|
||||
i = 0
|
||||
|
||||
@@ -24,3 +24,18 @@ $ ->
|
||||
$(window).resize ->
|
||||
responsive_resize()
|
||||
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 @@
|
||||
&.s24 { margin-right: 4px; }
|
||||
}
|
||||
|
||||
&.avatar-tile {
|
||||
@include border-radius(0px);
|
||||
}
|
||||
|
||||
&.s16 { width: 16px; height: 16px; margin-right: 6px; }
|
||||
&.s24 { width: 24px; height: 24px; margin-right: 8px; }
|
||||
&.s26 { width: 26px; height: 26px; margin-right: 8px; }
|
||||
|
||||
@@ -97,7 +97,17 @@
|
||||
|
||||
.dash-project-avatar {
|
||||
float: left;
|
||||
|
||||
.avatar {
|
||||
margin-top: -8px;
|
||||
margin-left: -15px;
|
||||
@include border-radius(0px);
|
||||
}
|
||||
.identicon {
|
||||
line-height: 40px;
|
||||
}
|
||||
}
|
||||
|
||||
.dash-project-access-icon {
|
||||
float: left;
|
||||
margin-right: 5px;
|
||||
|
||||
@@ -40,12 +40,12 @@
|
||||
font-size: $code_font_size;
|
||||
.old {
|
||||
span.idiff {
|
||||
background-color: #F99;
|
||||
background-color: #f8cbcb;
|
||||
}
|
||||
}
|
||||
.new {
|
||||
span.idiff {
|
||||
background-color: #8F8;
|
||||
background-color: #a6f3a6;
|
||||
}
|
||||
}
|
||||
.unfold {
|
||||
@@ -84,7 +84,7 @@
|
||||
padding: 0px;
|
||||
border: none;
|
||||
background: #F5F5F5;
|
||||
color: #666;
|
||||
color: rgba(0,0,0,0.3);
|
||||
padding: 0px 5px;
|
||||
border-right: 1px solid #ccc;
|
||||
text-align: right;
|
||||
@@ -96,7 +96,7 @@
|
||||
float: left;
|
||||
width: 35px;
|
||||
font-weight: normal;
|
||||
color: #666;
|
||||
color: rgba(0,0,0,0.3);
|
||||
&:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
@@ -114,13 +114,13 @@
|
||||
.line_holder {
|
||||
&.old .old_line,
|
||||
&.old .new_line {
|
||||
background: #FCC;
|
||||
border-color: #E7BABA;
|
||||
background: #ffdddd;
|
||||
border-color: #f1c0c0;
|
||||
}
|
||||
&.new .old_line,
|
||||
&.new .new_line {
|
||||
background: #CFC;
|
||||
border-color: #B9ECB9;
|
||||
background: #dbffdb;
|
||||
border-color: #c1e9c1;
|
||||
}
|
||||
}
|
||||
.line_content {
|
||||
@@ -129,10 +129,10 @@
|
||||
padding: 0px 0.5em;
|
||||
border: none;
|
||||
&.new {
|
||||
background: #CFD;
|
||||
background: #eaffea;
|
||||
}
|
||||
&.old {
|
||||
background: #FDD;
|
||||
background: #ffecec;
|
||||
}
|
||||
&.matched {
|
||||
color: #ccc;
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
|
||||
|
||||
.page-with-sidebar {
|
||||
background: #F5F5F5;
|
||||
|
||||
@@ -101,9 +99,7 @@
|
||||
}
|
||||
|
||||
@mixin expanded-sidebar {
|
||||
.page-with-sidebar {
|
||||
padding-left: $sidebar_width;
|
||||
}
|
||||
padding-left: $sidebar_width;
|
||||
|
||||
.sidebar-wrapper {
|
||||
width: $sidebar_width;
|
||||
@@ -122,9 +118,7 @@
|
||||
}
|
||||
|
||||
@mixin folded-sidebar {
|
||||
.page-with-sidebar {
|
||||
padding-left: 50px;
|
||||
}
|
||||
padding-left: 50px;
|
||||
|
||||
.sidebar-wrapper {
|
||||
width: 52px;
|
||||
@@ -150,10 +144,33 @@
|
||||
}
|
||||
}
|
||||
|
||||
.collapse-nav a {
|
||||
position: fixed;
|
||||
bottom: 15px;
|
||||
padding: 10px;
|
||||
background: #DDD;
|
||||
}
|
||||
|
||||
@media (max-width: $screen-md-max) {
|
||||
@include folded-sidebar;
|
||||
.page-sidebar-collapsed {
|
||||
@include folded-sidebar;
|
||||
}
|
||||
|
||||
.page-sidebar-expanded {
|
||||
@include folded-sidebar;
|
||||
}
|
||||
|
||||
.collapse-nav {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
@media(min-width: $screen-md-max) {
|
||||
@include expanded-sidebar;
|
||||
.page-sidebar-collapsed {
|
||||
@include folded-sidebar;
|
||||
}
|
||||
|
||||
.page-sidebar-expanded {
|
||||
@include expanded-sidebar;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,7 +81,7 @@ ul.notes {
|
||||
.diff-file .notes_holder {
|
||||
font-size: 13px;
|
||||
line-height: 18px;
|
||||
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
font-family: $regular_font;
|
||||
|
||||
td {
|
||||
border: 1px solid #ddd;
|
||||
|
||||
@@ -22,6 +22,7 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController
|
||||
def application_setting_params
|
||||
params.require(:application_setting).permit(
|
||||
:default_projects_limit,
|
||||
:default_branch_protection,
|
||||
:signup_enabled,
|
||||
:signin_enabled,
|
||||
:gravatar_enabled,
|
||||
|
||||
@@ -23,7 +23,7 @@ class GithubImportsController < ApplicationController
|
||||
end
|
||||
|
||||
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
|
||||
end
|
||||
|
||||
@@ -58,7 +58,7 @@ class GithubImportsController < ApplicationController
|
||||
|
||||
def octo_client
|
||||
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
|
||||
|
||||
def github_auth
|
||||
|
||||
@@ -15,4 +15,3 @@ class NamespacesController < ApplicationController
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -59,8 +59,7 @@ class Projects::BlobController < Projects::ApplicationController
|
||||
|
||||
def preview
|
||||
@content = params[:content]
|
||||
diffy = Diffy::Diff.new(@blob.data, @content, diff: '-U 3',
|
||||
include_diff_info: true)
|
||||
diffy = Diffy::Diff.new(@blob.data, @content, diff: '-U 3', include_diff_info: true)
|
||||
@diff_lines = Gitlab::Diff::Parser.new.parse(diffy.diff.scan(/.*\n/))
|
||||
|
||||
render layout: false
|
||||
|
||||
@@ -11,8 +11,6 @@ class Projects::CommitController < Projects::ApplicationController
|
||||
return git_not_found! unless @commit
|
||||
|
||||
@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
|
||||
@note = @project.build_commit_note(commit)
|
||||
@notes_count = @project.notes.for_commit_id(commit.id).count
|
||||
@@ -31,6 +29,12 @@ class Projects::CommitController < Projects::ApplicationController
|
||||
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
|
||||
@commit ||= @project.repository.commit(params[:id])
|
||||
end
|
||||
|
||||
@@ -35,4 +35,3 @@ class Projects::RawController < Projects::ApplicationController
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -31,10 +31,10 @@ class Projects::RefsController < Projects::ApplicationController
|
||||
|
||||
def logs_tree
|
||||
@offset = if params[:offset].present?
|
||||
params[:offset].to_i
|
||||
else
|
||||
0
|
||||
end
|
||||
params[:offset].to_i
|
||||
else
|
||||
0
|
||||
end
|
||||
|
||||
@limit = 25
|
||||
|
||||
|
||||
@@ -16,16 +16,16 @@ class Projects::WikisController < Projects::ApplicationController
|
||||
if @page
|
||||
render 'show'
|
||||
elsif file = @project_wiki.find_file(params[:id], params[:version_id])
|
||||
if file.on_disk?
|
||||
send_file file.on_disk_path, disposition: 'inline'
|
||||
else
|
||||
send_data(
|
||||
file.raw_data,
|
||||
type: file.mime_type,
|
||||
disposition: 'inline',
|
||||
filename: file.name
|
||||
)
|
||||
end
|
||||
if file.on_disk?
|
||||
send_file file.on_disk_path, disposition: 'inline'
|
||||
else
|
||||
send_data(
|
||||
file.raw_data,
|
||||
type: file.mime_type,
|
||||
disposition: 'inline',
|
||||
filename: file.name
|
||||
)
|
||||
end
|
||||
else
|
||||
return render('empty') unless can?(current_user, :write_wiki, @project)
|
||||
@page = WikiPage.new(@project_wiki)
|
||||
|
||||
@@ -27,7 +27,7 @@ class SnippetsController < ApplicationController
|
||||
@snippets = SnippetsFinder.new.execute(current_user, {
|
||||
filter: :by_user,
|
||||
user: @user,
|
||||
scope: params[:scope]}).
|
||||
scope: params[:scope] }).
|
||||
page(params[:page]).per(20)
|
||||
|
||||
if @user == current_user
|
||||
|
||||
@@ -1,14 +1,9 @@
|
||||
class UsersController < ApplicationController
|
||||
skip_before_filter :authenticate_user!, only: [:show, :activities]
|
||||
skip_before_filter :authenticate_user!
|
||||
before_filter :set_user
|
||||
layout :determine_layout
|
||||
|
||||
def show
|
||||
@user = User.find_by_username!(params[:username])
|
||||
|
||||
unless current_user || @user.public_profile?
|
||||
return authenticate_user!
|
||||
end
|
||||
|
||||
# Projects user can view
|
||||
visible_projects = ProjectsFinder.new.execute(current_user)
|
||||
authorized_projects_ids = visible_projects.pluck(:id)
|
||||
@@ -25,19 +20,22 @@ class UsersController < ApplicationController
|
||||
|
||||
@title = @user.name
|
||||
|
||||
# Get user repositories and collect timestamps for commits
|
||||
user_repositories = visible_projects.map(&:repository)
|
||||
calendar = Gitlab::CommitsCalendar.new(user_repositories, @user)
|
||||
@timestamps = calendar.timestamps
|
||||
@starting_year = (Time.now - 1.year).strftime("%Y")
|
||||
@starting_month = Date.today.strftime("%m").to_i
|
||||
|
||||
respond_to do |format|
|
||||
format.html
|
||||
format.atom { render layout: false }
|
||||
end
|
||||
end
|
||||
|
||||
def calendar
|
||||
visible_projects = ProjectsFinder.new.execute(current_user)
|
||||
calendar = Gitlab::CommitsCalendar.new(visible_projects, @user)
|
||||
@timestamps = calendar.timestamps
|
||||
@starting_year = calendar.starting_year
|
||||
@starting_month = calendar.starting_month
|
||||
|
||||
render 'calendar', layout: false
|
||||
end
|
||||
|
||||
def determine_layout
|
||||
if current_user
|
||||
'navless'
|
||||
@@ -45,4 +43,14 @@ class UsersController < ApplicationController
|
||||
'public_users'
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_user
|
||||
@user = User.find_by_username!(params[:username])
|
||||
|
||||
unless current_user || @user.public_profile?
|
||||
return authenticate_user!
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
+13
-12
@@ -7,18 +7,19 @@ class NotesFinder
|
||||
# Default to 0 to remain compatible with old clients
|
||||
last_fetched_at = Time.at(params.fetch(:last_fetched_at, 0).to_i)
|
||||
|
||||
notes = case target_type
|
||||
when "commit"
|
||||
project.notes.for_commit_id(target_id).not_inline.fresh
|
||||
when "issue"
|
||||
project.issues.find(target_id).notes.inc_author.fresh
|
||||
when "merge_request"
|
||||
project.merge_requests.find(target_id).mr_and_commit_notes.inc_author.fresh
|
||||
when "snippet", "project_snippet"
|
||||
project.snippets.find(target_id).notes.fresh
|
||||
else
|
||||
raise 'invalid target_type'
|
||||
end
|
||||
notes =
|
||||
case target_type
|
||||
when "commit"
|
||||
project.notes.for_commit_id(target_id).not_inline.fresh
|
||||
when "issue"
|
||||
project.issues.find(target_id).notes.inc_author.fresh
|
||||
when "merge_request"
|
||||
project.merge_requests.find(target_id).mr_and_commit_notes.inc_author.fresh
|
||||
when "snippet", "project_snippet"
|
||||
project.snippets.find(target_id).notes.fresh
|
||||
else
|
||||
raise 'invalid target_type'
|
||||
end
|
||||
|
||||
# Use overlapping intervals to avoid worrying about race conditions
|
||||
notes.where('updated_at > ?', last_fetched_at - FETCH_OVERLAP)
|
||||
|
||||
@@ -40,7 +40,7 @@ class SnippetsFinder
|
||||
when 'are_public' then
|
||||
snippets.are_public
|
||||
else
|
||||
snippets
|
||||
snippets
|
||||
end
|
||||
else
|
||||
snippets.public_and_internal
|
||||
|
||||
@@ -75,10 +75,10 @@ module ApplicationHelper
|
||||
options[:class] ||= ''
|
||||
options[:class] << ' identicon'
|
||||
bg_key = project.id % 7
|
||||
style = "background-color: ##{ allowed_colors.values[bg_key] }; color: #555"
|
||||
|
||||
content_tag(:div, class: options[:class],
|
||||
style: "background-color: ##{ allowed_colors.values[bg_key] }; color: #555") do
|
||||
project.name[0, 1].upcase
|
||||
content_tag(:div, class: options[:class], style: style) do
|
||||
project.name[0, 1].upcase
|
||||
end
|
||||
end
|
||||
|
||||
@@ -247,15 +247,6 @@ module ApplicationHelper
|
||||
Gitlab::MarkdownHelper.gitlab_markdown?(filename)
|
||||
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)
|
||||
begin
|
||||
uri = URI(options)
|
||||
@@ -324,4 +315,12 @@ module ApplicationHelper
|
||||
profile_key_path(key)
|
||||
end
|
||||
end
|
||||
|
||||
def nav_sidebar_class
|
||||
if nav_menu_collapsed?
|
||||
"page-sidebar-collapsed"
|
||||
else
|
||||
"page-sidebar-expanded"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -65,8 +65,7 @@ module CommitsHelper
|
||||
branches.sort.map do |branch|
|
||||
link_to(project_tree_path(project, branch)) do
|
||||
content_tag :span, class: 'label label-gray' do
|
||||
content_tag(:i, nil, class: 'fa fa-code-fork') + ' ' +
|
||||
branch
|
||||
icon('code-fork') + ' ' + branch
|
||||
end
|
||||
end
|
||||
end.join(" ").html_safe
|
||||
@@ -78,8 +77,7 @@ module CommitsHelper
|
||||
sorted.map do |tag|
|
||||
link_to(project_commits_path(project, project.repository.find_tag(tag).name)) do
|
||||
content_tag :span, class: 'label label-gray' do
|
||||
content_tag(:i, nil, class: 'fa fa-tag') + ' ' +
|
||||
tag
|
||||
icon('tag') + ' ' + tag
|
||||
end
|
||||
end
|
||||
end.join(" ").html_safe
|
||||
@@ -114,12 +112,13 @@ module CommitsHelper
|
||||
person_name = user.nil? ? source_name : user.name
|
||||
person_email = user.nil? ? source_email : user.email
|
||||
|
||||
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: "")
|
||||
%Q{#{avatar} <span class="commit-#{options[:source]}-name">#{person_name}</span>}
|
||||
else
|
||||
person_name
|
||||
end
|
||||
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: "")
|
||||
%Q{#{avatar} <span class="commit-#{options[:source]}-name">#{person_name}</span>}
|
||||
else
|
||||
person_name
|
||||
end
|
||||
|
||||
options = {
|
||||
class: "commit-#{options[:source]}-link has_tooltip",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
module CompareHelper
|
||||
def compare_to_mr_button?
|
||||
@project.merge_requests_enabled &&
|
||||
params[:from].present? &&
|
||||
params[:from].present? &&
|
||||
params[:to].present? &&
|
||||
@repository.branch_names.include?(params[:from]) &&
|
||||
@repository.branch_names.include?(params[:to]) &&
|
||||
@@ -10,6 +10,6 @@ module CompareHelper
|
||||
end
|
||||
|
||||
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
|
||||
|
||||
@@ -31,7 +31,7 @@ module EmailsHelper
|
||||
end
|
||||
|
||||
def add_email_highlight_css
|
||||
Rugments::Themes::Github.render(:scope => '.highlight')
|
||||
Rugments::Themes::Github.render(scope: '.highlight')
|
||||
end
|
||||
|
||||
def color_email_diff(diffcontent)
|
||||
|
||||
@@ -27,18 +27,17 @@ module EventsHelper
|
||||
|
||||
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
|
||||
content_tag(:i, nil, class: icon_for_event[key]) +
|
||||
content_tag(:span, ' ' + tooltip)
|
||||
icon(icon_for_event[key]) + content_tag(:span, ' ' + tooltip)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def icon_for_event
|
||||
{
|
||||
EventFilter.push => 'fa fa-upload',
|
||||
EventFilter.merged => 'fa fa-check-square-o',
|
||||
EventFilter.comments => 'fa fa-comments',
|
||||
EventFilter.team => 'fa fa-user',
|
||||
EventFilter.push => 'upload',
|
||||
EventFilter.merged => 'check-square-o',
|
||||
EventFilter.comments => 'comments',
|
||||
EventFilter.team => 'user',
|
||||
}
|
||||
end
|
||||
|
||||
|
||||
@@ -1,21 +1,39 @@
|
||||
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)
|
||||
if value.to_s == "true"
|
||||
content_tag :i, nil, class: 'fa fa-circle cgreen'
|
||||
icon('circle', class: 'cgreen')
|
||||
else
|
||||
content_tag :i, nil, class: 'fa fa-power-off clgray'
|
||||
icon('power-off', class: 'clgray')
|
||||
end
|
||||
end
|
||||
|
||||
def public_icon
|
||||
content_tag :i, nil, class: 'fa fa-globe'
|
||||
icon('globe')
|
||||
end
|
||||
|
||||
def internal_icon
|
||||
content_tag :i, nil, class: 'fa fa-shield'
|
||||
icon('shield')
|
||||
end
|
||||
|
||||
def private_icon
|
||||
content_tag :i, nil, class: 'fa fa-lock'
|
||||
icon('lock')
|
||||
end
|
||||
end
|
||||
|
||||
@@ -49,7 +49,7 @@ module IssuesHelper
|
||||
ts << capture_haml do
|
||||
haml_tag :span do
|
||||
haml_concat '·'
|
||||
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')
|
||||
end
|
||||
end
|
||||
|
||||
@@ -15,11 +15,13 @@ module MergeRequestsHelper
|
||||
end
|
||||
|
||||
def new_mr_from_push_event(event, target_project)
|
||||
return :merge_request => {
|
||||
source_project_id: event.project.id,
|
||||
target_project_id: target_project.id,
|
||||
source_branch: event.branch_name,
|
||||
target_branch: target_project.repository.root_ref
|
||||
return {
|
||||
merge_request: {
|
||||
source_project_id: event.project.id,
|
||||
target_project_id: target_project.id,
|
||||
source_branch: event.branch_name,
|
||||
target_branch: target_project.repository.root_ref
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
module NavHelper
|
||||
def nav_menu_collapsed?
|
||||
cookies[:collapsed_nav] == 'true'
|
||||
end
|
||||
end
|
||||
@@ -1,5 +1,5 @@
|
||||
module NotesHelper
|
||||
# Helps to distinguish e.g. commit notes in mr notes list
|
||||
# Helps to distinguish e.g. commit notes in mr notes list
|
||||
def note_for_main_target?(note)
|
||||
(@noteable.class.name == note.noteable_type && !note.for_diff_line?)
|
||||
end
|
||||
@@ -22,7 +22,7 @@ module NotesHelper
|
||||
ts << capture_haml do
|
||||
haml_tag :span do
|
||||
haml_concat '·'
|
||||
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')
|
||||
end
|
||||
end
|
||||
@@ -57,7 +57,7 @@ module NotesHelper
|
||||
button_tag(class: 'btn add-diff-note js-add-diff-note-button',
|
||||
data: data,
|
||||
title: 'Add a comment to this line') do
|
||||
content_tag :i, nil, class: 'fa fa-comment-o'
|
||||
icon('comment-o')
|
||||
end
|
||||
end
|
||||
|
||||
@@ -74,7 +74,7 @@ module NotesHelper
|
||||
|
||||
button_tag class: 'btn reply-btn js-discussion-reply-button',
|
||||
data: data, title: 'Add a reply' do
|
||||
link_text = content_tag(:i, nil, class: 'fa fa-comment')
|
||||
link_text = icon('comment')
|
||||
link_text << ' Reply'
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
module NotificationsHelper
|
||||
def notification_icon(notification)
|
||||
if notification.disabled?
|
||||
content_tag :i, nil, class: 'fa fa-volume-off ns-mute'
|
||||
icon('volume-off', class: 'ns-mute')
|
||||
elsif notification.participating?
|
||||
content_tag :i, nil, class: 'fa fa-volume-down ns-part'
|
||||
icon('volume-down', class: 'ns-part')
|
||||
elsif notification.watch?
|
||||
content_tag :i, nil, class: 'fa fa-volume-up ns-watch'
|
||||
icon('volume-up', class: 'ns-watch')
|
||||
else
|
||||
content_tag :i, nil, class: 'fa fa-circle-o ns-default'
|
||||
icon('circle-o', class: 'ns-default')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -83,7 +83,7 @@ module ProjectsHelper
|
||||
' Star'
|
||||
end
|
||||
|
||||
content_tag('i', ' ', class: 'fa fa-star') + toggle_text
|
||||
icon('star') + toggle_text
|
||||
end
|
||||
|
||||
count_html = content_tag('span', class: 'count') do
|
||||
@@ -95,7 +95,7 @@ module ProjectsHelper
|
||||
class: cls,
|
||||
method: :post,
|
||||
remote: true,
|
||||
data: {type: 'json'}
|
||||
data: { type: 'json' }
|
||||
}
|
||||
|
||||
|
||||
@@ -107,7 +107,7 @@ module ProjectsHelper
|
||||
end
|
||||
|
||||
def link_to_toggle_fork
|
||||
out = content_tag(:i, '', class: 'fa fa-code-fork')
|
||||
out = icon('code-fork')
|
||||
out << ' Fork'
|
||||
out << content_tag(:span, class: 'count') do
|
||||
@project.forks_count.to_s
|
||||
@@ -262,4 +262,3 @@ module ProjectsHelper
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -38,13 +38,8 @@ module TreeHelper
|
||||
#
|
||||
# type - String type of the tree item; either 'folder' or 'file'
|
||||
def tree_icon(type)
|
||||
icon_class = if type == 'folder'
|
||||
'fa fa-folder'
|
||||
else
|
||||
'fa fa-file-o'
|
||||
end
|
||||
|
||||
content_tag :i, nil, class: icon_class
|
||||
icon_class = type == 'folder' ? 'folder' : 'file-o'
|
||||
icon(icon_class)
|
||||
end
|
||||
|
||||
def tree_hex_class(content)
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# default_projects_limit :integer
|
||||
# default_branch_protection :integer
|
||||
# signup_enabled :boolean
|
||||
# signin_enabled :boolean
|
||||
# gravatar_enabled :boolean
|
||||
@@ -14,7 +15,8 @@
|
||||
#
|
||||
|
||||
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" },
|
||||
if: :home_page_url_column_exist
|
||||
|
||||
@@ -25,6 +27,7 @@ class ApplicationSetting < ActiveRecord::Base
|
||||
def self.create_from_defaults
|
||||
create(
|
||||
default_projects_limit: Settings.gitlab['default_projects_limit'],
|
||||
default_branch_protection: Settings.gitlab['default_branch_protection'],
|
||||
signup_enabled: Settings.gitlab['signup_enabled'],
|
||||
signin_enabled: Settings.gitlab['signin_enabled'],
|
||||
gravatar_enabled: Settings.gravatar['enabled'],
|
||||
|
||||
@@ -88,11 +88,12 @@ class Commit
|
||||
# cut off, ellipses (`&hellp;`) are prepended to the commit message.
|
||||
def description
|
||||
title_end = safe_message.index("\n")
|
||||
@description ||= if (!title_end && safe_message.length > 100) || (title_end && title_end > 100)
|
||||
"…".html_safe << safe_message[80..-1]
|
||||
else
|
||||
safe_message.split("\n", 2)[1].try(:chomp)
|
||||
end
|
||||
@description ||=
|
||||
if (!title_end && safe_message.length > 100) || (title_end && title_end > 100)
|
||||
"…".html_safe << safe_message[80..-1]
|
||||
else
|
||||
safe_message.split("\n", 2)[1].try(:chomp)
|
||||
end
|
||||
end
|
||||
|
||||
def description?
|
||||
|
||||
+1
-1
@@ -111,7 +111,7 @@ class Group < Namespace
|
||||
|
||||
class << self
|
||||
def search(query)
|
||||
where("LOWER(namespaces.name) LIKE :query", query: "%#{query.downcase}%")
|
||||
where("LOWER(namespaces.name) LIKE :query or LOWER(namespaces.path) LIKE :query", query: "%#{query.downcase}%")
|
||||
end
|
||||
|
||||
def sort(method)
|
||||
|
||||
@@ -44,11 +44,11 @@ class WebHook < ActiveRecord::Base
|
||||
}
|
||||
WebHook.post(post_url,
|
||||
body: data.to_json,
|
||||
headers: {"Content-Type" => "application/json"},
|
||||
headers: { "Content-Type" => "application/json" },
|
||||
verify: false,
|
||||
basic_auth: auth)
|
||||
end
|
||||
rescue SocketError, Errno::ECONNREFUSED, Net::OpenTimeout => e
|
||||
rescue SocketError, Errno::ECONNRESET, Errno::ECONNREFUSED, Net::OpenTimeout => e
|
||||
logger.error("WebHook Error => #{e}")
|
||||
false
|
||||
end
|
||||
|
||||
@@ -11,5 +11,5 @@
|
||||
class Identity < ActiveRecord::Base
|
||||
belongs_to :user
|
||||
|
||||
validates :extern_uid, allow_blank: true, uniqueness: {scope: :provider}
|
||||
validates :extern_uid, allow_blank: true, uniqueness: { scope: :provider }
|
||||
end
|
||||
|
||||
@@ -79,7 +79,7 @@ class MergeRequest < ActiveRecord::Base
|
||||
merge_request.save
|
||||
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.save
|
||||
end
|
||||
|
||||
+13
-8
@@ -20,15 +20,20 @@ class Namespace < ActiveRecord::Base
|
||||
belongs_to :owner, class_name: "User"
|
||||
|
||||
validates :owner, presence: true, unless: ->(n) { n.type == "Group" }
|
||||
validates :name, presence: true, uniqueness: true,
|
||||
length: { within: 0..255 },
|
||||
format: { with: Gitlab::Regex.name_regex,
|
||||
message: Gitlab::Regex.name_regex_message }
|
||||
validates :name,
|
||||
presence: true, uniqueness: true,
|
||||
length: { within: 0..255 },
|
||||
format: { with: Gitlab::Regex.name_regex,
|
||||
message: Gitlab::Regex.name_regex_message }
|
||||
|
||||
validates :description, length: { within: 0..255 }
|
||||
validates :path, uniqueness: { case_sensitive: false }, presence: true, length: { within: 1..255 },
|
||||
exclusion: { in: Gitlab::Blacklist.path },
|
||||
format: { with: Gitlab::Regex.path_regex,
|
||||
message: Gitlab::Regex.path_regex_message }
|
||||
validates :path,
|
||||
uniqueness: { case_sensitive: false },
|
||||
presence: true,
|
||||
length: { within: 1..255 },
|
||||
exclusion: { in: Gitlab::Blacklist.path },
|
||||
format: { with: Gitlab::Regex.path_regex,
|
||||
message: Gitlab::Regex.path_regex_message }
|
||||
|
||||
delegate :name, to: :owner, allow_nil: true, prefix: true
|
||||
|
||||
|
||||
+15
-12
@@ -14,7 +14,7 @@
|
||||
# merge_requests_enabled :boolean default(TRUE), not null
|
||||
# wiki_enabled :boolean default(TRUE), not null
|
||||
# namespace_id :integer
|
||||
# issues_tracker :string(255) default('gitlab'), not null
|
||||
# issues_tracker :string(255) default("gitlab"), not null
|
||||
# issues_tracker_id :string(255)
|
||||
# snippets_enabled :boolean default(TRUE), not null
|
||||
# last_activity_at :datetime
|
||||
@@ -115,13 +115,16 @@ class Project < ActiveRecord::Base
|
||||
# Validations
|
||||
validates :creator, presence: true, on: :create
|
||||
validates :description, length: { maximum: 2000 }, allow_blank: true
|
||||
validates :name, presence: true, length: { within: 0..255 },
|
||||
format: { with: Gitlab::Regex.project_name_regex,
|
||||
message: Gitlab::Regex.project_regex_message }
|
||||
validates :path, presence: true, length: { within: 0..255 },
|
||||
exclusion: { in: Gitlab::Blacklist.path },
|
||||
format: { with: Gitlab::Regex.path_regex,
|
||||
message: Gitlab::Regex.path_regex_message }
|
||||
validates :name,
|
||||
presence: true,
|
||||
length: { within: 0..255 },
|
||||
format: { with: Gitlab::Regex.project_name_regex,
|
||||
message: Gitlab::Regex.project_regex_message }
|
||||
validates :path,
|
||||
presence: true,
|
||||
length: { within: 0..255 },
|
||||
format: { with: Gitlab::Regex.path_regex,
|
||||
message: Gitlab::Regex.path_regex_message }
|
||||
validates :issues_enabled, :merge_requests_enabled,
|
||||
:wiki_enabled, inclusion: { in: [true, false] }
|
||||
validates :visibility_level,
|
||||
@@ -163,22 +166,22 @@ class Project < ActiveRecord::Base
|
||||
end
|
||||
|
||||
event :import_finish do
|
||||
transition :started => :finished
|
||||
transition started: :finished
|
||||
end
|
||||
|
||||
event :import_fail do
|
||||
transition :started => :failed
|
||||
transition started: :failed
|
||||
end
|
||||
|
||||
event :import_retry do
|
||||
transition :failed => :started
|
||||
transition failed: :started
|
||||
end
|
||||
|
||||
state :started
|
||||
state :finished
|
||||
state :failed
|
||||
|
||||
after_transition any => :started, :do => :add_import_job
|
||||
after_transition any => :started, do: :add_import_job
|
||||
end
|
||||
|
||||
class << self
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
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
|
||||
|
||||
prop_accessor :bamboo_url, :build_key, :username, :password
|
||||
|
||||
validates :bamboo_url, presence: true,
|
||||
format: { with: URI::regexp }, if: :activated?
|
||||
validates :bamboo_url,
|
||||
presence: true,
|
||||
format: { with: URI::regexp },
|
||||
if: :activated?
|
||||
validates :build_key, presence: true, if: :activated?
|
||||
validates :username, presence: true,
|
||||
if: ->(service) { service.password? }, if: :activated?
|
||||
validates :password, presence: true,
|
||||
if: ->(service) { service.username? }, if: :activated?
|
||||
validates :username,
|
||||
presence: true,
|
||||
if: ->(service) { service.password? },
|
||||
if: :activated?
|
||||
validates :password,
|
||||
presence: true,
|
||||
if: ->(service) { service.username? },
|
||||
if: :activated?
|
||||
|
||||
attr_accessor :response
|
||||
|
||||
|
||||
@@ -1,3 +1,17 @@
|
||||
# == 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
|
||||
|
||||
prop_accessor :title, :description, :project_url, :issues_url, :new_issue_url
|
||||
@@ -27,8 +41,8 @@ class CustomIssueTrackerService < IssueTrackerService
|
||||
{ type: 'text', name: 'title', placeholder: title },
|
||||
{ type: 'text', name: 'description', placeholder: description },
|
||||
{ type: 'text', name: 'project_url', placeholder: 'Project url' },
|
||||
{ type: 'text', name: 'issues_url', placeholder: 'Issue url'},
|
||||
{ type: 'text', name: 'new_issue_url', placeholder: 'New Issue url'}
|
||||
{ type: 'text', name: 'issues_url', placeholder: 'Issue url' },
|
||||
{ type: 'text', name: 'new_issue_url', placeholder: 'New Issue url' }
|
||||
]
|
||||
end
|
||||
|
||||
|
||||
@@ -81,7 +81,7 @@ class GitlabCiService < CiService
|
||||
def fields
|
||||
[
|
||||
{ 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
|
||||
|
||||
@@ -1,3 +1,17 @@
|
||||
# == 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
|
||||
include Rails.application.routes.url_helpers
|
||||
prop_accessor :title, :description, :project_url, :issues_url, :new_issue_url
|
||||
|
||||
@@ -1,3 +1,17 @@
|
||||
# == 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
|
||||
|
||||
validates :project_url, :issues_url, :new_issue_url, presence: true, if: :activated?
|
||||
@@ -30,8 +44,8 @@ class IssueTrackerService < Service
|
||||
[
|
||||
{ type: 'text', name: 'description', placeholder: description },
|
||||
{ type: 'text', name: 'project_url', placeholder: 'Project url' },
|
||||
{ type: 'text', name: 'issues_url', placeholder: 'Issue url'},
|
||||
{ type: 'text', name: 'new_issue_url', placeholder: 'New Issue url'}
|
||||
{ type: 'text', name: 'issues_url', placeholder: 'Issue url' },
|
||||
{ type: 'text', name: 'new_issue_url', placeholder: 'New Issue url' }
|
||||
]
|
||||
end
|
||||
|
||||
|
||||
@@ -1,3 +1,17 @@
|
||||
# == 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
|
||||
include HTTParty
|
||||
|
||||
|
||||
@@ -1,3 +1,17 @@
|
||||
# == 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
|
||||
|
||||
prop_accessor :title, :description, :project_url, :issues_url, :new_issue_url
|
||||
|
||||
@@ -17,13 +17,16 @@ class TeamcityService < CiService
|
||||
|
||||
prop_accessor :teamcity_url, :build_type, :username, :password
|
||||
|
||||
validates :teamcity_url, presence: true,
|
||||
format: { with: URI::regexp }, if: :activated?
|
||||
validates :teamcity_url,
|
||||
presence: true,
|
||||
format: { with: URI::regexp }, if: :activated?
|
||||
validates :build_type, presence: true, if: :activated?
|
||||
validates :username, presence: true,
|
||||
if: ->(service) { service.password? }, if: :activated?
|
||||
validates :password, presence: true,
|
||||
if: ->(service) { service.username? }, if: :activated?
|
||||
validates :username,
|
||||
presence: true,
|
||||
if: ->(service) { service.password? }, if: :activated?
|
||||
validates :password,
|
||||
presence: true,
|
||||
if: ->(service) { service.username? }, if: :activated?
|
||||
|
||||
attr_accessor :response
|
||||
|
||||
|
||||
@@ -136,7 +136,7 @@ class ProjectWiki
|
||||
def commit_details(action, message = nil, title = nil)
|
||||
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
|
||||
|
||||
def default_message(action, title)
|
||||
|
||||
+24
-37
@@ -30,7 +30,7 @@ class Repository
|
||||
commit = Gitlab::Git::Commit.find(raw_repository, id)
|
||||
commit = Commit.new(commit) if commit
|
||||
commit
|
||||
rescue Rugged::OdbError => ex
|
||||
rescue Rugged::OdbError
|
||||
nil
|
||||
end
|
||||
|
||||
@@ -61,25 +61,25 @@ class Repository
|
||||
end
|
||||
|
||||
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)
|
||||
end
|
||||
|
||||
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)
|
||||
end
|
||||
|
||||
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)
|
||||
end
|
||||
|
||||
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)
|
||||
end
|
||||
@@ -97,19 +97,15 @@ class Repository
|
||||
end
|
||||
|
||||
def branch_names
|
||||
Rails.cache.fetch(cache_key(:branch_names)) do
|
||||
raw_repository.branch_names
|
||||
end
|
||||
cache.fetch(:branch_names) { raw_repository.branch_names }
|
||||
end
|
||||
|
||||
def tag_names
|
||||
Rails.cache.fetch(cache_key(:tag_names)) do
|
||||
raw_repository.tag_names
|
||||
end
|
||||
cache.fetch(:tag_names) { raw_repository.tag_names }
|
||||
end
|
||||
|
||||
def commit_count
|
||||
Rails.cache.fetch(cache_key(:commit_count)) do
|
||||
cache.fetch(:commit_count) do
|
||||
begin
|
||||
raw_repository.commit_count(self.root_ref)
|
||||
rescue
|
||||
@@ -121,26 +117,19 @@ class Repository
|
||||
# Return repo size in megabytes
|
||||
# Cached in redis
|
||||
def size
|
||||
Rails.cache.fetch(cache_key(:size)) do
|
||||
raw_repository.size
|
||||
end
|
||||
cache.fetch(:size) { raw_repository.size }
|
||||
end
|
||||
|
||||
def expire_cache
|
||||
Rails.cache.delete(cache_key(:size))
|
||||
Rails.cache.delete(cache_key(:branch_names))
|
||||
Rails.cache.delete(cache_key(:tag_names))
|
||||
Rails.cache.delete(cache_key(:commit_count))
|
||||
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))
|
||||
%i(size branch_names tag_names commit_count graph_log
|
||||
readme version contribution_guide).each do |key|
|
||||
cache.expire(key)
|
||||
end
|
||||
end
|
||||
|
||||
def graph_log
|
||||
Rails.cache.fetch(cache_key(:graph_log)) do
|
||||
commits = raw_repository.log(limit: 6000,
|
||||
skip_merges: true,
|
||||
cache.fetch(:graph_log) do
|
||||
commits = raw_repository.log(limit: 6000, skip_merges: true,
|
||||
ref: root_ref)
|
||||
|
||||
commits.map do |rugged_commit|
|
||||
@@ -176,10 +165,6 @@ class Repository
|
||||
end
|
||||
end
|
||||
|
||||
def cache_key(type)
|
||||
"#{type}:#{path_with_namespace}"
|
||||
end
|
||||
|
||||
def method_missing(m, *args, &block)
|
||||
raw_repository.send(m, *args, &block)
|
||||
end
|
||||
@@ -199,13 +184,11 @@ class Repository
|
||||
end
|
||||
|
||||
def readme
|
||||
Rails.cache.fetch(cache_key(:readme)) do
|
||||
tree(:head).readme
|
||||
end
|
||||
cache.fetch(:readme) { tree(:head).readme }
|
||||
end
|
||||
|
||||
def version
|
||||
Rails.cache.fetch(cache_key(:version)) do
|
||||
cache.fetch(:version) do
|
||||
tree(:head).blobs.find do |file|
|
||||
file.name.downcase == 'version'
|
||||
end
|
||||
@@ -213,9 +196,7 @@ class Repository
|
||||
end
|
||||
|
||||
def contribution_guide
|
||||
Rails.cache.fetch(cache_key(:contribution_guide)) do
|
||||
tree(:head).contribution_guide
|
||||
end
|
||||
cache.fetch(:contribution_guide) { tree(:head).contribution_guide }
|
||||
end
|
||||
|
||||
def head_commit
|
||||
@@ -351,4 +332,10 @@ class Repository
|
||||
[]
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def cache
|
||||
@cache ||= RepositoryCache.new(path_with_namespace)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -29,9 +29,11 @@ class Snippet < ActiveRecord::Base
|
||||
|
||||
validates :author, presence: true
|
||||
validates :title, presence: true, length: { within: 0..255 }
|
||||
validates :file_name, presence: true, length: { within: 0..255 },
|
||||
format: { with: Gitlab::Regex.path_regex,
|
||||
message: Gitlab::Regex.path_regex_message }
|
||||
validates :file_name,
|
||||
presence: true,
|
||||
length: { within: 0..255 },
|
||||
format: { with: Gitlab::Regex.path_regex,
|
||||
message: Gitlab::Regex.path_regex_message }
|
||||
validates :content, presence: true
|
||||
validates :visibility_level, inclusion: { in: Gitlab::VisibilityLevel.values }
|
||||
|
||||
|
||||
+8
-6
@@ -113,13 +113,15 @@ class User < ActiveRecord::Base
|
||||
# Validations
|
||||
#
|
||||
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 :projects_limit, presence: true, numericality: {greater_than_or_equal_to: 0}
|
||||
validates :username, presence: true, uniqueness: { case_sensitive: false },
|
||||
exclusion: { in: Gitlab::Blacklist.path },
|
||||
format: { with: Gitlab::Regex.username_regex,
|
||||
message: Gitlab::Regex.username_regex_message }
|
||||
validates :projects_limit, presence: true, numericality: { greater_than_or_equal_to: 0 }
|
||||
validates :username,
|
||||
presence: true,
|
||||
uniqueness: { case_sensitive: false },
|
||||
exclusion: { in: Gitlab::Blacklist.path },
|
||||
format: { with: Gitlab::Regex.username_regex,
|
||||
message: Gitlab::Regex.username_regex_message }
|
||||
|
||||
validates :notification_level, inclusion: { in: Notification.notification_levels }, presence: true
|
||||
validate :namespace_uniq, if: ->(user) { user.username_changed? }
|
||||
|
||||
@@ -43,7 +43,7 @@ class WikiPage
|
||||
@attributes[:slug]
|
||||
end
|
||||
|
||||
alias :to_param :slug
|
||||
alias_method :to_param, :slug
|
||||
|
||||
# The formatted title of this page.
|
||||
def title
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
class GitPushService
|
||||
attr_accessor :project, :user, :push_data, :push_commits
|
||||
include Gitlab::CurrentSettings
|
||||
include Gitlab::Access
|
||||
|
||||
# This method will be called after each git update
|
||||
# and only if the provided user and project is present in GitLab.
|
||||
@@ -29,8 +31,12 @@ class GitPushService
|
||||
if is_default_branch?(ref)
|
||||
# Initial push to the default branch. Take the full history of that branch as "newly pushed".
|
||||
@push_commits = project.repository.commits(newrev)
|
||||
# Default branch is protected by default
|
||||
project.protected_branches.create({ name: project.default_branch })
|
||||
|
||||
# Set protection on the default branch if configured
|
||||
if (current_application_settings.default_branch_protection != PROTECTION_NONE)
|
||||
developers_can_push = current_application_settings.default_branch_protection == PROTECTION_DEV_CAN_PUSH ? true : false
|
||||
project.protected_branches.create({ name: project.default_branch, developers_can_push: developers_can_push })
|
||||
end
|
||||
else
|
||||
# Use the pushed commits that aren't reachable by the default branch
|
||||
# as a heuristic. This may include more commits than are actually pushed, but
|
||||
|
||||
@@ -38,4 +38,4 @@ module Oauth2::AccessTokenValidationService
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -14,14 +14,14 @@ module Projects
|
||||
uploader.store!(image)
|
||||
link = {
|
||||
'alt' => File.basename(alt, '.*'),
|
||||
'url' => File.join(@root_url, uploader.url)
|
||||
'url' => File.join(@root_url, uploader.url)
|
||||
}
|
||||
else
|
||||
link = nil
|
||||
end
|
||||
end
|
||||
|
||||
protected
|
||||
protected
|
||||
|
||||
def upload_path
|
||||
base_dir = FileUploader.generate_dir
|
||||
|
||||
@@ -5,11 +5,12 @@ module Projects
|
||||
end
|
||||
|
||||
def execute(note_type, note_id)
|
||||
participating = if note_type && note_id
|
||||
participants_in(note_type, note_id)
|
||||
else
|
||||
[]
|
||||
end
|
||||
participating =
|
||||
if note_type && note_id
|
||||
participants_in(note_type, note_id)
|
||||
else
|
||||
[]
|
||||
end
|
||||
team_members = sorted(@project.team.members)
|
||||
participants = all_members + team_members + participating
|
||||
participants.uniq
|
||||
|
||||
@@ -25,6 +25,10 @@
|
||||
= f.label :default_projects_limit, class: 'control-label'
|
||||
.col-sm-10
|
||||
= f.number_field :default_projects_limit, class: 'form-control'
|
||||
.form-group
|
||||
= f.label :default_branch_protection, class: 'control-label'
|
||||
.col-sm-10
|
||||
= f.select :default_branch_protection, options_for_select(Gitlab::Access.protection_options, @application_setting.default_branch_protection), {}, class: 'form-control'
|
||||
.form-group
|
||||
= f.label :home_page_url, class: 'control-label'
|
||||
.col-sm-10
|
||||
|
||||
@@ -91,7 +91,7 @@
|
||||
%div.prepend-top-10
|
||||
= select_tag :access_level, options_for_select(GroupMember.access_level_roles), class: "project-access-select select2"
|
||||
%hr
|
||||
= button_tag 'Add users into group', class: "btn btn-create"
|
||||
= button_tag 'Add users to group', class: "btn btn-create"
|
||||
.panel.panel-default
|
||||
.panel-heading
|
||||
%h3.panel-title
|
||||
|
||||
@@ -10,7 +10,8 @@
|
||||
- groups.each do |group|
|
||||
%li.group-row
|
||||
= 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
|
||||
= truncate(group.name, length: 35)
|
||||
%span.arrow
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
= 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
|
||||
= visibility_level_icon(project.visibility_level)
|
||||
.dash-project-avatar
|
||||
= project_icon(project.to_param, alt: '', class: 'avatar s24')
|
||||
%span.str-truncated
|
||||
%span.namespace-name
|
||||
- if project.namespace
|
||||
|
||||
@@ -12,4 +12,4 @@
|
||||
%strong= link_to "here", help_page_path("permissions", "permissions"), class: "vlink"
|
||||
|
||||
.form-actions
|
||||
= f.submit 'Add users into group', class: "btn btn-create"
|
||||
= f.submit 'Add users to group', class: "btn btn-create"
|
||||
|
||||
@@ -12,10 +12,10 @@
|
||||
- projects.each do |project|
|
||||
%li.project-row
|
||||
= 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
|
||||
= visibility_level_icon(project.visibility_level)
|
||||
.dash-project-avatar
|
||||
= project_icon(project.to_param, alt: '', class: 'avatar s24')
|
||||
%span.str-truncated
|
||||
%span.project-name
|
||||
= project.name
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.dashboard
|
||||
%div
|
||||
= image_tag group_icon(@group.path), class: "avatar s90"
|
||||
= image_tag group_icon(@group.path), class: "avatar avatar-tile s90"
|
||||
.clearfix
|
||||
%h2
|
||||
= @group.name
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
- if nav_menu_collapsed?
|
||||
= link_to icon('angle-right'), '#', class: 'toggle-nav-collapse'
|
||||
- else
|
||||
= link_to icon('angle-left'), '#', class: 'toggle-nav-collapse'
|
||||
@@ -1,8 +1,10 @@
|
||||
- if defined?(sidebar)
|
||||
.page-with-sidebar
|
||||
.page-with-sidebar{ class: nav_sidebar_class }
|
||||
= render "layouts/broadcast"
|
||||
.sidebar-wrapper
|
||||
= render(sidebar)
|
||||
.collapse-nav
|
||||
= render partial: 'layouts/collapse_button'
|
||||
.content-wrapper
|
||||
.container-fluid
|
||||
.content
|
||||
|
||||
@@ -30,5 +30,5 @@
|
||||
%code
|
||||
:erb
|
||||
<% lines.each do |line| %>
|
||||
<%= highlight(@blob.name, line, true).html_safe %>
|
||||
<%= highlight(@blob.name, line.force_encoding("utf-8"), true).html_safe %>
|
||||
<% end %>
|
||||
|
||||
@@ -37,23 +37,8 @@
|
||||
- @commit.parents.each do |parent|
|
||||
= link_to parent.short_id, project_commit_path(@project, parent)
|
||||
|
||||
.commit-info-row
|
||||
- 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)
|
||||
.commit-info-row.branches
|
||||
%i.fa.fa-spinner.fa-spin
|
||||
|
||||
.commit-box
|
||||
%h3.commit-title
|
||||
@@ -61,3 +46,7 @@
|
||||
- if @commit.description.present?
|
||||
%pre.commit-description
|
||||
= preserve(gfm(escape_once(@commit.description)))
|
||||
|
||||
:coffeescript
|
||||
$ ->
|
||||
$(".commit-info-row.branches").load("#{branches_project_commit_path(@project, @commit.id)}")
|
||||
@@ -0,0 +1,16 @@
|
||||
- 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)
|
||||
@@ -3,8 +3,7 @@
|
||||
.project-edit-content
|
||||
%div
|
||||
%h3.page-title
|
||||
Project settings:
|
||||
%p.light Some settings, such as "Transfer Project", are hidden inside the danger area below.
|
||||
Project settings
|
||||
%hr
|
||||
.panel-body
|
||||
= form_for @project, remote: true, html: { multipart: true, class: "edit_project form-horizontal" }, authenticity_token: true do |f|
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
You can
|
||||
= link_to project_new_blob_path(@project, 'master'), class: 'btn btn-new btn-lg' do
|
||||
add a file
|
||||
or push it via command line.
|
||||
or do a push via the command line.
|
||||
|
||||
%h4
|
||||
%strong Command line instructions
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
= link_to_member(@project, participant, name: false, size: 24)
|
||||
|
||||
.voting_notes#notes= render "projects/notes/notes_with_form"
|
||||
.col-md-3.hidden-sm.hidden-xs
|
||||
.col-md-3
|
||||
%div
|
||||
.clearfix
|
||||
%span.slead.has_tooltip{:"data-original-title" => 'Cross-project reference'}
|
||||
|
||||
@@ -2,23 +2,21 @@
|
||||
%div.prepend-top-20
|
||||
%p
|
||||
Assignee:
|
||||
|
||||
- if issue.assignee
|
||||
= link_to_member(@project, @issue.assignee)
|
||||
- else
|
||||
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)
|
||||
- elsif issue.assignee
|
||||
= link_to_member(@project, @issue.assignee)
|
||||
- else
|
||||
None
|
||||
|
||||
%div.prepend-top-20
|
||||
%p
|
||||
Milestone:
|
||||
- if issue.milestone
|
||||
#{link_to @issue.milestone.title, project_milestone_path(@project, @issue.milestone)}
|
||||
- else
|
||||
none
|
||||
- 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'})
|
||||
= hidden_field_tag :issue_context
|
||||
= 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 @@
|
||||
:plain
|
||||
$("##{dom_id(@issue)}").fadeOut();
|
||||
- elsif params[:issue_context]
|
||||
$('.context').html("#{escape_javascript(render partial: 'issue_context', locals: { issue: @issue })}");
|
||||
$('.context').effect('highlight');
|
||||
- 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>")
|
||||
- else
|
||||
$('.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 @@
|
||||
.col-md-9
|
||||
= render "projects/merge_requests/show/participants"
|
||||
= render "projects/notes/notes_with_form"
|
||||
.col-md-3.hidden-sm.hidden-xs
|
||||
.col-md-3
|
||||
.clearfix
|
||||
%span.slead.has_tooltip{:"data-original-title" => 'Cross-project reference'}
|
||||
= cross_project_reference(@project, @merge_request)
|
||||
@@ -18,7 +18,7 @@
|
||||
%cite.cgray
|
||||
= render partial: 'projects/merge_requests/show/context', locals: { merge_request: @merge_request }
|
||||
%hr
|
||||
.votes-holder.hidden-sm.hidden-xs
|
||||
.votes-holder
|
||||
%h6 Votes
|
||||
#votes= render 'votes/votes_block', votable: @merge_request
|
||||
|
||||
|
||||
@@ -2,22 +2,22 @@
|
||||
%div.prepend-top-20
|
||||
%p
|
||||
Assignee:
|
||||
|
||||
- if @merge_request.assignee
|
||||
= link_to_member(@project, @merge_request.assignee)
|
||||
- else
|
||||
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)
|
||||
- elsif merge_request.assignee
|
||||
= link_to_member(@project, @merge_request.assignee)
|
||||
- else
|
||||
None
|
||||
|
||||
%div.prepend-top-20
|
||||
%p
|
||||
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)
|
||||
= 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
|
||||
= f.submit class: 'btn'
|
||||
- elsif merge_request.milestone
|
||||
= link_to merge_request.milestone.title, project_milestone_path
|
||||
- else
|
||||
None
|
||||
|
||||
@@ -1,2 +1,8 @@
|
||||
- if params[:merge_request_context]
|
||||
$('.context').html("#{escape_javascript(render partial: 'projects/merge_requests/show/context', locals: { issue: @issue })}");
|
||||
$('.context').effect('highlight');
|
||||
|
||||
new ProjectUsersSelect();
|
||||
|
||||
$('select.select2').select2({width: 'resolve', dropdownAutoWidth: true});
|
||||
merge_request = new MergeRequest();
|
||||
|
||||
@@ -19,8 +19,10 @@
|
||||
%td.new_line= "..."
|
||||
%td.line_content.matched= line.text
|
||||
- else
|
||||
%td.old_line= raw(line.type == "new" ? " " : line.old_pos)
|
||||
%td.new_line= raw(line.type == "old" ? " " : line.new_pos)
|
||||
%td.old_line{class: line.type == "new" ? "new" : "old"}
|
||||
= raw(line.type == "new" ? " " : line.old_pos)
|
||||
%td.new_line{class: line.type == "new" ? "new" : "old"}
|
||||
= raw(line.type == "old" ? " " : line.new_pos)
|
||||
%td.line_content{class: "noteable_line #{line.type} #{line_code}", "line_code" => line_code}= raw diff_line_content(line.text)
|
||||
|
||||
- if line_code == note.line_code
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.clearfix
|
||||
- groups.each do |group|
|
||||
= link_to group, class: 'profile-groups-avatars', title: group.name do
|
||||
= image_tag group_icon(group.path), class: 'avatar avatar-inline s40'
|
||||
= link_to group, class: 'profile-groups-avatars inline', title: group.name do
|
||||
= image_tag group_icon(group.path), class: 'avatar avatar-tile s40'
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
%h4 Calendar
|
||||
#cal-heatmap.calendar
|
||||
:javascript
|
||||
new calendar(
|
||||
@@ -1,7 +1,7 @@
|
||||
.row
|
||||
.col-md-8
|
||||
%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
|
||||
- if @user == current_user
|
||||
.pull-right
|
||||
@@ -15,15 +15,16 @@
|
||||
.clearfix
|
||||
|
||||
- if @groups.any?
|
||||
%h4 Groups:
|
||||
%h4 Groups
|
||||
= render 'groups', groups: @groups
|
||||
%hr
|
||||
|
||||
%h4 Calendar:
|
||||
%div= render 'calendar'
|
||||
.user-calendar
|
||||
%h4.center.light
|
||||
%i.fa.fa-spinner.fa-spin
|
||||
%hr
|
||||
%h4
|
||||
User Activity:
|
||||
User Activity
|
||||
|
||||
- if current_user
|
||||
%span.rss-icon.pull-right
|
||||
@@ -36,3 +37,8 @@
|
||||
= render 'profile', user: @user
|
||||
- if @projects.present?
|
||||
= render 'projects', projects: @projects
|
||||
|
||||
|
||||
:coffeescript
|
||||
$ ->
|
||||
$(".user-calendar").load("#{user_calendar_path}")
|
||||
|
||||
@@ -70,7 +70,10 @@ module Gitlab
|
||||
config.middleware.use Rack::Cors do
|
||||
allow do
|
||||
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
|
||||
|
||||
|
||||
@@ -13,7 +13,11 @@ class Settings < Settingslogic
|
||||
if gitlab_shell.ssh_port != 22
|
||||
"ssh://#{gitlab_shell.ssh_user}@#{gitlab_shell.ssh_host}:#{gitlab_shell.ssh_port}/"
|
||||
else
|
||||
"#{gitlab_shell.ssh_user}@#{gitlab_shell.ssh_host}:"
|
||||
if gitlab_shell.ssh_host.include? ':'
|
||||
"[#{gitlab_shell.ssh_user}@#{gitlab_shell.ssh_host}]:"
|
||||
else
|
||||
"#{gitlab_shell.ssh_user}@#{gitlab_shell.ssh_host}:"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -94,6 +98,7 @@ Settings['issues_tracker'] ||= {}
|
||||
#
|
||||
Settings['gitlab'] ||= Settingslogic.new({})
|
||||
Settings.gitlab['default_projects_limit'] ||= 10
|
||||
Settings.gitlab['default_branch_protection'] ||= 2
|
||||
Settings.gitlab['default_can_create_group'] = true if Settings.gitlab['default_can_create_group'].nil?
|
||||
Settings.gitlab['default_theme'] = Gitlab::Theme::MARS if Settings.gitlab['default_theme'].nil?
|
||||
Settings.gitlab['host'] ||= 'localhost'
|
||||
@@ -155,7 +160,7 @@ Settings.gitlab_shell['ssh_path_prefix'] ||= Settings.send(:build_gitlab_shell_s
|
||||
Settings['backup'] ||= Settingslogic.new({})
|
||||
Settings.backup['keep_time'] ||= 0
|
||||
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
|
||||
if Settings.backup['upload']['connection']
|
||||
Settings.backup['upload']['connection'] = Hash[Settings.backup['upload']['connection'].map { |k, v| [k.to_sym, v] }]
|
||||
|
||||
@@ -42,11 +42,12 @@ module ActsAsTaggableOn::Taggable
|
||||
|
||||
elsif options.delete(:any)
|
||||
# get tags, drop out if nothing returned (we need at least one)
|
||||
tags = if options.delete(:wild)
|
||||
ActsAsTaggableOn::Tag.named_like_any(tag_list)
|
||||
else
|
||||
ActsAsTaggableOn::Tag.named_any(tag_list)
|
||||
end
|
||||
tags =
|
||||
if options.delete(:wild)
|
||||
ActsAsTaggableOn::Tag.named_like_any(tag_list)
|
||||
else
|
||||
ActsAsTaggableOn::Tag.named_any(tag_list)
|
||||
end
|
||||
|
||||
return empty_result unless tags.length > 0
|
||||
|
||||
@@ -68,12 +69,12 @@ module ActsAsTaggableOn::Taggable
|
||||
select_clause = "DISTINCT #{table_name}.*" unless context and tag_types.one?
|
||||
|
||||
if owned_by
|
||||
tagging_join << " AND " +
|
||||
sanitize_sql([
|
||||
"#{taggings_alias}.tagger_id = ? AND #{taggings_alias}.tagger_type = ?",
|
||||
owned_by.id,
|
||||
owned_by.class.base_class.to_s
|
||||
])
|
||||
tagging_join << " AND " +
|
||||
sanitize_sql([
|
||||
"#{taggings_alias}.tagger_id = ? AND #{taggings_alias}.tagger_type = ?",
|
||||
owned_by.id,
|
||||
owned_by.class.base_class.to_s
|
||||
])
|
||||
end
|
||||
|
||||
joins << tagging_join
|
||||
@@ -92,12 +93,12 @@ module ActsAsTaggableOn::Taggable
|
||||
tagging_join << " AND " + sanitize_sql(["#{taggings_alias}.context = ?", context.to_s]) if context
|
||||
|
||||
if owned_by
|
||||
tagging_join << " AND " +
|
||||
sanitize_sql([
|
||||
"#{taggings_alias}.tagger_id = ? AND #{taggings_alias}.tagger_type = ?",
|
||||
owned_by.id,
|
||||
owned_by.class.base_class.to_s
|
||||
])
|
||||
tagging_join << " AND " +
|
||||
sanitize_sql([
|
||||
"#{taggings_alias}.tagger_id = ? AND #{taggings_alias}.tagger_type = ?",
|
||||
owned_by.id,
|
||||
owned_by.class.base_class.to_s
|
||||
])
|
||||
end
|
||||
|
||||
joins << tagging_join
|
||||
|
||||
@@ -12,22 +12,30 @@ if File.exists?(aws_file)
|
||||
aws_secret_access_key: AWS_CONFIG['secret_access_key'], # required
|
||||
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
|
||||
config.fog_attributes = {'Cache-Control'=>'max-age=315576000'} # optional, defaults to {}
|
||||
config.fog_authenticated_url_expiration = 1 << 29 # optional time (in seconds) that authenticated urls will be valid.
|
||||
# when fog_public is false and provider is AWS or Google, defaults to 600
|
||||
|
||||
# required
|
||||
config.fog_directory = AWS_CONFIG['bucket']
|
||||
|
||||
# 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
|
||||
config.fog_authenticated_url_expiration = 1 << 29
|
||||
end
|
||||
|
||||
# Mocking Fog requests, based on: https://github.com/carrierwaveuploader/carrierwave/wiki/How-to%3A-Test-Fog-based-uploaders
|
||||
if Rails.env.test?
|
||||
Fog.mock!
|
||||
connection = ::Fog::Storage.new(
|
||||
:aws_access_key_id => AWS_CONFIG['access_key_id'],
|
||||
:aws_secret_access_key => AWS_CONFIG['secret_access_key'],
|
||||
:provider => 'AWS',
|
||||
:region => AWS_CONFIG['region']
|
||||
aws_access_key_id: AWS_CONFIG['access_key_id'],
|
||||
aws_secret_access_key: AWS_CONFIG['secret_access_key'],
|
||||
provider: 'AWS',
|
||||
region: AWS_CONFIG['region']
|
||||
)
|
||||
connection.directories.create(:key => AWS_CONFIG['bucket'])
|
||||
connection.directories.create(key: AWS_CONFIG['bucket'])
|
||||
end
|
||||
end
|
||||
|
||||
@@ -43,10 +43,10 @@ Doorkeeper.configure do
|
||||
force_ssl_in_redirect_uri false
|
||||
|
||||
# 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
|
||||
# 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
|
||||
# For more information go to
|
||||
|
||||
@@ -16,4 +16,4 @@ end
|
||||
|
||||
if File.exist?(Gitlab.config.gitlab_shell.path) && !File.exist?(gitlab_shell_symlink)
|
||||
FileUtils.symlink(secret_file, gitlab_shell_symlink)
|
||||
end
|
||||
end
|
||||
|
||||
+40
-40
@@ -3,9 +3,9 @@ require 'api/api'
|
||||
|
||||
Gitlab::Application.routes.draw do
|
||||
use_doorkeeper do
|
||||
controllers :applications => 'oauth/applications',
|
||||
:authorized_applications => 'oauth/authorized_applications',
|
||||
:authorizations => 'oauth/authorizations'
|
||||
controllers applications: 'oauth/applications',
|
||||
authorized_applications: 'oauth/authorized_applications',
|
||||
authorizations: 'oauth/authorizations'
|
||||
end
|
||||
#
|
||||
# Search
|
||||
@@ -167,10 +167,9 @@ Gitlab::Application.routes.draw do
|
||||
end
|
||||
end
|
||||
|
||||
# route for commits used by the cal-heatmap
|
||||
get 'u/:username/activities' => 'users#activities', as: :user_activities,
|
||||
constraints: { username: /(?:[^.]|\.(?!atom$))+/, format: /atom/ },
|
||||
via: :get
|
||||
get 'u/:username/calendar' => 'users#calendar', as: :user_calendar,
|
||||
constraints: { username: /(?:[^.]|\.(?!atom$))+/, format: /atom/ }
|
||||
|
||||
get '/u/:username' => 'users#show', as: :user,
|
||||
constraints: { username: /(?:[^.]|\.(?!atom$))+/, format: /atom/ }
|
||||
|
||||
@@ -188,7 +187,7 @@ Gitlab::Application.routes.draw do
|
||||
#
|
||||
# Groups Area
|
||||
#
|
||||
resources :groups, constraints: {id: /(?:[^.]|\.(?!atom$))+/, format: /atom/} do
|
||||
resources :groups, constraints: { id: /(?:[^.]|\.(?!atom$))+/, format: /atom/ } do
|
||||
member do
|
||||
get :issues
|
||||
get :merge_requests
|
||||
@@ -239,40 +238,44 @@ Gitlab::Application.routes.draw do
|
||||
|
||||
scope module: :projects do
|
||||
# Blob routes:
|
||||
get '/new/:id', to: 'blob#new', constraints: {id: /.+/}, as: 'new_blob'
|
||||
post '/create/:id', to: 'blob#create', constraints: {id: /.+/}, as: 'create_blob'
|
||||
get '/edit/:id', to: 'blob#edit', constraints: {id: /.+/}, as: 'edit_blob'
|
||||
put '/update/:id', to: 'blob#update', constraints: {id: /.+/}, as: 'update_blob'
|
||||
post '/preview/:id', to: 'blob#preview', constraints: {id: /.+/}, as: 'preview_blob'
|
||||
get '/new/:id', to: 'blob#new', constraints: { id: /.+/ }, as: 'new_blob'
|
||||
post '/create/:id', to: 'blob#create', constraints: { id: /.+/ }, as: 'create_blob'
|
||||
get '/edit/:id', to: 'blob#edit', constraints: { id: /.+/ }, as: 'edit_blob'
|
||||
put '/update/:id', to: 'blob#update', constraints: { id: /.+/ }, as: 'update_blob'
|
||||
post '/preview/:id', to: 'blob#preview', constraints: { id: /.+/ }, as: 'preview_blob'
|
||||
|
||||
resources :blob, only: [:show, :destroy], constraints: { id: /.+/, format: false } do
|
||||
get :diff, on: :member
|
||||
end
|
||||
|
||||
resources :raw, only: [:show], constraints: {id: /.+/}
|
||||
resources :tree, only: [:show], constraints: {id: /.+/, format: /(html|js)/ }
|
||||
resources :raw, only: [:show], constraints: { id: /.+/ }
|
||||
resources :tree, only: [:show], constraints: { id: /.+/, format: /(html|js)/ }
|
||||
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 :blame, only: [:show], constraints: {id: /.+/}
|
||||
resources :network, only: [:show], constraints: {id: /(?:[^.]|\.(?!json$))+/, format: /json/}
|
||||
resources :graphs, only: [:show], constraints: {id: /(?:[^.]|\.(?!json$))+/, format: /json/} do
|
||||
resources :blame, only: [:show], constraints: { id: /.+/ }
|
||||
resources :network, only: [:show], constraints: { id: /(?:[^.]|\.(?!json$))+/, format: /json/ }
|
||||
resources :graphs, only: [:show], constraints: { id: /(?:[^.]|\.(?!json$))+/, format: /json/ } do
|
||||
member do
|
||||
get :commits
|
||||
end
|
||||
end
|
||||
|
||||
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
|
||||
get 'raw'
|
||||
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
|
||||
get :pages
|
||||
put ':id' => 'wikis#update'
|
||||
@@ -299,7 +302,7 @@ Gitlab::Application.routes.draw do
|
||||
end
|
||||
end
|
||||
|
||||
resources :deploy_keys, constraints: {id: /\d+/} do
|
||||
resources :deploy_keys, constraints: { id: /\d+/ } do
|
||||
member do
|
||||
put :enable
|
||||
put :disable
|
||||
@@ -318,16 +321,14 @@ Gitlab::Application.routes.draw do
|
||||
member do
|
||||
# tree viewer logs
|
||||
get 'logs_tree', constraints: { id: Gitlab::Regex.git_reference_regex }
|
||||
get 'logs_tree/:path' => 'refs#logs_tree',
|
||||
as: :logs_file,
|
||||
constraints: {
|
||||
id: Gitlab::Regex.git_reference_regex,
|
||||
path: /.*/
|
||||
}
|
||||
get 'logs_tree/:path' => 'refs#logs_tree', as: :logs_file, constraints: {
|
||||
id: Gitlab::Regex.git_reference_regex,
|
||||
path: /.*/
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
resources :merge_requests, constraints: {id: /\d+/}, except: [:destroy] do
|
||||
resources :merge_requests, constraints: { id: /\d+/ }, except: [:destroy] do
|
||||
member do
|
||||
get :diffs
|
||||
post :automerge
|
||||
@@ -342,29 +343,28 @@ Gitlab::Application.routes.draw do
|
||||
end
|
||||
end
|
||||
|
||||
resources :git_hooks, constraints: {id: /\d+/}
|
||||
|
||||
resources :hooks, only: [:index, :create, :destroy], constraints: {id: /\d+/} do
|
||||
resources :git_hooks, constraints: { id: /\d+/ }
|
||||
resources :hooks, only: [:index, :create, :destroy], constraints: { id: /\d+/ } do
|
||||
member do
|
||||
get :test
|
||||
end
|
||||
end
|
||||
|
||||
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
|
||||
put :sort_issues
|
||||
put :sort_merge_requests
|
||||
end
|
||||
end
|
||||
|
||||
resources :labels, constraints: {id: /\d+/} do
|
||||
resources :labels, constraints: { id: /\d+/ } do
|
||||
collection do
|
||||
post :generate
|
||||
end
|
||||
end
|
||||
|
||||
resources :issues, constraints: {id: /\d+/}, except: [:destroy] do
|
||||
resources :issues, constraints: { id: /\d+/ }, except: [:destroy] do
|
||||
collection do
|
||||
post :bulk_update
|
||||
end
|
||||
@@ -381,9 +381,9 @@ Gitlab::Application.routes.draw do
|
||||
end
|
||||
end
|
||||
|
||||
resources :group_links, only: [:index, :create, :destroy], constraints: {id: /\d+/}
|
||||
resources :group_links, only: [:index, :create, :destroy], constraints: { id: /\d+/ }
|
||||
|
||||
resources :notes, only: [:index, :create, :destroy, :update], constraints: {id: /\d+/} do
|
||||
resources :notes, only: [:index, :create, :destroy, :update], constraints: { id: /\d+/ } do
|
||||
member do
|
||||
delete :delete_attachment
|
||||
end
|
||||
@@ -394,7 +394,7 @@ Gitlab::Application.routes.draw do
|
||||
get "/audit_events" => "audit_events#project_log"
|
||||
end
|
||||
|
||||
get ':id' => 'namespaces#show', constraints: {id: /(?:[^.]|\.(?!atom$))+/, format: /atom/}
|
||||
get ':id' => 'namespaces#show', constraints: { id: /(?:[^.]|\.(?!atom$))+/, format: /atom/ }
|
||||
|
||||
root to: 'dashboard#show'
|
||||
end
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
class AddDefaultBranchProtectionSetting < ActiveRecord::Migration
|
||||
def change
|
||||
add_column :application_settings, :default_branch_protection, :integer, :default => 2
|
||||
end
|
||||
end
|
||||
+20
-19
@@ -11,7 +11,7 @@
|
||||
#
|
||||
# It's strongly recommended that you check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema.define(version: 20150116234545) do
|
||||
ActiveRecord::Schema.define(version: 20150125163100) do
|
||||
|
||||
# These are extensions that must be enabled in order to support this database
|
||||
enable_extension "plpgsql"
|
||||
@@ -27,6 +27,18 @@ ActiveRecord::Schema.define(version: 20150116234545) do
|
||||
t.string "light_logo"
|
||||
end
|
||||
|
||||
create_table "application_settings", force: true do |t|
|
||||
t.integer "default_projects_limit"
|
||||
t.boolean "signup_enabled"
|
||||
t.boolean "signin_enabled"
|
||||
t.boolean "gravatar_enabled"
|
||||
t.text "sign_in_text"
|
||||
t.datetime "created_at"
|
||||
t.datetime "updated_at"
|
||||
t.string "home_page_url"
|
||||
t.integer "default_branch_protection", default: 2
|
||||
end
|
||||
|
||||
create_table "audit_events", force: true do |t|
|
||||
t.integer "author_id", null: false
|
||||
t.string "type", null: false
|
||||
@@ -41,17 +53,6 @@ ActiveRecord::Schema.define(version: 20150116234545) do
|
||||
add_index "audit_events", ["entity_id", "entity_type"], name: "index_audit_events_on_entity_id_and_entity_type", using: :btree
|
||||
add_index "audit_events", ["type"], name: "index_audit_events_on_type", using: :btree
|
||||
|
||||
create_table "application_settings", force: true do |t|
|
||||
t.integer "default_projects_limit"
|
||||
t.boolean "signup_enabled"
|
||||
t.boolean "signin_enabled"
|
||||
t.boolean "gravatar_enabled"
|
||||
t.text "sign_in_text"
|
||||
t.datetime "created_at"
|
||||
t.datetime "updated_at"
|
||||
t.string "home_page_url"
|
||||
end
|
||||
|
||||
create_table "broadcast_messages", force: true do |t|
|
||||
t.text "message", null: false
|
||||
t.datetime "starts_at"
|
||||
@@ -378,14 +379,14 @@ ActiveRecord::Schema.define(version: 20150116234545) do
|
||||
t.string "import_url"
|
||||
t.integer "visibility_level", default: 0, null: false
|
||||
t.boolean "archived", default: false, null: false
|
||||
t.string "avatar"
|
||||
t.string "import_status"
|
||||
t.float "repository_size", default: 0.0
|
||||
t.text "merge_requests_template"
|
||||
t.integer "star_count", default: 0, null: false
|
||||
t.boolean "merge_requests_rebase_enabled", default: false
|
||||
t.string "import_type"
|
||||
t.string "import_source"
|
||||
t.float "repository_size", default: 0.0
|
||||
t.integer "star_count", default: 0, null: false
|
||||
t.text "merge_requests_template"
|
||||
t.boolean "merge_requests_rebase_enabled", default: false
|
||||
t.string "avatar"
|
||||
end
|
||||
|
||||
add_index "projects", ["creator_id"], name: "index_projects_on_creator_id", using: :btree
|
||||
@@ -483,6 +484,7 @@ ActiveRecord::Schema.define(version: 20150116234545) do
|
||||
t.integer "notification_level", default: 1, null: false
|
||||
t.datetime "password_expires_at"
|
||||
t.integer "created_by_id"
|
||||
t.datetime "last_credential_check_at"
|
||||
t.string "avatar"
|
||||
t.string "confirmation_token"
|
||||
t.datetime "confirmed_at"
|
||||
@@ -490,9 +492,8 @@ ActiveRecord::Schema.define(version: 20150116234545) do
|
||||
t.string "unconfirmed_email"
|
||||
t.boolean "hide_no_ssh_key", default: false
|
||||
t.string "website_url", default: "", null: false
|
||||
t.datetime "last_credential_check_at"
|
||||
t.string "github_access_token"
|
||||
t.datetime "admin_email_unsubscribed_at"
|
||||
t.string "github_access_token"
|
||||
t.string "gitlab_access_token"
|
||||
end
|
||||
|
||||
|
||||
+2
-2
@@ -97,7 +97,7 @@ Return values:
|
||||
|
||||
## Sudo
|
||||
|
||||
All API requests support performing an api call as if you were another user, if your private token is for an administration account. You need to pass `sudo` parameter by url or header with an id or username of the user you want to perform the operation as. If passed as header, the header name must be "SUDO" (capitals).
|
||||
All API requests support performing an api call as if you were another user, if your private token is for an administration account. You need to pass `sudo` parameter by URL or header with an id or username of the user you want to perform the operation as. If passed as header, the header name must be "SUDO" (capitals).
|
||||
|
||||
If a non administrative `private_token` is provided then an error message will be returned with status code 403:
|
||||
|
||||
@@ -142,7 +142,7 @@ When listing resources you can pass the following parameters:
|
||||
- `page` (default: `1`) - page number
|
||||
- `per_page` (default: `20`, max: `100`) - number of items to list per page
|
||||
|
||||
[Link headers](http://www.w3.org/wiki/LinkHeader) are send back with each response. These have `rel` prev/next/first/last and contain the relevant URL. Please use these instead of generating your own urls.
|
||||
[Link headers](http://www.w3.org/wiki/LinkHeader) are send back with each response. These have `rel` prev/next/first/last and contain the relevant URL. Please use these instead of generating your own URLs.
|
||||
|
||||
## id vs iid
|
||||
|
||||
|
||||
+26
-6
@@ -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
|
||||
|
||||
@@ -32,7 +32,7 @@ GET /groups/:id
|
||||
|
||||
Parameters:
|
||||
|
||||
- `id` (required) - The ID of a group
|
||||
- `id` (required) - The ID or path of a group
|
||||
|
||||
## New group
|
||||
|
||||
@@ -58,7 +58,7 @@ POST /groups/:id/projects/:project_id
|
||||
|
||||
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
|
||||
|
||||
## Remove group
|
||||
@@ -71,7 +71,27 @@ DELETE /groups/:id
|
||||
|
||||
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
|
||||
|
||||
@@ -128,7 +148,7 @@ POST /groups/:id/members
|
||||
|
||||
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
|
||||
- `access_level` (required) - Project access level
|
||||
|
||||
@@ -142,5 +162,5 @@ DELETE /groups/:id/members/:user_id
|
||||
|
||||
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
|
||||
|
||||
+1
-1
@@ -56,7 +56,7 @@ Parameters:
|
||||
"title": "v1.0",
|
||||
"description": "",
|
||||
"due_date": "2012-07-20",
|
||||
"state": "reopenend",
|
||||
"state": "reopened",
|
||||
"updated_at": "2012-07-04T13:42:48Z",
|
||||
"created_at": "2012-07-04T13:42:48Z"
|
||||
},
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user