diff options
64 files changed, 554 insertions, 127 deletions
diff --git a/CHANGELOG b/CHANGELOG index 28586bdeb8c..50dc6b8945b 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -12,6 +12,11 @@ v 7.2.0 - Test gitlab-shell integration - Repository import timeout increased from 2 to 4 minutes allowing larger repos to be imported +v 7.1.1 + - Fix cpu usage issue in Firefox + - Fix redirect loop when changing password by new user + - Fix 500 error on new merge request page + v 7.1.0 - Remove observers - Improve MR discussions @@ -178,6 +178,7 @@ gem "gitlab_emoji", "~> 0.0.1.1" gem "gon", '~> 5.0.0' gem 'nprogress-rails' gem 'request_store' +gem "virtus" group :development do gem "annotate", "~> 2.6.0.beta2" diff --git a/Gemfile.lock b/Gemfile.lock index c77d20debd9..500e80ce4ee 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -179,12 +179,12 @@ GEM mime-types (~> 1.19) gitlab_emoji (0.0.1.1) emoji (~> 1.0.1) - gitlab_git (6.1.0) + gitlab_git (6.2.1) activesupport (~> 4.0) charlock_holmes (~> 0.6) gitlab-grit (~> 2.6) gitlab-linguist (~> 3.0) - rugged (~> 0.19.0) + rugged (~> 0.21.0) gitlab_meta (7.0) gitlab_omniauth-ldap (1.0.4) net-ldap (~> 0.3.1) @@ -334,7 +334,7 @@ GEM multi_json (~> 1.0) websocket-driver (>= 0.2.0) polyglot (0.3.4) - posix-spawn (0.3.8) + posix-spawn (0.3.9) pry (0.9.12.4) coderay (~> 1.0) method_source (~> 0.8) @@ -436,7 +436,7 @@ GEM ruby-progressbar (1.2.0) rubyntlm (0.1.1) rubypants (0.2.0) - rugged (0.19.0) + rugged (0.21.0) safe_yaml (0.9.7) sanitize (2.1.0) nokogiri (>= 1.4.4) @@ -540,7 +540,7 @@ GEM eventmachine (>= 0.12.8) http_parser.rb (~> 0.5.1) simple_oauth (~> 0.1.4) - tzinfo (1.2.1) + tzinfo (1.2.2) thread_safe (~> 0.1) uglifier (2.3.2) execjs (>= 0.3.0) @@ -692,5 +692,6 @@ DEPENDENCIES unicorn (~> 4.6.3) unicorn-worker-killer version_sorter + virtus webmock wikicloth (= 0.8.1) diff --git a/app/assets/javascripts/application.js.coffee b/app/assets/javascripts/application.js.coffee index a28f76ddd15..1960479321c 100644 --- a/app/assets/javascripts/application.js.coffee +++ b/app/assets/javascripts/application.js.coffee @@ -53,15 +53,40 @@ window.split = (val) -> window.extractLast = (term) -> return split( term ).pop() +window.rstrip = (val) -> + return val.replace(/\s+$/, '') + # Disable button if text field is empty window.disableButtonIfEmptyField = (field_selector, button_selector) -> field = $(field_selector) - closest_submit = field.closest("form").find(button_selector) + closest_submit = field.closest('form').find(button_selector) + + closest_submit.disable() if rstrip(field.val()) is "" + + field.on 'input', -> + if rstrip($(@).val()) is "" + closest_submit.disable() + else + closest_submit.enable() + +# Disable button if any input field with given selector is empty +window.disableButtonIfAnyEmptyField = (form, form_selector, button_selector) -> + closest_submit = form.find(button_selector) + empty = false + form.find('input').filter(form_selector).each -> + empty = true if rstrip($(this).val()) is "" + + if empty + closest_submit.disable() + else + closest_submit.enable() - closest_submit.disable() if field.val() is "" + form.keyup -> + empty = false + form.find('input').filter(form_selector).each -> + empty = true if rstrip($(this).val()) is "" - field.on "input", -> - if $(@).val() is "" + if empty closest_submit.disable() else closest_submit.enable() diff --git a/app/assets/javascripts/diff.js.coffee b/app/assets/javascripts/diff.js.coffee new file mode 100644 index 00000000000..dbe00c487dc --- /dev/null +++ b/app/assets/javascripts/diff.js.coffee @@ -0,0 +1,46 @@ +class Diff + UNFOLD_COUNT = 20 + constructor: -> + $(document).on('click', '.js-unfold', (event) => + target = $(event.target) + unfoldBottom = target.hasClass('js-unfold-bottom') + unfold = true + + [old_line, line_number] = @lineNumbers(target.parent()) + offset = line_number - old_line + + if unfoldBottom + line_number += 1 + since = line_number + to = line_number + UNFOLD_COUNT + else + [prev_old_line, prev_new_line] = @lineNumbers(target.parent().prev()) + line_number -= 1 + to = line_number + if line_number - UNFOLD_COUNT > prev_new_line + 1 + since = line_number - UNFOLD_COUNT + else + since = prev_new_line + 1 + unfold = false + + link = target.parents('.diff-file').attr('data-blob-diff-path') + params = + since: since + to: to + bottom: unfoldBottom + offset: offset + unfold: unfold + + $.get(link, params, (response) => + target.parent().replaceWith(response) + ) + ) + + lineNumbers: (line) -> + return ([0, 0]) unless line.children().length + lines = line.children().slice(0, 2) + line_numbers = ($(l).attr('data-linenumber') for l in lines) + (parseInt(line_number) for line_number in line_numbers) + + +@Diff = Diff diff --git a/app/assets/javascripts/dispatcher.js.coffee b/app/assets/javascripts/dispatcher.js.coffee index ff68b520ad6..a463a2eb194 100644 --- a/app/assets/javascripts/dispatcher.js.coffee +++ b/app/assets/javascripts/dispatcher.js.coffee @@ -23,13 +23,21 @@ class Dispatcher new Issue() when 'projects:milestones:show' new Milestone() - when 'projects:issues:new', 'projects:merge_requests:new' + when 'projects:issues:new' GitLab.GfmAutoComplete.setup() + when 'projects:merge_requests:new' + GitLab.GfmAutoComplete.setup() + new Diff() + when 'projects:merge_requests:show' + new Diff() + when "projects:merge_requests:diffs" + new Diff() when 'dashboard:show' new Dashboard() new Activities() when 'projects:commit:show' new Commit() + new Diff() when 'groups:show', 'projects:show' new Activities() when 'projects:new', 'projects:edit' @@ -42,6 +50,8 @@ class Dispatcher new TreeView() when 'projects:blob:show' new BlobView() + when 'projects:labels:new' + new Labels() switch path.first() when 'admin' then new Admin() diff --git a/app/assets/javascripts/labels.js.coffee b/app/assets/javascripts/labels.js.coffee new file mode 100644 index 00000000000..8e53d6929df --- /dev/null +++ b/app/assets/javascripts/labels.js.coffee @@ -0,0 +1,35 @@ +class Labels + constructor: -> + form = $('.label-form') + @setupLabelForm(form) + @cleanBinding() + @addBinding() + @updateColorPreview + + addBinding: -> + $(document).on 'click', '.suggest-colors a', @setSuggestedColor + $(document).on 'input', 'input#label_color', @updateColorPreview + + cleanBinding: -> + $(document).off 'click', '.suggest-colors a' + $(document).off 'input', 'input#label_color' + + # Initializes the form to disable the save button if no color or title is entered + setupLabelForm: (form) -> + disableButtonIfAnyEmptyField form, '.form-control', form.find('.js-save-button') + + # Updates the the preview color with the hex-color input + updateColorPreview: => + previewColor = $('input#label_color').val() + $('div.label-color-preview').css('background-color', previewColor) + + # Updates the preview color with a click on a suggested color + setSuggestedColor: (e) => + color = $(e.currentTarget).data('color') + $('input#label_color').val(color) + @updateColorPreview() + # Notify the form, that color has changed + $('.label-form').trigger('keyup') + e.preventDefault() + +@Labels = Labels diff --git a/app/assets/javascripts/pager.js.coffee b/app/assets/javascripts/pager.js.coffee index 1f763e8b956..fe83dc0410e 100644 --- a/app/assets/javascripts/pager.js.coffee +++ b/app/assets/javascripts/pager.js.coffee @@ -1,24 +1,21 @@ @Pager = - limit: 0 - offset: 0 - disable: false - init: (limit, preload) -> - @limit = limit + init: (@limit = 0, preload, @disable = false) -> + @loading = $(".loading") if preload @offset = 0 @getOld() else - @offset = limit + @offset = @limit @initLoadMore() getOld: -> - $(".loading").show() + @loading.show() $.ajax type: "GET" url: location.href data: "limit=" + @limit + "&offset=" + @offset - complete: -> - $(".loading").hide() + complete: => + @loading.hide() success: (data) -> Pager.append(data.count, data.html) dataType: "json" @@ -39,6 +36,7 @@ ceaseFire: -> Pager.disable - callback: (i) -> - $(".loading").show() - Pager.getOld() + callback: (i) => + unless @loading.is(':visible') + @loading.show() + Pager.getOld() diff --git a/app/assets/stylesheets/sections/commits.scss b/app/assets/stylesheets/sections/commits.scss index 684e8377a7b..0083d01c460 100644 --- a/app/assets/stylesheets/sections/commits.scss +++ b/app/assets/stylesheets/sections/commits.scss @@ -244,6 +244,7 @@ li.commit { font-family: inherit; padding-left: $left; position: relative; + resize: vertical; z-index: 2; } } diff --git a/app/assets/stylesheets/sections/diff.scss b/app/assets/stylesheets/sections/diff.scss index 88b188dbe8d..488d06919b0 100644 --- a/app/assets/stylesheets/sections/diff.scss +++ b/app/assets/stylesheets/sections/diff.scss @@ -48,6 +48,9 @@ background-color: #8F8; } } + .unfold { + cursor: pointer; + } .file-mode-changed { padding: 10px; diff --git a/app/assets/stylesheets/sections/login.scss b/app/assets/stylesheets/sections/login.scss index 54887b7c401..77ebef690c3 100644 --- a/app/assets/stylesheets/sections/login.scss +++ b/app/assets/stylesheets/sections/login.scss @@ -13,6 +13,10 @@ max-width: 100%; margin-bottom: 20px; } + + &.default-brand-image { + margin: 0 80px; + } } .login-logo{ diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index d0546a441e1..5ffec7f75bf 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -201,15 +201,10 @@ class ApplicationController < ActionController::Base def ldap_security_check if current_user && current_user.requires_ldap_check? - gitlab_ldap_access do |access| - if access.allowed?(current_user) - current_user.last_credential_check_at = Time.now - current_user.save - else - sign_out current_user - flash[:alert] = "Access denied for your LDAP account." - redirect_to new_user_session_path - end + unless Gitlab::LDAP::Access.allowed?(current_user) + sign_out current_user + flash[:alert] = "Access denied for your LDAP account." + redirect_to new_user_session_path end end end diff --git a/app/controllers/omniauth_callbacks_controller.rb b/app/controllers/omniauth_callbacks_controller.rb index ef2afec52dc..3ed6a69c2d8 100644 --- a/app/controllers/omniauth_callbacks_controller.rb +++ b/app/controllers/omniauth_callbacks_controller.rb @@ -21,13 +21,12 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController @user = Gitlab::LDAP::User.find_or_create(oauth) @user.remember_me = true if @user.persisted? - gitlab_ldap_access do |access| - if access.allowed?(@user) - sign_in_and_redirect(@user) - else - flash[:alert] = "Access denied for your LDAP account." - redirect_to new_user_session_path - end + # Do additional LDAP checks for the user filter and EE features + if Gitlab::LDAP::Access.allowed?(@user) + sign_in_and_redirect(@user) + else + flash[:alert] = "Access denied for your LDAP account." + redirect_to new_user_session_path end end diff --git a/app/controllers/projects/blob_controller.rb b/app/controllers/projects/blob_controller.rb index db3d173b98d..7009e3b1bc8 100644 --- a/app/controllers/projects/blob_controller.rb +++ b/app/controllers/projects/blob_controller.rb @@ -25,6 +25,21 @@ class Projects::BlobController < Projects::ApplicationController end end + def diff + @form = UnfoldForm.new(params) + @lines = @blob.data.lines[@form.since - 1..@form.to - 1] + + if @form.bottom? + @match_line = '' + else + lines_length = @lines.length - 1 + line = [@form.since, lines_length].join(',') + @match_line = "@@ -#{line}+#{line} @@" + end + + render layout: false + end + private def blob diff --git a/app/controllers/projects/labels_controller.rb b/app/controllers/projects/labels_controller.rb index d049012f6d8..87d1c942034 100644 --- a/app/controllers/projects/labels_controller.rb +++ b/app/controllers/projects/labels_controller.rb @@ -50,7 +50,10 @@ class Projects::LabelsController < Projects::ApplicationController def destroy @label.destroy - redirect_to project_labels_path(@project), notice: 'Label was removed' + respond_to do |format| + format.html { redirect_to project_labels_path(@project), notice: 'Label was removed' } + format.js { render nothing: true } + end end protected diff --git a/app/controllers/projects/repositories_controller.rb b/app/controllers/projects/repositories_controller.rb index f76ddb34bc4..f30eaadd928 100644 --- a/app/controllers/projects/repositories_controller.rb +++ b/app/controllers/projects/repositories_controller.rb @@ -14,11 +14,7 @@ class Projects::RepositoriesController < Projects::ApplicationController render_404 and return end - storage_path = Gitlab.config.gitlab.repository_downloads_path - - @repository.clean_old_archives - - file_path = @repository.archive_repo(params[:ref], storage_path, params[:format].downcase) + file_path = ArchiveRepositoryService.new.execute(@project, params[:ref], params[:format]) if file_path # Send file to user diff --git a/app/helpers/commits_helper.rb b/app/helpers/commits_helper.rb index 9a8b3928bf4..f61aa259154 100644 --- a/app/helpers/commits_helper.rb +++ b/app/helpers/commits_helper.rb @@ -232,4 +232,16 @@ module CommitsHelper def diff_file_mode_changed?(diff) diff.a_mode && diff.b_mode && diff.a_mode != diff.b_mode end + + def unfold_bottom_class(bottom) + (bottom) ? 'js-unfold-bottom' : '' + end + + def view_file_btn(commit_sha, diff, project) + link_to project_blob_path(project, tree_join(commit_sha, diff.new_path)), + class: 'btn btn-small view-file js-view-file' do + raw('View file @') + content_tag(:span, commit_sha[0..6], + class: 'commit-short-id') + end + end end diff --git a/app/helpers/labels_helper.rb b/app/helpers/labels_helper.rb index 37f3832e54f..5bfba4f14f2 100644 --- a/app/helpers/labels_helper.rb +++ b/app/helpers/labels_helper.rb @@ -4,7 +4,7 @@ module LabelsHelper end def render_colored_label(label) - label_color = label.color || "#428bca" + label_color = label.color || Label::DEFAULT_COLOR text_color = text_color_for_bg(label_color) content_tag :span, class: 'label color-label', style: "background:#{label_color};color:#{text_color}" do diff --git a/app/models/concerns/issuable.rb b/app/models/concerns/issuable.rb index 517e4548624..0a5fe24b5af 100644 --- a/app/models/concerns/issuable.rb +++ b/app/models/concerns/issuable.rb @@ -140,7 +140,8 @@ module Issuable def add_labels_by_names(label_names) label_names.each do |label_name| - label = project.labels.find_or_create_by(title: label_name.strip) + label = project.labels.create_with( + color: Label::DEFAULT_COLOR).find_or_create_by(title: label_name.strip) self.labels << label end end diff --git a/app/models/label.rb b/app/models/label.rb index ce982579675..c32efc7c47f 100644 --- a/app/models/label.rb +++ b/app/models/label.rb @@ -1,13 +1,20 @@ class Label < ActiveRecord::Base + DEFAULT_COLOR = '#428bca' + belongs_to :project has_many :label_links, dependent: :destroy has_many :issues, through: :label_links, source: :target, source_type: 'Issue' - validates :color, format: { with: /\A\#[0-9A-Fa-f]{6}+\Z/ }, allow_blank: true + validates :color, + format: { with: /\A\#[0-9A-Fa-f]{6}+\Z/ }, + allow_blank: false validates :project, presence: true - # Dont allow '?', '&', and ',' for label titles - validates :title, presence: true, format: { with: /\A[^&\?,&]*\z/ } + # Don't allow '?', '&', and ',' for label titles + validates :title, + presence: true, + format: { with: /\A[^&\?,&]*\z/ }, + uniqueness: { scope: :project_id } scope :order_by_name, -> { reorder("labels.title ASC") } diff --git a/app/models/project_services/hipchat_service.rb b/app/models/project_services/hipchat_service.rb index 48fe365760b..256debffc51 100644 --- a/app/models/project_services/hipchat_service.rb +++ b/app/models/project_services/hipchat_service.rb @@ -59,11 +59,15 @@ class HipchatService < Service message = "" message << "#{push[:user_name]} " if before =~ /000000/ - message << "pushed new branch <a href=\"#{project.web_url}/commits/#{ref}\">#{ref}</a> to <a href=\"#{project.web_url}\">#{project.name_with_namespace.gsub!(/\s/,'')}</a>\n" + message << "pushed new branch <a href=\""\ + "#{project.web_url}/commits/#{URI.escape(ref)}\">#{ref}</a>"\ + " to <a href=\"#{project.web_url}\">"\ + "#{project.name_with_namespace.gsub!(/\s/, "")}</a>\n" elsif after =~ /000000/ message << "removed branch #{ref} from <a href=\"#{project.web_url}\">#{project.name_with_namespace.gsub!(/\s/,'')}</a> \n" else - message << "pushed to branch <a href=\"#{project.web_url}/commits/#{ref}\">#{ref}</a> " + message << "pushed to branch <a href=\""\ + "#{project.web_url}/commits/#{URI.escape(ref)}\">#{ref}</a> " message << "of <a href=\"#{project.web_url}\">#{project.name_with_namespace.gsub!(/\s/,'')}</a> " message << "(<a href=\"#{project.web_url}/compare/#{before}...#{after}\">Compare changes</a>)" diff --git a/app/models/user.rb b/app/models/user.rb index 9ab3ea025c3..f1ff76edd15 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -414,7 +414,9 @@ class User < ActiveRecord::Base end def requires_ldap_check? - if ldap_user? + if !Gitlab.config.ldap.enabled + false + elsif ldap_user? !last_credential_check_at || (last_credential_check_at + 1.hour) < Time.now else false diff --git a/app/services/archive_repository_service.rb b/app/services/archive_repository_service.rb new file mode 100644 index 00000000000..8823f6fdc67 --- /dev/null +++ b/app/services/archive_repository_service.rb @@ -0,0 +1,14 @@ +class ArchiveRepositoryService + def execute(project, ref, format) + storage_path = Gitlab.config.gitlab.repository_downloads_path + + unless File.directory?(storage_path) + FileUtils.mkdir_p(storage_path) + end + + format ||= 'tar.gz' + repository = project.repository + repository.clean_old_archives + repository.archive_repo(ref, storage_path, format.downcase) + end +end diff --git a/app/views/layouts/devise.html.haml b/app/views/layouts/devise.html.haml index 00b1959912f..dd70836cdc9 100644 --- a/app/views/layouts/devise.html.haml +++ b/app/views/layouts/devise.html.haml @@ -18,7 +18,7 @@ .brand_text = brand_text - else - .brand-image.hidden-sm.hidden-xs + .brand-image.default-brand-image.hidden-sm.hidden-xs = image_tag 'brand_logo.png' .brand_text.hidden-xs %h2 Open source software to collaborate on code diff --git a/app/views/projects/blob/diff.html.haml b/app/views/projects/blob/diff.html.haml new file mode 100644 index 00000000000..cfb91d6568a --- /dev/null +++ b/app/views/projects/blob/diff.html.haml @@ -0,0 +1,19 @@ +- if @lines.present? + - if @form.unfold? && @form.since != 1 && !@form.bottom? + %tr.line_holder{ id: @form.since } + = render "projects/commits/diffs/match_line", {line: @match_line, + line_old: @form.since, line_new: @form.since, bottom: false} + + - @lines.each_with_index do |line, index| + - line_new = index + @form.since + - line_old = line_new - @form.offset + %tr.line_holder + %td.old_line.diff-line-num{data: {linenumber: line_old}} + = link_to raw(line_old), "#" + %td.new_line= link_to raw(line_new) , "#" + %td.line_content.noteable_line= line + + - if @form.unfold? && @form.bottom? && @form.to < @blob.loc + %tr.line_holder{ id: @form.to } + = render "projects/commits/diffs/match_line", {line: @match_line, + line_old: @form.to, line_new: @form.to, bottom: true} diff --git a/app/views/projects/commits/_diff_file.html.haml b/app/views/projects/commits/_diff_file.html.haml index 9cbcb84aead..6e6107c8849 100644 --- a/app/views/projects/commits/_diff_file.html.haml +++ b/app/views/projects/commits/_diff_file.html.haml @@ -1,15 +1,15 @@ - file = project.repository.blob_for_diff(@commit, diff) - return unless file -.diff-file{id: "diff-#{i}"} +- blob_diff_path = diff_project_blob_path(project, + tree_join(@commit.id, diff.new_path)) +.diff-file{id: "diff-#{i}", data: {blob_diff_path: blob_diff_path }} .diff-header{id: "file-path-#{hexdigest(diff.new_path || diff.old_path)}"} - if diff.deleted_file %span= diff.old_path .diff-btn-group - if @commit.parent_ids.present? - = link_to project_blob_path(project, tree_join(@commit.parent_id, diff.new_path)), { class: 'btn btn-small view-file' } do - View file @ - %span.commit-short-id= @commit.short_id(6) + = view_file_btn(@commit.parent_id, diff, project) - else %span= diff.new_path - if diff_file_mode_changed?(diff) @@ -26,10 +26,7 @@ Edit - = link_to project_blob_path(project, tree_join(@commit.id, diff.new_path)), { class: 'btn btn-small view-file' } do - View file @ - %span.commit-short-id= @commit.short_id(6) - + = view_file_btn(@commit.id, diff, project) .diff-content -# Skipp all non non-supported blobs diff --git a/app/views/projects/commits/_text_file.html.haml b/app/views/projects/commits/_text_file.html.haml index f5b0d711416..756481c1b21 100644 --- a/app/views/projects/commits/_text_file.html.haml +++ b/app/views/projects/commits/_text_file.html.haml @@ -3,18 +3,20 @@ %a.supp_diff_link Changes suppressed. Click to show %table.text-file{class: "#{'hide' if too_big}"} + - last_line = 0 - each_diff_line(diff, index) do |line, type, line_code, line_new, line_old, raw_line| + - last_line = line_new %tr.line_holder{ id: line_code, class: "#{type}" } - if type == "match" - %td.old_line= "..." - %td.new_line= "..." - %td.line_content.matched= line + = render "projects/commits/diffs/match_line", {line: line, + line_old: line_old, line_new: line_new, bottom: false} - else %td.old_line = link_to raw(type == "new" ? " " : line_old), "##{line_code}", id: line_code - if @comments_allowed = link_to_new_diff_note(line_code) - %td.new_line= link_to raw(type == "old" ? " " : line_new) , "##{line_code}", id: line_code + %td.new_line{data: {linenumber: line_new}} + = link_to raw(type == "old" ? " " : line_new) , "##{line_code}", id: line_code %td.line_content{class: "noteable_line #{type} #{line_code}", "line_code" => line_code}= raw diff_line_content(line) - if @reply_allowed @@ -22,6 +24,10 @@ - unless comments.empty? = render "projects/notes/diff_notes_with_reply", notes: comments, line: line + - if last_line > 0 + = render "projects/commits/diffs/match_line", {line: "", + line_old: last_line, line_new: last_line, bottom: true} + - if diff.diff.blank? && diff_file_mode_changed?(diff) .file-mode-changed File mode changed diff --git a/app/views/projects/commits/diffs/_match_line.html.haml b/app/views/projects/commits/diffs/_match_line.html.haml new file mode 100644 index 00000000000..4ebe3379733 --- /dev/null +++ b/app/views/projects/commits/diffs/_match_line.html.haml @@ -0,0 +1,7 @@ +%td.old_line.diff-line-num.unfold.js-unfold{data: {linenumber: line_old}, + class: unfold_bottom_class(bottom)} + \... +%td.new_line.diff-line-num.unfold.js-unfold{data: {linenumber: line_new}, + class: unfold_bottom_class(bottom)} + \... +%td.line_content.matched= line diff --git a/app/views/projects/labels/_form.html.haml b/app/views/projects/labels/_form.html.haml index 2a5c907febe..72a01e1c271 100644 --- a/app/views/projects/labels/_form.html.haml +++ b/app/views/projects/labels/_form.html.haml @@ -28,22 +28,6 @@ .form-actions - = f.submit 'Save', class: 'btn btn-save' + = f.submit 'Save', class: 'btn btn-save js-save-button' = link_to "Cancel", project_labels_path(@project), class: 'btn btn-cancel' - -:coffeescript - updateColorPreview = -> - previewColor = $('input#label_color').val() - $('div.label-color-preview').css('background-color', previewColor) - - $('.suggest-colors a').on 'click', (e) -> - color = $(this).data("color") - $('input#label_color').val(color) - updateColorPreview() - e.preventDefault() - - $('input#label_color').on 'input', -> - updateColorPreview() - - updateColorPreview() diff --git a/app/views/projects/labels/_label.html.haml b/app/views/projects/labels/_label.html.haml index 725bf852078..03a8f0921b7 100644 --- a/app/views/projects/labels/_label.html.haml +++ b/app/views/projects/labels/_label.html.haml @@ -7,4 +7,4 @@ - if can? current_user, :admin_label, @project = link_to 'Edit', edit_project_label_path(@project, label), class: 'btn' - = link_to 'Remove', project_label_path(@project, label), class: 'btn btn-remove', method: :delete, data: {confirm: "Remove this label? Are you sure?"} + = link_to 'Remove', project_label_path(@project, label), class: 'btn btn-remove remove-row', method: :delete, remote: true, data: {confirm: "Remove this label? Are you sure?"} diff --git a/app/views/projects/milestones/_form.html.haml b/app/views/projects/milestones/_form.html.haml index 979c27daa2b..df79125eae6 100644 --- a/app/views/projects/milestones/_form.html.haml +++ b/app/views/projects/milestones/_form.html.haml @@ -21,7 +21,7 @@ .form-group = f.label :description, "Description", class: "control-label" .col-sm-10 - = f.text_area :description, maxlength: 2000, class: "form-control markdown-area", rows: 10 + = f.text_area :description, maxlength: 65535, class: "form-control markdown-area", rows: 10 .hint .pull-left Milestones are parsed with #{link_to "GitLab Flavored Markdown", help_page_path("markdown", "markdown"), target: '_blank'}. .pull-left Attach images (JPG, PNG, GIF) by dragging & dropping or #{link_to "selecting them", '#', class: 'markdown-selector' }. diff --git a/app/workers/post_receive.rb b/app/workers/post_receive.rb index 3b0cf77d42e..f110e20bf00 100644 --- a/app/workers/post_receive.rb +++ b/app/workers/post_receive.rb @@ -12,7 +12,7 @@ class PostReceive log("Check gitlab.yml config for correct gitlab_shell.repos_path variable. \"#{Gitlab.config.gitlab_shell.repos_path}\" does not match \"#{repo_path}\"") end - repo_path.gsub!(/.git$/, "") + repo_path.gsub!(/\.git$/, "") repo_path.gsub!(/^\//, "") project = Project.find_with_namespace(repo_path) diff --git a/config/environments/development.rb b/config/environments/development.rb index 356e26bd68c..03af7f07864 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -23,7 +23,7 @@ Gitlab::Application.configure do config.assets.compress = false # Expands the lines which load the assets - config.assets.debug = true + # config.assets.debug = true # For having correct urls in mails config.action_mailer.default_url_options = { host: 'localhost', port: 3000 } diff --git a/config/gitlab.yml.example b/config/gitlab.yml.example index 7f31fb113c9..d897eb4c02d 100644 --- a/config/gitlab.yml.example +++ b/config/gitlab.yml.example @@ -259,6 +259,11 @@ test: gitlab: host: localhost port: 80 + + # When you run tests we clone and setup gitlab-shell + # In order to setup it correctly you need to specify + # your system username you use to run GitLab + # user: YOUR_USERNAME satellites: path: tmp/tests/gitlab-satellites/ gitlab_shell: diff --git a/config/routes.rb b/config/routes.rb index 261fbb50e38..ce66ea99951 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -193,7 +193,9 @@ Gitlab::Application.routes.draw do end scope module: :projects do - resources :blob, only: [:show, :destroy], constraints: {id: /.+/} + resources :blob, only: [:show, :destroy], constraints: { id: /.+/ } do + get :diff, on: :member + end resources :raw, only: [:show], constraints: {id: /.+/} resources :tree, only: [:show], constraints: {id: /.+/, format: /(html|js)/ } resources :edit_tree, only: [:show, :update], constraints: { id: /.+/ }, path: 'edit' do diff --git a/doc/api/issues.md b/doc/api/issues.md index f775d502a6d..a4b3b3e9918 100644 --- a/doc/api/issues.md +++ b/doc/api/issues.md @@ -157,6 +157,9 @@ Parameters: - `milestone_id` (optional) - The ID of a milestone to assign issue - `labels` (optional) - Comma-separated label names for an issue +If the operation is successful, 200 and the newly created issue is returned. +If an error occurs, an error number and a message explaining the reason is returned. + ## Edit issue Updates an existing project issue. This function is also used to mark an issue as closed. @@ -176,6 +179,9 @@ Parameters: - `labels` (optional) - Comma-separated label names for an issue - `state_event` (optional) - The state event of an issue ('close' to close issue and 'reopen' to reopen it) +If the operation is successful, 200 and the updated issue is returned. +If an error occurs, an error number and a message explaining the reason is returned. + ## Delete existing issue (**Deprecated**) The function is deprecated and returns a `405 Method Not Allowed` error if called. An issue gets now closed and is done by calling `PUT /projects/:id/issues/:issue_id` with parameter `closed` set to 1. diff --git a/doc/api/merge_requests.md b/doc/api/merge_requests.md index a46472a0812..230f572fc3b 100644 --- a/doc/api/merge_requests.md +++ b/doc/api/merge_requests.md @@ -42,7 +42,8 @@ Parameters: "name": "Administrator", "state": "active", "created_at": "2012-04-29T08:46:00Z" - } + }, + "description":"fixed login page css paddings" } ] ``` @@ -86,7 +87,8 @@ Parameters: "name": "Administrator", "state": "active", "created_at": "2012-04-29T08:46:00Z" - } + }, + "description":"fixed login page css paddings" } ``` @@ -132,10 +134,14 @@ Parameters: "name": "Administrator", "state": "active", "created_at": "2012-04-29T08:46:00Z" - } + }, + "description":"fixed login page css paddings" } ``` +If the operation is successful, 200 and the newly created merge request is returned. +If an error occurs, an error number and a message explaining the reason is returned. + ## Update MR Updates an existing merge request. You can change branches, title, or even close the MR. @@ -183,15 +189,18 @@ Parameters: } ``` +If the operation is successful, 200 and the updated merge request is returned. +If an error occurs, an error number and a message explaining the reason is returned. + ## Accept MR -Merge changes submitted with MR usign this API. +Merge changes submitted with MR using this API. If merge success you get 200 OK. If it has some conflicts and can not be merged - you get 405 and error message 'Branch cannot be merged' -If merge request is already merged or closed - you get 405 and error message 'Method Not Allowed' +If merge request is already merged or closed - you get 405 and error message 'Method Not Allowed' If you dont have permissions to accept this merge request - you get 401 diff --git a/doc/install/installation.md b/doc/install/installation.md index e502a3ed82c..44742984ca9 100644 --- a/doc/install/installation.md +++ b/doc/install/installation.md @@ -69,7 +69,7 @@ Is the system packaged Git too old? Remove it and compile from source. # Download and compile from source cd /tmp - curl --progress https://www.kernel.org/pub/software/scm/git/git-2.0.0.tar.gz | tar xz + curl -L --progress https://www.kernel.org/pub/software/scm/git/git-2.0.0.tar.gz | tar xz cd git-2.0.0/ make prefix=/usr/local all @@ -95,7 +95,7 @@ Remove the old Ruby 1.8 if present Download Ruby and compile it: mkdir /tmp/ruby && cd /tmp/ruby - curl --progress ftp://ftp.ruby-lang.org/pub/ruby/2.1/ruby-2.1.2.tar.gz | tar xz + curl -L --progress ftp://ftp.ruby-lang.org/pub/ruby/2.1/ruby-2.1.2.tar.gz | tar xz cd ruby-2.1.2 ./configure --disable-install-rdoc make diff --git a/doc/update/4.0-to-4.1.md b/doc/update/4.0-to-4.1.md index d5e5d62fb15..4149ed6b08d 100644 --- a/doc/update/4.0-to-4.1.md +++ b/doc/update/4.0-to-4.1.md @@ -36,7 +36,7 @@ sudo -u gitlab -H bundle exec rake db:migrate RAILS_ENV=production sudo mv /etc/init.d/gitlab /etc/init.d/gitlab.old # get new one using sidekiq -sudo curl --output /etc/init.d/gitlab https://raw.github.com/gitlabhq/gitlab-recipes/4-1-stable/init.d/gitlab +sudo curl -L --output /etc/init.d/gitlab https://raw.github.com/gitlabhq/gitlab-recipes/4-1-stable/init.d/gitlab sudo chmod +x /etc/init.d/gitlab ``` diff --git a/doc/update/4.2-to-5.0.md b/doc/update/4.2-to-5.0.md index 27cc72c1cb6..6ec153f6245 100644 --- a/doc/update/4.2-to-5.0.md +++ b/doc/update/4.2-to-5.0.md @@ -116,7 +116,7 @@ sudo chmod -R u+rwX /home/git/gitlab/tmp/pids ```bash # init.d sudo rm /etc/init.d/gitlab -sudo curl --output /etc/init.d/gitlab https://raw.github.com/gitlabhq/gitlab-recipes/5-0-stable/init.d/gitlab +sudo curl -L --output /etc/init.d/gitlab https://raw.github.com/gitlabhq/gitlab-recipes/5-0-stable/init.d/gitlab sudo chmod +x /etc/init.d/gitlab # unicorn diff --git a/doc/update/5.0-to-5.1.md b/doc/update/5.0-to-5.1.md index b04f3065a17..0e597abb1a9 100644 --- a/doc/update/5.0-to-5.1.md +++ b/doc/update/5.0-to-5.1.md @@ -52,7 +52,7 @@ sudo -u git -H bundle exec rake assets:precompile RAILS_ENV=production ```bash # init.d sudo rm /etc/init.d/gitlab -sudo curl --output /etc/init.d/gitlab https://raw.github.com/gitlabhq/gitlab-recipes/5-1-stable/init.d/gitlab +sudo curl -L --output /etc/init.d/gitlab https://raw.github.com/gitlabhq/gitlab-recipes/5-1-stable/init.d/gitlab sudo chmod +x /etc/init.d/gitlab ``` diff --git a/doc/update/5.2-to-5.3.md b/doc/update/5.2-to-5.3.md index e39e18d4211..9851f7b2730 100644 --- a/doc/update/5.2-to-5.3.md +++ b/doc/update/5.2-to-5.3.md @@ -50,7 +50,7 @@ sudo -u git -H bundle exec rake assets:precompile RAILS_ENV=production ```bash sudo rm /etc/init.d/gitlab -sudo curl --output /etc/init.d/gitlab https://raw.github.com/gitlabhq/gitlabhq/5-3-stable/lib/support/init.d/gitlab +sudo curl -L --output /etc/init.d/gitlab https://raw.github.com/gitlabhq/gitlabhq/5-3-stable/lib/support/init.d/gitlab sudo chmod +x /etc/init.d/gitlab ``` diff --git a/doc/update/5.3-to-5.4.md b/doc/update/5.3-to-5.4.md index e1749f133b3..b130f4c65bb 100644 --- a/doc/update/5.3-to-5.4.md +++ b/doc/update/5.3-to-5.4.md @@ -54,7 +54,7 @@ sudo -u git -H bundle exec rake assets:precompile RAILS_ENV=production ```bash sudo rm /etc/init.d/gitlab -sudo curl --output /etc/init.d/gitlab https://raw.github.com/gitlabhq/gitlabhq/5-4-stable/lib/support/init.d/gitlab +sudo curl -L --output /etc/init.d/gitlab https://raw.github.com/gitlabhq/gitlabhq/5-4-stable/lib/support/init.d/gitlab sudo chmod +x /etc/init.d/gitlab ``` diff --git a/doc/update/6.9-to-7.0.md b/doc/update/6.9-to-7.0.md index 806a714c49b..99ec441e275 100644 --- a/doc/update/6.9-to-7.0.md +++ b/doc/update/6.9-to-7.0.md @@ -32,7 +32,7 @@ Download and compile Ruby: ```bash mkdir /tmp/ruby && cd /tmp/ruby -curl --progress ftp://ftp.ruby-lang.org/pub/ruby/2.1/ruby-2.1.2.tar.gz | tar xz +curl -L --progress ftp://ftp.ruby-lang.org/pub/ruby/2.1/ruby-2.1.2.tar.gz | tar xz cd ruby-2.1.2 ./configure --disable-install-rdoc make diff --git a/doc/update/7.0-to-7.1.md b/doc/update/7.0-to-7.1.md index ba2d9a23a36..569f9160eb3 100644 --- a/doc/update/7.0-to-7.1.md +++ b/doc/update/7.0-to-7.1.md @@ -32,7 +32,7 @@ Download and compile Ruby: ```bash mkdir /tmp/ruby && cd /tmp/ruby -curl --progress ftp://ftp.ruby-lang.org/pub/ruby/2.1/ruby-2.1.2.tar.gz | tar xz +curl -L --progress ftp://ftp.ruby-lang.org/pub/ruby/2.1/ruby-2.1.2.tar.gz | tar xz cd ruby-2.1.2 ./configure --disable-install-rdoc make diff --git a/features/project/issues/labels.feature b/features/project/issues/labels.feature index 4a37b6dc9fa..29cf5307271 100644 --- a/features/project/issues/labels.feature +++ b/features/project/issues/labels.feature @@ -10,7 +10,7 @@ Feature: Project Labels And I should see label "feature" Scenario: I create new label - Given I visit new label page + Given I visit project "Shop" new label page When I submit new label 'support' Then I should see label 'support' @@ -23,3 +23,21 @@ Feature: Project Labels Scenario: I remove label When I remove label 'bug' Then I should not see label 'bug' + + Scenario: I create a label with invalid color + Given I visit project "Shop" new label page + When I submit new label with invalid color + Then I should see label color error message + + Scenario: I create a label that already exists + Given I visit project "Shop" new label page + When I submit new label 'bug' + Then I should see label label exist error message + + Scenario: I create the same label on another project + Given I own project "Forum" + And I visit project "Forum" labels page + And I visit project "Forum" new label page + When I submit new label 'bug' + Then I should see label 'bug' + diff --git a/features/project/merge_requests.feature b/features/project/merge_requests.feature index d4c71ba336e..8b6c296dfe6 100644 --- a/features/project/merge_requests.feature +++ b/features/project/merge_requests.feature @@ -139,3 +139,11 @@ Feature: Project Merge Requests And I click link "Show inline discussion" of the second file Then I should see a comment like "Line is wrong" in the second file And I should still see a comment like "Line is correct" in the first file + + @javascript + Scenario: I unfold diff + Given project "Shop" have "Bug NS-05" open merge request with diffs inside + And I visit merge request page "Bug NS-05" + And I switch to the diff tab + And I unfold diff + Then I should see additional file lines diff --git a/features/steps/project/labels.rb b/features/steps/project/labels.rb index 3d9aa29299c..8320405e096 100644 --- a/features/steps/project/labels.rb +++ b/features/steps/project/labels.rb @@ -31,6 +31,36 @@ class ProjectLabels < Spinach::FeatureSteps click_button 'Save' end + step 'I submit new label \'bug\'' do + fill_in 'Title', with: 'bug' + fill_in 'Background Color', with: '#F95610' + click_button 'Save' + end + + step 'I submit new label with invalid color' do + fill_in 'Title', with: 'support' + fill_in 'Background Color', with: '#12' + click_button 'Save' + end + + step 'I should see label label exist error message' do + within '.label-form' do + page.should have_content 'Title has already been taken' + end + end + + step 'I should see label color error message' do + within '.label-form' do + page.should have_content 'Color is invalid' + end + end + + step 'I should see label \'bug\'' do + within '.manage-labels-list' do + page.should have_content 'bug' + end + end + step 'I should not see label \'bug\'' do within '.manage-labels-list' do page.should_not have_content 'bug' diff --git a/features/steps/project/merge_requests.rb b/features/steps/project/merge_requests.rb index f0007a039e4..05d3e5067c5 100644 --- a/features/steps/project/merge_requests.rb +++ b/features/steps/project/merge_requests.rb @@ -242,6 +242,14 @@ class ProjectMergeRequests < Spinach::FeatureSteps end end + step 'I unfold diff' do + first('.js-unfold').click + end + + step 'I should see additional file lines' do + expect(first('.text-file')).to have_content('.bundle') + end + def project @project ||= Project.find_by!(name: "Shop") end diff --git a/features/steps/shared/paths.rb b/features/steps/shared/paths.rb index 4e97dba20b3..0d06383509f 100644 --- a/features/steps/shared/paths.rb +++ b/features/steps/shared/paths.rb @@ -287,10 +287,22 @@ module SharedPaths end step 'I visit project "Shop" labels page' do + project = Project.find_by(name: 'Shop') visit project_labels_path(project) end - step 'I visit new label page' do + step 'I visit project "Forum" labels page' do + project = Project.find_by(name: 'Forum') + visit project_labels_path(project) + end + + step 'I visit project "Shop" new label page' do + project = Project.find_by(name: 'Shop') + visit new_project_label_path(project) + end + + step 'I visit project "Forum" new label page' do + project = Project.find_by(name: 'Forum') visit new_project_label_path(project) end diff --git a/lib/api/entities.rb b/lib/api/entities.rb index 8731db59e57..fc7d391fd30 100644 --- a/lib/api/entities.rb +++ b/lib/api/entities.rb @@ -137,6 +137,8 @@ module API expose :author, :assignee, using: Entities::UserBasic expose :source_project_id, :target_project_id expose :label_names, as: :labels + expose :description + expose :milestone, using: Entities::Milestone end class SSHKey < Grape::Entity diff --git a/lib/api/helpers.rb b/lib/api/helpers.rb index 8189e433789..d36b29a00b1 100644 --- a/lib/api/helpers.rb +++ b/lib/api/helpers.rb @@ -112,6 +112,21 @@ module API ActionController::Parameters.new(attrs).permit! end + # Helper method for validating all labels against its names + def validate_label_params(params) + if params[:labels].present? + params[:labels].split(',').each do |label_name| + label = user_project.labels.create_with( + color: Label::DEFAULT_COLOR).find_or_initialize_by( + title: label_name.strip) + if label.invalid? + return true + end + end + end + false + end + # error helpers def forbidden! diff --git a/lib/api/issues.rb b/lib/api/issues.rb index b29118b2fd8..055529ccbd8 100644 --- a/lib/api/issues.rb +++ b/lib/api/issues.rb @@ -51,12 +51,18 @@ module API required_attributes! [:title] attrs = attributes_for_keys [:title, :description, :assignee_id, :milestone_id] + # Validate label names in advance + if validate_label_params(params) + return render_api_error!('Label names invalid', 405) + end + issue = ::Issues::CreateService.new(user_project, current_user, attrs).execute if issue.valid? - # Find or create labels and attach to issue + # Find or create labels and attach to issue. Labels are valid because + # we already checked its name, so there can't be an error here if params[:labels].present? - issue.add_labels_by_names(params[:labels].split(",")) + issue.add_labels_by_names(params[:labels].split(',')) end present issue, with: Entities::Issue @@ -83,12 +89,19 @@ module API authorize! :modify_issue, issue attrs = attributes_for_keys [:title, :description, :assignee_id, :milestone_id, :state_event] + # Validate label names in advance + if validate_label_params(params) + return render_api_error!('Label names invalid', 405) + end + issue = ::Issues::UpdateService.new(user_project, current_user, attrs).execute(issue) if issue.valid? - # Find or create labels and attach to issue + # Find or create labels and attach to issue. Labels are valid because + # we already checked its name, so there can't be an error here if params[:labels].present? - issue.add_labels_by_names(params[:labels].split(",")) + # Create and add labels to the new created issue + issue.add_labels_by_names(params[:labels].split(',')) end present issue, with: Entities::Issue diff --git a/lib/api/merge_requests.rb b/lib/api/merge_requests.rb index acca7cb6bad..0d765f9280e 100644 --- a/lib/api/merge_requests.rb +++ b/lib/api/merge_requests.rb @@ -76,6 +76,12 @@ module API authorize! :write_merge_request, user_project required_attributes! [:source_branch, :target_branch, :title] attrs = attributes_for_keys [:source_branch, :target_branch, :assignee_id, :title, :target_project_id, :description] + + # Validate label names in advance + if validate_label_params(params) + return render_api_error!('Label names invalid', 405) + end + merge_request = ::MergeRequests::CreateService.new(user_project, current_user, attrs).execute if merge_request.valid? @@ -109,6 +115,12 @@ module API attrs = attributes_for_keys [:source_branch, :target_branch, :assignee_id, :title, :state_event, :description] merge_request = user_project.merge_requests.find(params[:merge_request_id]) authorize! :modify_merge_request, merge_request + + # Validate label names in advance + if validate_label_params(params) + return render_api_error!('Label names invalid', 405) + end + merge_request = ::MergeRequests::UpdateService.new(user_project, current_user, attrs).execute(merge_request) if merge_request.valid? diff --git a/lib/api/repositories.rb b/lib/api/repositories.rb index 461ce4e59cf..42068bb343d 100644 --- a/lib/api/repositories.rb +++ b/lib/api/repositories.rb @@ -115,21 +115,13 @@ module API # GET /projects/:id/repository/archive get ":id/repository/archive", requirements: { format: Gitlab::Regex.archive_formats_regex } do authorize! :download_code, user_project - repo = user_project.repository - ref = params[:sha] - format = params[:format] - storage_path = Gitlab.config.gitlab.repository_downloads_path + file_path = ArchiveRepositoryService.new.execute(user_project, params[:sha], params[:format]) - file_path = repo.archive_repo(ref, storage_path, format) if file_path && File.exists?(file_path) data = File.open(file_path, 'rb').read - header["Content-Disposition"] = "attachment; filename=\"#{File.basename(file_path)}\"" - content_type MIME::Types.type_for(file_path).first.content_type - env['api.format'] = :binary - present data else not_found! diff --git a/lib/gitlab/diff_parser.rb b/lib/gitlab/diff_parser.rb index 14bbb328637..b244295027e 100644 --- a/lib/gitlab/diff_parser.rb +++ b/lib/gitlab/diff_parser.rb @@ -30,7 +30,7 @@ module Gitlab line_new = line.match(/\+[0-9]*/)[0].to_i.abs rescue 0 next if line_old == 1 && line_new == 1 #top of file - yield(full_line, type, nil, nil, nil) + yield(full_line, type, nil, line_new, line_old) next else type = identification_type(line) diff --git a/lib/gitlab/ldap/access.rb b/lib/gitlab/ldap/access.rb index 4e48ff11871..62709a12942 100644 --- a/lib/gitlab/ldap/access.rb +++ b/lib/gitlab/ldap/access.rb @@ -9,6 +9,19 @@ module Gitlab end end + def self.allowed?(user) + self.open do |access| + if access.allowed?(user) + # GitLab EE LDAP code goes here + user.last_credential_check_at = Time.now + user.save + true + else + false + end + end + end + def initialize(adapter=nil) @adapter = adapter end diff --git a/lib/gitlab/user_access.rb b/lib/gitlab/user_access.rb index 16df21b49ba..4885baf9526 100644 --- a/lib/gitlab/user_access.rb +++ b/lib/gitlab/user_access.rb @@ -3,13 +3,8 @@ module Gitlab def self.allowed?(user) return false if user.blocked? - if Gitlab.config.ldap.enabled - if user.ldap_user? - # Check if LDAP user exists and match LDAP user_filter - Gitlab::LDAP::Access.open do |adapter| - return false unless adapter.allowed?(user) - end - end + if user.requires_ldap_check? + return false unless Gitlab::LDAP::Access.allowed?(user) end true diff --git a/lib/gt_one_coercion.rb b/lib/gt_one_coercion.rb new file mode 100644 index 00000000000..ef2dc09767c --- /dev/null +++ b/lib/gt_one_coercion.rb @@ -0,0 +1,5 @@ +class GtOneCoercion < Virtus::Attribute + def coerce(value) + [1, value.to_i].max + end +end diff --git a/lib/tasks/gitlab/check.rake b/lib/tasks/gitlab/check.rake index 3f219261abe..032ed5ee370 100644 --- a/lib/tasks/gitlab/check.rake +++ b/lib/tasks/gitlab/check.rake @@ -318,7 +318,8 @@ namespace :gitlab do options = { "user.name" => "GitLab", - "user.email" => Gitlab.config.gitlab.email_from + "user.email" => Gitlab.config.gitlab.email_from, + "core.autocrlf" => "input" } correct_options = options.map do |name, value| run(%W(git config --global --get #{name})).try(:squish) == value @@ -330,7 +331,8 @@ namespace :gitlab do puts "no".red try_fixing_it( sudo_gitlab("git config --global user.name \"#{options["user.name"]}\""), - sudo_gitlab("git config --global user.email \"#{options["user.email"]}\"") + sudo_gitlab("git config --global user.email \"#{options["user.email"]}\""), + sudo_gitlab("git config --global core.autocrlf \"#{options["core.autocrlf"]}\"") ) for_more_information( see_installation_guide_section "GitLab" diff --git a/lib/unfold_form.rb b/lib/unfold_form.rb new file mode 100644 index 00000000000..46b12beeaaf --- /dev/null +++ b/lib/unfold_form.rb @@ -0,0 +1,11 @@ +require_relative 'gt_one_coercion' + +class UnfoldForm + include Virtus.model + + attribute :since, GtOneCoercion + attribute :to, GtOneCoercion + attribute :bottom, Boolean + attribute :unfold, Boolean, default: true + attribute :offset, Integer +end diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index ef6b8a94502..7221328a45f 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -312,6 +312,40 @@ describe User do end end + describe :requires_ldap_check? do + let(:user) { User.new } + + it 'is false when LDAP is disabled' do + # Create a condition which would otherwise cause 'true' to be returned + user.stub(ldap_user?: true) + user.last_credential_check_at = nil + expect(user.requires_ldap_check?).to be_false + end + + context 'when LDAP is enabled' do + before { Gitlab.config.ldap.stub(enabled: true) } + + it 'is false for non-LDAP users' do + user.stub(ldap_user?: false) + expect(user.requires_ldap_check?).to be_false + end + + context 'and when the user is an LDAP user' do + before { user.stub(ldap_user?: true) } + + it 'is true when the user has never had an LDAP check before' do + user.last_credential_check_at = nil + expect(user.requires_ldap_check?).to be_true + end + + it 'is true when the last LDAP check happened over 1 hour ago' do + user.last_credential_check_at = 2.hours.ago + expect(user.requires_ldap_check?).to be_true + end + end + end + end + describe '#full_website_url' do let(:user) { create(:user) } diff --git a/spec/requests/api/issues_spec.rb b/spec/requests/api/issues_spec.rb index dff7f20cb32..d8e8e4f5035 100644 --- a/spec/requests/api/issues_spec.rb +++ b/spec/requests/api/issues_spec.rb @@ -5,6 +5,10 @@ describe API::API, api: true do let(:user) { create(:user) } let!(:project) { create(:project, namespace: user.namespace ) } let!(:issue) { create(:issue, author: user, assignee: user, project: project) } + let!(:label) do + create(:label, title: 'label', color: '#FFAABB', project: project) + end + before { project.team << [user, :reporter] } describe "GET /issues" do @@ -68,6 +72,14 @@ describe API::API, api: true do post api("/projects/#{project.id}/issues", user), labels: 'label, label2' response.status.should == 400 end + + it 'should return 405 on invalid label names' do + post api("/projects/#{project.id}/issues", user), + title: 'new issue', + labels: 'label, ?' + response.status.should == 405 + json_response['message'].should == 'Label names invalid' + end end describe "PUT /projects/:id/issues/:issue_id to update only title" do @@ -84,6 +96,14 @@ describe API::API, api: true do title: 'updated title' response.status.should == 404 end + + it 'should return 405 on invalid label names' do + put api("/projects/#{project.id}/issues/#{issue.id}", user), + title: 'updated title', + labels: 'label, ?' + response.status.should == 405 + json_response['message'].should == 'Label names invalid' + end end describe "PUT /projects/:id/issues/:issue_id to update state and label" do diff --git a/spec/requests/api/merge_requests_spec.rb b/spec/requests/api/merge_requests_spec.rb index 3611d9d6dc3..58cf7f139dc 100644 --- a/spec/requests/api/merge_requests_spec.rb +++ b/spec/requests/api/merge_requests_spec.rb @@ -78,9 +78,14 @@ describe API::API, api: true do context 'between branches projects' do it "should return merge_request" do post api("/projects/#{project.id}/merge_requests", user), - title: 'Test merge_request', source_branch: "stable", target_branch: "master", author: user + title: 'Test merge_request', + source_branch: 'stable', + target_branch: 'master', + author: user, + labels: 'label, label2' response.status.should == 201 json_response['title'].should == 'Test merge_request' + json_response['labels'].should == ['label', 'label2'] end it "should return 422 when source_branch equals target_branch" do @@ -106,6 +111,17 @@ describe API::API, api: true do target_branch: 'master', source_branch: 'stable' response.status.should == 400 end + + it 'should return 405 on invalid label names' do + post api("/projects/#{project.id}/merge_requests", user), + title: 'Test merge_request', + source_branch: 'stable', + target_branch: 'master', + author: user, + labels: 'label, ?' + response.status.should == 405 + json_response['message'].should == 'Label names invalid' + end end context 'forked projects' do @@ -235,6 +251,15 @@ describe API::API, api: true do response.status.should == 200 json_response['target_branch'].should == 'wiki' end + + it 'should return 405 on invalid label names' do + put api("/projects/#{project.id}/merge_request/#{merge_request.id}", + user), + title: 'new issue', + labels: 'label, ?' + response.status.should == 405 + json_response['message'].should == 'Label names invalid' + end end describe "POST /projects/:id/merge_request/:merge_request_id/comments" do |