diff options
author | Douwe Maan <douwe@gitlab.com> | 2015-08-20 12:19:19 -0700 |
---|---|---|
committer | Douwe Maan <douwe@gitlab.com> | 2015-08-20 12:19:19 -0700 |
commit | 3d51a6d4351c6a15c92762f5710a967374d0c59b (patch) | |
tree | 10c5e87e0add51ef0bdcc9be42ac0176907a080c /app | |
parent | 8ec5fb138dde9937814ac138352177399d3e776d (diff) | |
parent | 8819007c83fdf1ac642836640a37cc541f6eddc6 (diff) | |
download | gitlab-ce-3d51a6d4351c6a15c92762f5710a967374d0c59b.tar.gz |
Merge branch 'master' into reply-by-email
Diffstat (limited to 'app')
82 files changed, 841 insertions, 542 deletions
diff --git a/app/assets/javascripts/merge_request_widget.js.coffee b/app/assets/javascripts/merge_request_widget.js.coffee index 5ab91261d75..995a2f24093 100644 --- a/app/assets/javascripts/merge_request_widget.js.coffee +++ b/app/assets/javascripts/merge_request_widget.js.coffee @@ -19,7 +19,7 @@ class @MergeRequestWidget when 'merged' location.reload() else - setTimeout(merge_request_widget.mergeInProgress, 3000) + setTimeout(merge_request_widget.mergeInProgress, 2000) dataType: 'json' getMergeStatus: -> diff --git a/app/assets/stylesheets/generic/common.scss b/app/assets/stylesheets/generic/common.scss index d36530169a9..bf5c7a8d75e 100644 --- a/app/assets/stylesheets/generic/common.scss +++ b/app/assets/stylesheets/generic/common.scss @@ -373,3 +373,23 @@ table { border-color: #EEE !important; } } + +.center-top-menu { + border-bottom: 1px solid #EEE; + list-style: none; + text-align: center; + padding-bottom: 15px; + margin-bottom: 15px; + + li { + display: inline-block; + + a { + padding: 10px; + } + + &.active a { + color: #666; + } + } +} diff --git a/app/assets/stylesheets/pages/explore.scss b/app/assets/stylesheets/pages/explore.scss index 9b92128624c..da06fe9954e 100644 --- a/app/assets/stylesheets/pages/explore.scss +++ b/app/assets/stylesheets/pages/explore.scss @@ -6,3 +6,11 @@ font-size: 30px; } } + +.explore-trending-block { + .lead { + line-height: 32px; + font-size: 18px; + margin-top: 10px; + } +} diff --git a/app/controllers/admin/application_settings_controller.rb b/app/controllers/admin/application_settings_controller.rb index c7c643db401..f38e07af84b 100644 --- a/app/controllers/admin/application_settings_controller.rb +++ b/app/controllers/admin/application_settings_controller.rb @@ -29,6 +29,15 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController end end + import_sources = params[:application_setting][:import_sources] + if import_sources.nil? + params[:application_setting][:import_sources] = [] + else + import_sources.map! do |source| + source.to_str + end + end + params.require(:application_setting).permit( :default_projects_limit, :default_branch_protection, @@ -47,6 +56,7 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController :version_check_enabled, :user_oauth_applications, restricted_visibility_levels: [], + import_sources: [] ) end end diff --git a/app/controllers/admin/projects_controller.rb b/app/controllers/admin/projects_controller.rb index da5f5bb83fa..ae1de06b983 100644 --- a/app/controllers/admin/projects_controller.rb +++ b/app/controllers/admin/projects_controller.rb @@ -9,6 +9,7 @@ class Admin::ProjectsController < Admin::ApplicationController @projects = @projects.where("visibility_level IN (?)", params[:visibility_levels]) if params[:visibility_levels].present? @projects = @projects.with_push if params[:with_push].present? @projects = @projects.abandoned if params[:abandoned].present? + @projects = @projects.non_archived unless params[:with_archived].present? @projects = @projects.search(params[:name]) if params[:name].present? @projects = @projects.sort(@sort = params[:sort]) @projects = @projects.includes(:namespace).order("namespaces.path, projects.name ASC").page(params[:page]).per(PER_PAGE) diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 3ce8dbc9407..12d439b0b31 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -20,7 +20,7 @@ class ApplicationController < ActionController::Base protect_from_forgery with: :exception helper_method :abilities, :can?, :current_application_settings - helper_method :github_import_enabled?, :gitlab_import_enabled?, :bitbucket_import_enabled? + helper_method :import_sources_enabled?, :github_import_enabled?, :github_import_configured?, :gitlab_import_enabled?, :gitlab_import_configured?, :bitbucket_import_enabled?, :bitbucket_import_configured?, :gitorious_import_enabled?, :google_code_import_enabled?, :git_import_enabled? rescue_from Encoding::CompatibilityError do |exception| log_exception(exception) @@ -298,15 +298,43 @@ class ApplicationController < ActionController::Base @issuable_finder.execute end + def import_sources_enabled? + !current_application_settings.import_sources.empty? + end + def github_import_enabled? + current_application_settings.import_sources.include?('github') + end + + def github_import_configured? Gitlab::OAuth::Provider.enabled?(:github) end def gitlab_import_enabled? + request.host != 'gitlab.com' && current_application_settings.import_sources.include?('gitlab') + end + + def gitlab_import_configured? Gitlab::OAuth::Provider.enabled?(:gitlab) end def bitbucket_import_enabled? + current_application_settings.import_sources.include?('bitbucket') + end + + def bitbucket_import_configured? Gitlab::OAuth::Provider.enabled?(:bitbucket) && Gitlab::BitbucketImport.public_key.present? end + + def gitorious_import_enabled? + current_application_settings.import_sources.include?('gitorious') + end + + def google_code_import_enabled? + current_application_settings.import_sources.include?('google_code') + end + + def git_import_enabled? + current_application_settings.import_sources.include?('git') + end end diff --git a/app/controllers/explore/projects_controller.rb b/app/controllers/explore/projects_controller.rb index e9bcb44f6b3..6c733c1ae4d 100644 --- a/app/controllers/explore/projects_controller.rb +++ b/app/controllers/explore/projects_controller.rb @@ -7,6 +7,7 @@ class Explore::ProjectsController < Explore::ApplicationController @tags = @projects.tags_on(:tags) @projects = @projects.tagged_with(params[:tag]) if params[:tag].present? @projects = @projects.where(visibility_level: params[:visibility_level]) if params[:visibility_level].present? + @projects = @projects.non_archived @projects = @projects.search(params[:search]) if params[:search].present? @projects = @projects.sort(@sort = params[:sort]) @projects = @projects.includes(:namespace).page(params[:page]).per(PER_PAGE) @@ -14,6 +15,7 @@ class Explore::ProjectsController < Explore::ApplicationController def trending @trending_projects = TrendingProjectsFinder.new.execute(current_user) + @trending_projects = @trending_projects.non_archived @trending_projects = @trending_projects.page(params[:page]).per(PER_PAGE) end diff --git a/app/controllers/help_controller.rb b/app/controllers/help_controller.rb index 8a45dc8860d..71831c5380d 100644 --- a/app/controllers/help_controller.rb +++ b/app/controllers/help_controller.rb @@ -10,7 +10,8 @@ class HelpController < ApplicationController respond_to do |format| format.any(:markdown, :md, :html) do - path = Rails.root.join('doc', @category, "#{@file}.md") + # Note: We are purposefully NOT using `Rails.root.join` + path = File.join(Rails.root, 'doc', @category, "#{@file}.md") if File.exist?(path) @markdown = File.read(path) @@ -24,7 +25,8 @@ class HelpController < ApplicationController # Allow access to images in the doc folder format.any(:png, :gif, :jpeg) do - path = Rails.root.join('doc', @category, "#{@file}.#{params[:format]}") + # Note: We are purposefully NOT using `Rails.root.join` + path = File.join(Rails.root, 'doc', @category, "#{@file}.#{params[:format]}") if File.exist?(path) send_file(path, disposition: 'inline') diff --git a/app/controllers/import/gitorious_controller.rb b/app/controllers/import/gitorious_controller.rb index c121d2de7cb..f24cdb3709a 100644 --- a/app/controllers/import/gitorious_controller.rb +++ b/app/controllers/import/gitorious_controller.rb @@ -1,4 +1,5 @@ class Import::GitoriousController < Import::BaseController + before_action :verify_gitorious_import_enabled def new redirect_to client.authorize_url(callback_import_gitorious_url) @@ -40,4 +41,8 @@ class Import::GitoriousController < Import::BaseController @client ||= Gitlab::GitoriousImport::Client.new(session[:gitorious_repos]) end + def verify_gitorious_import_enabled + not_found! unless gitorious_import_enabled? + end + end diff --git a/app/controllers/import/google_code_controller.rb b/app/controllers/import/google_code_controller.rb index 4aa6d28c9a8..82fadeb7e83 100644 --- a/app/controllers/import/google_code_controller.rb +++ b/app/controllers/import/google_code_controller.rb @@ -1,4 +1,5 @@ class Import::GoogleCodeController < Import::BaseController + before_action :verify_google_code_import_enabled before_action :user_map, only: [:new_user_map, :create_user_map] def new @@ -104,6 +105,10 @@ class Import::GoogleCodeController < Import::BaseController @client ||= Gitlab::GoogleCodeImport::Client.new(session[:google_code_dump]) end + def verify_google_code_import_enabled + not_found! unless google_code_import_enabled? + end + def user_map @user_map ||= begin user_map = client.user_map diff --git a/app/controllers/projects/blob_controller.rb b/app/controllers/projects/blob_controller.rb index b762518d377..100d3d3b317 100644 --- a/app/controllers/projects/blob_controller.rb +++ b/app/controllers/projects/blob_controller.rb @@ -13,27 +13,20 @@ class Projects::BlobController < Projects::ApplicationController before_action :commit, except: [:new, :create] before_action :blob, except: [:new, :create] before_action :from_merge_request, only: [:edit, :update] - before_action :after_edit_path, only: [:edit, :update] before_action :require_branch_head, only: [:edit, :update] + before_action :editor_variables, except: [:show, :preview, :diff] + before_action :after_edit_path, only: [:edit, :update] def new commit unless @repository.empty? end def create - file_path = File.join(@path, File.basename(params[:file_name])) - result = Files::CreateService.new( - @project, - current_user, - params.merge(new_branch: sanitized_new_branch_name), - @ref, - file_path - ).execute + result = Files::CreateService.new(@project, current_user, @commit_params).execute if result[:status] == :success flash[:notice] = "Your changes have been successfully committed" - ref = sanitized_new_branch_name.presence || @ref - redirect_to namespace_project_blob_path(@project.namespace, @project, File.join(ref, file_path)) + redirect_to namespace_project_blob_path(@project.namespace, @project, File.join(@target_branch, @file_path)) else flash[:alert] = result[:message] render :new @@ -48,22 +41,10 @@ class Projects::BlobController < Projects::ApplicationController end def update - result = Files::UpdateService. - new( - @project, - current_user, - params.merge(new_branch: sanitized_new_branch_name), - @ref, - @path - ).execute + result = Files::UpdateService.new(@project, current_user, @commit_params).execute if result[:status] == :success flash[:notice] = "Your changes have been successfully committed" - - if from_merge_request - from_merge_request.reload_code - end - redirect_to after_edit_path else flash[:alert] = result[:message] @@ -80,12 +61,11 @@ class Projects::BlobController < Projects::ApplicationController end def destroy - result = Files::DeleteService.new(@project, current_user, params, @ref, @path).execute + result = Files::DeleteService.new(@project, current_user, @commit_params).execute if result[:status] == :success flash[:notice] = "Your changes have been successfully committed" - redirect_to namespace_project_tree_path(@project.namespace, @project, - @ref) + redirect_to namespace_project_tree_path(@project.namespace, @project, @target_branch) else flash[:alert] = result[:message] render :show @@ -135,7 +115,6 @@ class Projects::BlobController < Projects::ApplicationController @id = params[:id] @ref, @path = extract_ref(@id) - rescue InvalidPathError not_found! end @@ -145,8 +124,8 @@ class Projects::BlobController < Projects::ApplicationController if from_merge_request diffs_namespace_project_merge_request_path(from_merge_request.target_project.namespace, from_merge_request.target_project, from_merge_request) + "#file-path-#{hexdigest(@path)}" - elsif sanitized_new_branch_name.present? - namespace_project_blob_path(@project.namespace, @project, File.join(sanitized_new_branch_name, @path)) + elsif @target_branch.present? + namespace_project_blob_path(@project.namespace, @project, File.join(@target_branch, @path)) else namespace_project_blob_path(@project.namespace, @project, @id) end @@ -160,4 +139,25 @@ class Projects::BlobController < Projects::ApplicationController def sanitized_new_branch_name @new_branch ||= sanitize(strip_tags(params[:new_branch])) end + + def editor_variables + @current_branch = @ref + @target_branch = (sanitized_new_branch_name || @ref) + + @file_path = + if action_name.to_s == 'create' + File.join(@path, File.basename(params[:file_name])) + else + @path + end + + @commit_params = { + file_path: @file_path, + current_branch: @current_branch, + target_branch: @target_branch, + commit_message: params[:commit_message], + file_content: params[:content], + file_content_encoding: params[:encoding] + } + end end diff --git a/app/controllers/projects/compare_controller.rb b/app/controllers/projects/compare_controller.rb index c5f085c236f..d9b3adae95b 100644 --- a/app/controllers/projects/compare_controller.rb +++ b/app/controllers/projects/compare_controller.rb @@ -13,13 +13,8 @@ class Projects::CompareController < Projects::ApplicationController base_ref = Addressable::URI.unescape(params[:from]) @ref = head_ref = Addressable::URI.unescape(params[:to]) - compare_result = CompareService.new.execute( - current_user, - @project, - head_ref, - @project, - base_ref - ) + compare_result = CompareService.new. + execute(@project, head_ref, @project, base_ref) @commits = compare_result.commits @diffs = compare_result.diffs diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb index d1265198318..f3054881daf 100644 --- a/app/controllers/projects/merge_requests_controller.rb +++ b/app/controllers/projects/merge_requests_controller.rb @@ -1,9 +1,7 @@ -require 'gitlab/satellite/satellite' - class Projects::MergeRequestsController < Projects::ApplicationController before_action :module_enabled before_action :merge_request, only: [ - :edit, :update, :show, :diffs, :commits, :automerge, :automerge_check, + :edit, :update, :show, :diffs, :commits, :merge, :merge_check, :ci_status, :toggle_subscription ] before_action :closes_issues, only: [:edit, :update, :show, :diffs, :commits] @@ -137,7 +135,7 @@ class Projects::MergeRequestsController < Projects::ApplicationController end end - def automerge_check + def merge_check if @merge_request.unchecked? @merge_request.check_if_can_be_merged end @@ -147,11 +145,11 @@ class Projects::MergeRequestsController < Projects::ApplicationController render partial: "projects/merge_requests/widget/show.html.haml", layout: false end - def automerge + def merge return access_denied! unless @merge_request.can_be_merged_by?(current_user) - if @merge_request.automergeable? - AutoMergeWorker.perform_async(@merge_request.id, current_user.id, params) + if @merge_request.mergeable? + MergeWorker.perform_async(@merge_request.id, current_user.id, params) @status = true else @status = false diff --git a/app/helpers/application_settings_helper.rb b/app/helpers/application_settings_helper.rb index 61d14383945..7d6b58ee21a 100644 --- a/app/helpers/application_settings_helper.rb +++ b/app/helpers/application_settings_helper.rb @@ -39,4 +39,21 @@ module ApplicationSettingsHelper end end end + + # Return a group of checkboxes that use Bootstrap's button plugin for a + # toggle button effect. + def import_sources_checkboxes(help_block_id) + Gitlab::ImportSources.options.map do |name, source| + checked = current_application_settings.import_sources.include?(source) + css_class = 'btn' + css_class += ' active' if checked + checkbox_name = 'application_setting[import_sources][]' + + label_tag(checkbox_name, class: css_class) do + check_box_tag(checkbox_name, source, checked, + autocomplete: 'off', + 'aria-describedby' => help_block_id) + name + end + end + end end diff --git a/app/helpers/explore_helper.rb b/app/helpers/explore_helper.rb index 7616fe6bad8..0d291f9a87e 100644 --- a/app/helpers/explore_helper.rb +++ b/app/helpers/explore_helper.rb @@ -10,7 +10,7 @@ module ExploreHelper options = exist_opts.merge(options) - path = request.path + path = explore_projects_path path << "?#{options.to_param}" path end diff --git a/app/helpers/tab_helper.rb b/app/helpers/tab_helper.rb index 77727337f07..0e7d8065ac7 100644 --- a/app/helpers/tab_helper.rb +++ b/app/helpers/tab_helper.rb @@ -67,6 +67,14 @@ module TabHelper path.any? do |single_path| current_path?(single_path) end + elsif page = options.delete(:page) + unless page.respond_to?(:each) + page = [page] + end + + page.any? do |single_page| + current_page?(single_page) + end else c = options.delete(:controller) a = options.delete(:action) diff --git a/app/models/application_setting.rb b/app/models/application_setting.rb index 6d1ad82a262..8f27e35d723 100644 --- a/app/models/application_setting.rb +++ b/app/models/application_setting.rb @@ -22,10 +22,12 @@ # user_oauth_applications :boolean default(TRUE) # after_sign_out_path :string(255) # session_expire_delay :integer default(10080), not null +# import_sources :text # class ApplicationSetting < ActiveRecord::Base serialize :restricted_visibility_levels + serialize :import_sources serialize :restricted_signup_domains, Array attr_accessor :restricted_signup_domains_raw @@ -52,6 +54,16 @@ class ApplicationSetting < ActiveRecord::Base end end + validates_each :import_sources do |record, attr, value| + unless value.nil? + value.each do |source| + unless Gitlab::ImportSources.options.has_value?(source) + record.errors.add(attr, "'#{source}' is not a import source") + end + end + end + end + def self.current ApplicationSetting.last end @@ -70,7 +82,8 @@ class ApplicationSetting < ActiveRecord::Base session_expire_delay: Settings.gitlab['session_expire_delay'], default_project_visibility: Settings.gitlab.default_projects_features['visibility_level'], default_snippet_visibility: Settings.gitlab.default_projects_features['visibility_level'], - restricted_signup_domains: Settings.gitlab['restricted_signup_domains'] + restricted_signup_domains: Settings.gitlab['restricted_signup_domains'], + import_sources: ['github','bitbucket','gitlab','gitorious','google_code','git'] ) end diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb index 324d1795ab4..467b90861f9 100644 --- a/app/models/merge_request.rb +++ b/app/models/merge_request.rb @@ -41,8 +41,6 @@ class MergeRequest < ActiveRecord::Base delegate :commits, :diffs, :last_commit, :last_commit_short_sha, to: :merge_request_diff, prefix: nil - attr_accessor :should_remove_source_branch - # When this attribute is true some MR validation is ignored # It allows us to close or modify broken merge requests attr_accessor :allow_broken @@ -57,7 +55,7 @@ class MergeRequest < ActiveRecord::Base transition [:reopened, :opened] => :closed end - event :merge do + event :mark_as_merged do transition [:reopened, :opened, :locked] => :merged end @@ -205,7 +203,10 @@ class MergeRequest < ActiveRecord::Base end def check_if_can_be_merged - if Gitlab::Satellite::MergeAction.new(self.author, self).can_be_merged? + can_be_merged = + project.repository.can_be_merged?(source_sha, target_branch) + + if can_be_merged mark_as_mergeable else mark_as_unmergeable @@ -220,18 +221,6 @@ class MergeRequest < ActiveRecord::Base self.target_project.events.where(target_id: self.id, target_type: "MergeRequest", action: Event::CLOSED).last end - def automerge!(current_user, commit_message = nil) - return unless automergeable? - - MergeRequests::AutoMergeService. - new(target_project, current_user). - execute(self, commit_message) - end - - def remove_source_branch? - self.should_remove_source_branch && !self.source_project.root_ref?(self.source_branch) && !self.for_fork? - end - def open? opened? || reopened? end @@ -240,11 +229,11 @@ class MergeRequest < ActiveRecord::Base title =~ /\A\[?WIP\]?:? /i end - def automergeable? + def mergeable? open? && !work_in_progress? && can_be_merged? end - def automerge_status + def gitlab_merge_status if work_in_progress? "work_in_progress" else @@ -271,14 +260,14 @@ class MergeRequest < ActiveRecord::Base # # see "git diff" def to_diff(current_user) - Gitlab::Satellite::MergeAction.new(current_user, self).diff_in_satellite + target_project.repository.diff_text(target_branch, source_sha) end # Returns the commit as a series of email patches. # # see "git format-patch" def to_patch(current_user) - Gitlab::Satellite::MergeAction.new(current_user, self).format_patch + target_project.repository.format_patch(target_branch, source_sha) end def hook_attrs @@ -429,4 +418,30 @@ class MergeRequest < ActiveRecord::Base "Open" end end + + def target_sha + @target_sha ||= target_project. + repository.commit(target_branch).sha + end + + def source_sha + commits.first.sha + end + + def fetch_ref + target_project.repository.fetch_ref( + source_project.repository.path_to_repo, + "refs/heads/#{source_branch}", + "refs/merge-requests/#{iid}/head" + ) + end + + def in_locked_state + begin + lock_mr + yield + ensure + unlock_mr if locked? + end + end end diff --git a/app/models/merge_request_diff.rb b/app/models/merge_request_diff.rb index df1c2b78758..e317c8eac4d 100644 --- a/app/models/merge_request_diff.rb +++ b/app/models/merge_request_diff.rb @@ -16,9 +16,8 @@ require Rails.root.join("app/models/commit") class MergeRequestDiff < ActiveRecord::Base include Sortable - # Prevent store of diff - # if commits amount more then 200 - COMMITS_SAFE_SIZE = 200 + # Prevent store of diff if commits amount more then 500 + COMMITS_SAFE_SIZE = 500 attr_reader :commits, :diffs @@ -124,12 +123,12 @@ class MergeRequestDiff < ActiveRecord::Base if new_diffs.any? if new_diffs.size > Commit::DIFF_HARD_LIMIT_FILES self.state = :overflow_diff_files_limit - new_diffs = [] + new_diffs = new_diffs.first[Commit::DIFF_HARD_LIMIT_LINES] end if new_diffs.sum { |diff| diff.diff.lines.count } > Commit::DIFF_HARD_LIMIT_LINES self.state = :overflow_diff_lines_limit - new_diffs = [] + new_diffs = new_diffs.first[Commit::DIFF_HARD_LIMIT_LINES] end end @@ -160,12 +159,21 @@ class MergeRequestDiff < ActiveRecord::Base private def compare_result - @compare_result ||= CompareService.new.execute( - merge_request.author, - merge_request.source_project, - merge_request.source_branch, - merge_request.target_project, - merge_request.target_branch, - ) + @compare_result ||= + begin + # Update ref for merge request + merge_request.fetch_ref + + # Get latest sha of branch from source project + source_sha = merge_request.source_project.commit(source_branch).sha + + Gitlab::CompareResult.new( + Gitlab::Git::Compare.new( + merge_request.target_project.repository.raw_repository, + merge_request.target_branch, + source_sha, + ) + ) + end end end diff --git a/app/models/namespace.rb b/app/models/namespace.rb index 30ffacadded..161a16ca61c 100644 --- a/app/models/namespace.rb +++ b/app/models/namespace.rb @@ -118,12 +118,11 @@ class Namespace < ActiveRecord::Base gitlab_shell.add_namespace(path_was) if gitlab_shell.mv_namespace(path_was, path) - # If repositories moved successfully we need to remove old satellites - # and send update instructions to users. + # If repositories moved successfully we need to + # send update instructions to users. # However we cannot allow rollback since we moved namespace dir # So we basically we mute exceptions in next actions begin - gitlab_shell.rm_satellites(path_was) send_update_instructions rescue # Returning false does not rollback after_* transaction but gives diff --git a/app/models/project.rb b/app/models/project.rb index 3dc1729e812..69f9af91c51 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -215,7 +215,7 @@ class Project < ActiveRecord::Base end def search(query) - joins(:namespace).where('projects.archived = ?', false). + joins(:namespace). where('LOWER(projects.name) LIKE :query OR LOWER(projects.path) LIKE :query OR LOWER(namespaces.name) LIKE :query OR @@ -520,14 +520,6 @@ class Project < ActiveRecord::Base !repository.exists? || repository.empty? end - def ensure_satellite_exists - self.satellite.create unless self.satellite.exists? - end - - def satellite - @satellite ||= Gitlab::Satellite::Satellite.new(self) - end - def repo repository.raw end @@ -597,14 +589,11 @@ class Project < ActiveRecord::Base new_path_with_namespace = File.join(namespace_dir, path) if gitlab_shell.mv_repository(old_path_with_namespace, new_path_with_namespace) - # If repository moved successfully we need to remove old satellite - # and send update instructions to users. + # If repository moved successfully we need to send update instructions to users. # However we cannot allow rollback since we moved repository # So we basically we mute exceptions in next actions begin gitlab_shell.mv_repository("#{old_path_with_namespace}.wiki", "#{new_path_with_namespace}.wiki") - gitlab_shell.rm_satellites(old_path_with_namespace) - ensure_satellite_exists send_move_instructions reset_events_cache rescue @@ -702,7 +691,6 @@ class Project < ActiveRecord::Base def create_repository if forked? if gitlab_shell.fork_repository(forked_from_project.path_with_namespace, self.namespace.path) - ensure_satellite_exists true else errors.add(:base, 'Failed to fork repository via gitlab-shell') diff --git a/app/models/project_services/gitlab_ci_service.rb b/app/models/project_services/gitlab_ci_service.rb index 5aaa4e85cbc..ecdcd48ae60 100644 --- a/app/models/project_services/gitlab_ci_service.rb +++ b/app/models/project_services/gitlab_ci_service.rb @@ -74,6 +74,8 @@ class GitlabCiService < CiService else :error end + rescue Errno::ECONNREFUSED + :error end def fork_registration(new_project, private_token) @@ -103,6 +105,8 @@ class GitlabCiService < CiService if response.code == 200 and response["coverage"] response["coverage"] end + rescue Errno::ECONNREFUSED + nil end def build_page(sha, ref) diff --git a/app/models/repository.rb b/app/models/repository.rb index 24c32d90051..79b48ebfedf 100644 --- a/app/models/repository.rb +++ b/app/models/repository.rb @@ -1,4 +1,9 @@ +require 'securerandom' + class Repository + class PreReceiveError < StandardError; end + class CommitError < StandardError; end + include Gitlab::ShellAdapter attr_accessor :raw_repository, :path_with_namespace, :project @@ -368,6 +373,89 @@ class Repository @root_ref ||= raw_repository.root_ref end + def commit_file(user, path, content, message, branch) + commit_with_hooks(user, branch) do |ref| + path[0] = '' if path[0] == '/' + + committer = user_to_comitter(user) + options = {} + options[:committer] = committer + options[:author] = committer + options[:commit] = { + message: message, + branch: ref, + } + + options[:file] = { + content: content, + path: path + } + + Gitlab::Git::Blob.commit(raw_repository, options) + end + end + + def remove_file(user, path, message, branch) + commit_with_hooks(user, branch) do |ref| + path[0] = '' if path[0] == '/' + + committer = user_to_comitter(user) + options = {} + options[:committer] = committer + options[:author] = committer + options[:commit] = { + message: message, + branch: ref + } + + options[:file] = { + path: path + } + + Gitlab::Git::Blob.remove(raw_repository, options) + end + end + + def user_to_comitter(user) + { + email: user.email, + name: user.name, + time: Time.now + } + end + + def can_be_merged?(source_sha, target_branch) + our_commit = rugged.branches[target_branch].target + their_commit = rugged.lookup(source_sha) + + if our_commit && their_commit + !rugged.merge_commits(our_commit, their_commit).conflicts? + else + false + end + end + + def merge(user, source_sha, target_branch, options = {}) + our_commit = rugged.branches[target_branch].target + their_commit = rugged.lookup(source_sha) + + raise "Invalid merge target" if our_commit.nil? + raise "Invalid merge source" if their_commit.nil? + + merge_index = rugged.merge_commits(our_commit, their_commit) + return false if merge_index.conflicts? + + commit_with_hooks(user, target_branch) do |ref| + actual_options = options.merge( + parents: [our_commit, their_commit], + tree: merge_index.write_tree(rugged), + update_ref: ref + ) + + Rugged::Commit.create(rugged, actual_options) + end + end + def merged_to_root_ref?(branch_name) branch_commit = commit(branch_name) root_ref_commit = commit(root_ref) @@ -412,6 +500,64 @@ class Repository ) end + def fetch_ref(source_path, source_ref, target_ref) + args = %W(git fetch #{source_path} #{source_ref}:#{target_ref}) + Gitlab::Popen.popen(args, path_to_repo) + end + + def commit_with_hooks(current_user, branch) + oldrev = Gitlab::Git::BLANK_SHA + ref = Gitlab::Git::BRANCH_REF_PREFIX + branch + gl_id = Gitlab::ShellEnv.gl_id(current_user) + was_empty = empty? + + # Create temporary ref + random_string = SecureRandom.hex + tmp_ref = "refs/tmp/#{random_string}/head" + + unless was_empty + oldrev = find_branch(branch).target + rugged.references.create(tmp_ref, oldrev) + end + + # Make commit in tmp ref + newrev = yield(tmp_ref) + + unless newrev + raise CommitError.new('Failed to create commit') + end + + # Run GitLab pre-receive hook + pre_receive_hook = Gitlab::Git::Hook.new('pre-receive', path_to_repo) + status = pre_receive_hook.trigger(gl_id, oldrev, newrev, ref) + + if status + if was_empty + # Create branch + rugged.references.create(ref, newrev) + else + # Update head + current_head = find_branch(branch).target + + # Make sure target branch was not changed during pre-receive hook + if current_head == oldrev + rugged.references.update(ref, newrev) + else + raise CommitError.new('Commit was rejected because branch received new push') + end + end + + # Run GitLab post receive hook + post_receive_hook = Gitlab::Git::Hook.new('post-receive', path_to_repo) + status = post_receive_hook.trigger(gl_id, oldrev, newrev, ref) + else + # Remove tmp ref and return error to user + rugged.references.delete(tmp_ref) + + raise PreReceiveError.new('Commit was rejected by pre-receive hook') + end + end + private def cache diff --git a/app/services/base_service.rb b/app/services/base_service.rb index 6d9ed345914..f00ec7408b6 100644 --- a/app/services/base_service.rb +++ b/app/services/base_service.rb @@ -31,6 +31,10 @@ class BaseService SystemHooksService.new end + def repository + project.repository + end + # Add an error to the specified model for restricted visibility levels def deny_visibility_level(model, denied_visibility_level = nil) denied_visibility_level ||= model.visibility_level diff --git a/app/services/compare_service.rb b/app/services/compare_service.rb index 6aa9df4b194..70f642baaaa 100644 --- a/app/services/compare_service.rb +++ b/app/services/compare_service.rb @@ -1,27 +1,28 @@ +require 'securerandom' + # Compare 2 branches for one repo or between repositories # and return Gitlab::CompareResult object that responds to commits and diffs class CompareService - def execute(current_user, source_project, source_branch, target_project, target_branch) - # Try to compare branches to get commits list and diffs - # - # Note: Use satellite only when need to compare between two repos - # because satellites are slower than operations on bare repo - if target_project == source_project - Gitlab::CompareResult.new( - Gitlab::Git::Compare.new( - target_project.repository.raw_repository, - target_branch, - source_branch, - ) + def execute(source_project, source_branch, target_project, target_branch) + source_sha = source_project.commit(source_branch).sha + + # If compare with other project we need to fetch ref first + unless target_project == source_project + random_string = SecureRandom.hex + + target_project.repository.fetch_ref( + source_project.repository.path_to_repo, + "refs/heads/#{source_branch}", + "refs/tmp/#{random_string}/head" ) - else - Gitlab::Satellite::CompareAction.new( - current_user, - target_project, - target_branch, - source_project, - source_branch - ).result end + + Gitlab::CompareResult.new( + Gitlab::Git::Compare.new( + target_project.repository.raw_repository, + target_branch, + source_sha, + ) + ) end end diff --git a/app/services/files/base_service.rb b/app/services/files/base_service.rb index bd245100955..7aecee217d8 100644 --- a/app/services/files/base_service.rb +++ b/app/services/files/base_service.rb @@ -1,17 +1,75 @@ module Files class BaseService < ::BaseService - attr_reader :ref, :path + class ValidationError < StandardError; end - def initialize(project, user, params, ref, path = nil) - @project, @current_user, @params = project, user, params.dup - @ref = ref - @path = path + def execute + @current_branch = params[:current_branch] + @target_branch = params[:target_branch] + @commit_message = params[:commit_message] + @file_path = params[:file_path] + @file_content = if params[:file_content_encoding] == 'base64' + Base64.decode64(params[:file_content]) + else + params[:file_content] + end + + # Validate parameters + validate + + # Create new branch if it different from current_branch + if @target_branch != @current_branch + create_target_branch + end + + if sha = commit + success + else + error("Something went wrong. Your changes were not committed") + end + rescue Repository::CommitError, Repository::PreReceiveError, ValidationError => ex + error(ex.message) end private - def repository - project.repository + def current_branch + @current_branch ||= params[:current_branch] + end + + def target_branch + @target_branch ||= params[:target_branch] + end + + def raise_error(message) + raise ValidationError.new(message) + end + + def validate + allowed = ::Gitlab::GitAccess.new(current_user, project).can_push_to_branch?(@target_branch) + + unless allowed + raise_error("You are not allowed to push into this branch") + end + + unless project.empty_repo? + unless repository.branch_names.include?(@current_branch) + raise_error("You can only create files if you are on top of a branch") + end + + if @current_branch != @target_branch + if repository.branch_names.include?(@target_branch) + raise_error("Branch with such name already exists. You need to switch to this branch in order to make changes") + end + end + end + end + + def create_target_branch + result = CreateBranchService.new(project, current_user).execute(@target_branch, @current_branch) + + unless result[:status] == :success + raise_error("Something went wrong when we tried to create #{@target_branch} for you") + end end end end diff --git a/app/services/files/create_service.rb b/app/services/files/create_service.rb index 23833aa78ec..91d715b2d63 100644 --- a/app/services/files/create_service.rb +++ b/app/services/files/create_service.rb @@ -1,52 +1,30 @@ require_relative "base_service" module Files - class CreateService < BaseService - def execute - allowed = Gitlab::GitAccess.new(current_user, project).can_push_to_branch?(ref) + class CreateService < Files::BaseService + def commit + repository.commit_file(current_user, @file_path, @file_content, @commit_message, @target_branch) + end - unless allowed - return error("You are not allowed to create file in this branch") - end + def validate + super - file_name = File.basename(path) - file_path = path + file_name = File.basename(@file_path) unless file_name =~ Gitlab::Regex.file_name_regex - return error( + raise_error( 'Your changes could not be committed, because the file name ' + Gitlab::Regex.file_name_regex_message ) end - if project.empty_repo? - # everything is ok because repo does not have a commits yet - else - unless repository.branch_names.include?(ref) - return error("You can only create files if you are on top of a branch") - end - - blob = repository.blob_at_branch(ref, file_path) + unless project.empty_repo? + blob = repository.blob_at_branch(@current_branch, @file_path) if blob - return error("Your changes could not be committed, because file with such name exists") + raise_error("Your changes could not be committed, because file with such name exists") end end - - - new_file_action = Gitlab::Satellite::NewFileAction.new(current_user, project, ref, file_path) - created_successfully = new_file_action.commit!( - params[:content], - params[:commit_message], - params[:encoding], - params[:new_branch] - ) - - if created_successfully - success - else - error("Your changes could not be committed, because the file has been changed") - end end end end diff --git a/app/services/files/delete_service.rb b/app/services/files/delete_service.rb index 1497a0f883b..27c881c3430 100644 --- a/app/services/files/delete_service.rb +++ b/app/services/files/delete_service.rb @@ -1,36 +1,9 @@ require_relative "base_service" module Files - class DeleteService < BaseService - def execute - allowed = ::Gitlab::GitAccess.new(current_user, project).can_push_to_branch?(ref) - - unless allowed - return error("You are not allowed to push into this branch") - end - - unless repository.branch_names.include?(ref) - return error("You can only create files if you are on top of a branch") - end - - blob = repository.blob_at_branch(ref, path) - - unless blob - return error("You can only edit text files") - end - - delete_file_action = Gitlab::Satellite::DeleteFileAction.new(current_user, project, ref, path) - - deleted_successfully = delete_file_action.commit!( - nil, - params[:commit_message] - ) - - if deleted_successfully - success - else - error("Your changes could not be committed, because the file has been changed") - end + class DeleteService < Files::BaseService + def commit + repository.remove_file(current_user, @file_path, @commit_message, @target_branch) end end end diff --git a/app/services/files/update_service.rb b/app/services/files/update_service.rb index 0724d3ae634..a20903c6f02 100644 --- a/app/services/files/update_service.rb +++ b/app/services/files/update_service.rb @@ -1,39 +1,9 @@ require_relative "base_service" module Files - class UpdateService < BaseService - def execute - allowed = ::Gitlab::GitAccess.new(current_user, project).can_push_to_branch?(ref) - - unless allowed - return error("You are not allowed to push into this branch") - end - - unless repository.branch_names.include?(ref) - return error("You can only create files if you are on top of a branch") - end - - blob = repository.blob_at_branch(ref, path) - - unless blob - return error("You can only edit text files") - end - - edit_file_action = Gitlab::Satellite::EditFileAction.new(current_user, project, ref, path) - edit_file_action.commit!( - params[:content], - params[:commit_message], - params[:encoding], - params[:new_branch] - ) - - success - rescue Gitlab::Satellite::CheckoutFailed => ex - error("Your changes could not be committed because ref '#{ref}' could not be checked out", 400) - rescue Gitlab::Satellite::CommitFailed => ex - error("Your changes could not be committed. Maybe there was nothing to commit?", 409) - rescue Gitlab::Satellite::PushFailed => ex - error("Your changes could not be committed. Maybe the file was changed by another process?", 409) + class UpdateService < Files::BaseService + def commit + repository.commit_file(current_user, @file_path, @file_content, @commit_message, @target_branch) end end end diff --git a/app/services/git_push_service.rb b/app/services/git_push_service.rb index 5a2c97b08af..81535450ac1 100644 --- a/app/services/git_push_service.rb +++ b/app/services/git_push_service.rb @@ -10,16 +10,14 @@ class GitPushService # # Next, this method: # 1. Creates the push event - # 2. Ensures that the project satellite exists - # 3. Updates merge requests - # 4. Recognizes cross-references from commit messages - # 5. Executes the project's web hooks - # 6. Executes the project's services + # 2. Updates merge requests + # 3. Recognizes cross-references from commit messages + # 4. Executes the project's web hooks + # 5. Executes the project's services # def execute(project, user, oldrev, newrev, ref) @project, @user = project, user - project.ensure_satellite_exists project.repository.expire_cache if push_remove_branch?(ref, newrev) @@ -133,7 +131,8 @@ class GitPushService end def is_default_branch?(ref) - Gitlab::Git.branch_ref?(ref) && Gitlab::Git.ref_name(ref) == project.default_branch + Gitlab::Git.branch_ref?(ref) && + (Gitlab::Git.ref_name(ref) == project.default_branch || project.default_branch.nil?) end def commit_user(commit) diff --git a/app/services/merge_requests/auto_merge_service.rb b/app/services/merge_requests/auto_merge_service.rb deleted file mode 100644 index cdedf48b0c0..00000000000 --- a/app/services/merge_requests/auto_merge_service.rb +++ /dev/null @@ -1,30 +0,0 @@ -module MergeRequests - # AutoMergeService class - # - # Do git merge in satellite and in case of success - # mark merge request as merged and execute all hooks and notifications - # Called when you do merge via GitLab UI - class AutoMergeService < BaseMergeService - def execute(merge_request, commit_message) - merge_request.lock_mr - - if Gitlab::Satellite::MergeAction.new(current_user, merge_request).merge!(commit_message) - merge_request.merge - - create_merge_event(merge_request, current_user) - create_note(merge_request) - notification_service.merge_mr(merge_request, current_user) - execute_hooks(merge_request, 'merge') - - true - else - merge_request.unlock_mr - false - end - rescue - merge_request.unlock_mr if merge_request.locked? - merge_request.mark_as_unmergeable - false - end - end -end diff --git a/app/services/merge_requests/base_merge_service.rb b/app/services/merge_requests/base_merge_service.rb deleted file mode 100644 index 9579573adf9..00000000000 --- a/app/services/merge_requests/base_merge_service.rb +++ /dev/null @@ -1,10 +0,0 @@ -module MergeRequests - class BaseMergeService < MergeRequests::BaseService - - private - - def create_merge_event(merge_request, current_user) - EventCreateService.new.merge_mr(merge_request, current_user) - end - end -end diff --git a/app/services/merge_requests/build_service.rb b/app/services/merge_requests/build_service.rb index 956480938c3..a9b29f9654d 100644 --- a/app/services/merge_requests/build_service.rb +++ b/app/services/merge_requests/build_service.rb @@ -12,12 +12,16 @@ module MergeRequests merge_request.target_project ||= (project.forked_from_project || project) merge_request.target_branch ||= merge_request.target_project.default_branch - unless merge_request.target_branch && merge_request.source_branch - return build_failed(merge_request, nil) + if merge_request.target_branch.blank? || merge_request.source_branch.blank? + message = + if params[:source_branch] || params[:target_branch] + "You must select source and target branch" + end + + return build_failed(merge_request, message) end compare_result = CompareService.new.execute( - current_user, merge_request.source_project, merge_request.source_branch, merge_request.target_project, @@ -40,7 +44,6 @@ module MergeRequests merge_request.compare_diffs = diffs elsif diffs == false - # satellite timeout return false merge_request.can_be_created = false merge_request.compare_failed = true end @@ -59,9 +62,6 @@ module MergeRequests end merge_request - - rescue Gitlab::Satellite::BranchesWithoutParent - return build_failed(merge_request, "Selected branches have no common commit so they cannot be merged.") end def build_failed(merge_request, message) diff --git a/app/services/merge_requests/merge_service.rb b/app/services/merge_requests/merge_service.rb index 327ead4ff3f..98a67c0bc99 100644 --- a/app/services/merge_requests/merge_service.rb +++ b/app/services/merge_requests/merge_service.rb @@ -1,22 +1,47 @@ module MergeRequests # MergeService class # - # Mark existing merge request as merged - # and execute all hooks and notifications - # Called when you do merge via command line and push code - # to target branch - class MergeService < BaseMergeService + # Do git merge and in case of success + # mark merge request as merged and execute all hooks and notifications + # Executed when you do merge via GitLab UI + # + class MergeService < MergeRequests::BaseService + attr_reader :merge_request, :commit_message + def execute(merge_request, commit_message) - merge_request.merge + @commit_message = commit_message + @merge_request = merge_request + + unless @merge_request.mergeable? + return error('Merge request is not mergeable') + end + + merge_request.in_locked_state do + if commit + after_merge + success + else + error('Can not merge changes') + end + end + end - create_merge_event(merge_request, current_user) - create_note(merge_request) - notification_service.merge_mr(merge_request, current_user) - execute_hooks(merge_request, 'merge') + private + + def commit + committer = repository.user_to_comitter(current_user) + + options = { + message: commit_message, + author: committer, + committer: committer + } + + repository.merge(current_user, merge_request.source_sha, merge_request.target_branch, options) + end - true - rescue - false + def after_merge + MergeRequests::PostMergeService.new(project, current_user).execute(merge_request) end end end diff --git a/app/services/merge_requests/post_merge_service.rb b/app/services/merge_requests/post_merge_service.rb new file mode 100644 index 00000000000..aceb8cb9021 --- /dev/null +++ b/app/services/merge_requests/post_merge_service.rb @@ -0,0 +1,22 @@ +module MergeRequests + # PostMergeService class + # + # Mark existing merge request as merged + # and execute all hooks and notifications + # + class PostMergeService < MergeRequests::BaseService + def execute(merge_request) + merge_request.mark_as_merged + create_merge_event(merge_request, current_user) + create_note(merge_request) + notification_service.merge_mr(merge_request, current_user) + execute_hooks(merge_request, 'merge') + end + + private + + def create_merge_event(merge_request, current_user) + EventCreateService.new.merge_mr(merge_request, current_user) + end + end +end diff --git a/app/services/merge_requests/refresh_service.rb b/app/services/merge_requests/refresh_service.rb index d0648da049b..e903e48e3cd 100644 --- a/app/services/merge_requests/refresh_service.rb +++ b/app/services/merge_requests/refresh_service.rb @@ -33,9 +33,9 @@ module MergeRequests merge_requests.uniq.select(&:source_project).each do |merge_request| - MergeRequests::MergeService. + MergeRequests::PostMergeService. new(merge_request.target_project, @current_user). - execute(merge_request, nil) + execute(merge_request) end end diff --git a/app/services/projects/destroy_service.rb b/app/services/projects/destroy_service.rb index 403f419ec50..28872c89259 100644 --- a/app/services/projects/destroy_service.rb +++ b/app/services/projects/destroy_service.rb @@ -27,7 +27,6 @@ module Projects end end - project.satellite.destroy log_info("Project \"#{project.name}\" was removed") system_hook_service.execute_hooks_for(project, :destroy) true diff --git a/app/services/projects/transfer_service.rb b/app/services/projects/transfer_service.rb index f43c0ef70e9..550ed6897dd 100644 --- a/app/services/projects/transfer_service.rb +++ b/app/services/projects/transfer_service.rb @@ -33,9 +33,6 @@ module Projects raise TransferError.new("Project with same path in target namespace already exists") end - # Remove old satellite - project.satellite.destroy - # Apply new namespace id project.namespace = new_namespace project.save! @@ -51,9 +48,6 @@ module Projects # Move wiki repo also if present gitlab_shell.mv_repository("#{old_path}.wiki", "#{new_path}.wiki") - # Create a new satellite (reload project from DB) - Project.find(project.id).ensure_satellite_exists - # clear project cached events project.reset_events_cache diff --git a/app/views/admin/application_settings/_form.html.haml b/app/views/admin/application_settings/_form.html.haml index b67d2116fa4..330b8bbf9d2 100644 --- a/app/views/admin/application_settings/_form.html.haml +++ b/app/views/admin/application_settings/_form.html.haml @@ -28,6 +28,20 @@ = level %span.help-block#restricted-visibility-help Selected levels cannot be used by non-admin users for projects or snippets .form-group + = f.label :import_sources, class: 'control-label col-sm-2' + .col-sm-10 + - data_attrs = { toggle: 'buttons' } + .btn-group{ data: data_attrs } + - import_sources_checkboxes('import-sources-help').each do |source| + = source + %span.help-block#import-sources-help + Enabled sources for code import during project creation. OmniAuth must be configured for GitHub + = link_to "(?)", help_page_path("integration", "github") + , Bitbucket + = link_to "(?)", help_page_path("integration", "bitbucket") + and GitLab.com + = link_to "(?)", help_page_path("integration", "gitlab") + .form-group .col-sm-offset-2.col-sm-10 .checkbox = f.label :version_check_enabled do diff --git a/app/views/admin/projects/index.html.haml b/app/views/admin/projects/index.html.haml index f43d46356fa..d9b481404f7 100644 --- a/app/views/admin/projects/index.html.haml +++ b/app/views/admin/projects/index.html.haml @@ -23,6 +23,10 @@ = label_tag :abandoned do = check_box_tag :abandoned, 1, params[:abandoned] %span No activity over 6 month + .checkbox + = label_tag :with_archived do + = check_box_tag :with_archived, 1, params[:with_archived] + %span Show archived projects %fieldset %strong Visibility level: @@ -73,6 +77,8 @@ = visibility_level_icon(project.visibility_level) = link_to project.name_with_namespace, [:admin, project.namespace.becomes(Namespace), project] .pull-right + - if project.archived + %span.label.label-warning archived %span.label.label-gray = repository_size(project) = link_to 'Edit', edit_namespace_project_path(project.namespace, project), id: "edit_#{dom_id(project)}", class: "btn btn-sm" diff --git a/app/views/dashboard/_groups_head.html.haml b/app/views/dashboard/_groups_head.html.haml new file mode 100644 index 00000000000..8a397a84e0e --- /dev/null +++ b/app/views/dashboard/_groups_head.html.haml @@ -0,0 +1,7 @@ +%ul.center-top-menu + = nav_link(page: [dashboard_groups_path]) do + = link_to dashboard_groups_path, title: 'Your groups', data: {placement: 'right'} do + Your Groups + = nav_link(page: [explore_groups_path]) do + = link_to explore_groups_path, title: 'Explore groups', data: {toggle: 'tooltip', placement: 'bottom'} do + Explore Groups diff --git a/app/views/dashboard/_projects_head.html.haml b/app/views/dashboard/_projects_head.html.haml new file mode 100644 index 00000000000..f7be194c696 --- /dev/null +++ b/app/views/dashboard/_projects_head.html.haml @@ -0,0 +1,10 @@ +%ul.center-top-menu + = nav_link(path: ['dashboard#show', 'root#show']) do + = link_to dashboard_path, title: 'Home', class: 'shortcuts-activity', data: {placement: 'right'} do + Your Projects + = nav_link(page: starred_dashboard_projects_path) do + = link_to starred_dashboard_projects_path, title: 'Starred Projects', data: {placement: 'right'} do + Starred Projects + = nav_link(page: [explore_root_path, trending_explore_projects_path, starred_explore_projects_path, explore_projects_path]) do + = link_to explore_root_path, title: 'Explore', data: {toggle: 'tooltip', placement: 'bottom'} do + Explore Projects diff --git a/app/views/dashboard/groups/index.html.haml b/app/views/dashboard/groups/index.html.haml index 0a354373b9b..0860fe3c761 100644 --- a/app/views/dashboard/groups/index.html.haml +++ b/app/views/dashboard/groups/index.html.haml @@ -1,14 +1,13 @@ - page_title "Groups" -%h3.page-title - Group Membership += render 'dashboard/groups_head' + +.slead + Group members have access to all group projects. - if current_user.can_create_group? %span.pull-right.hidden-xs - = link_to new_group_path, class: "btn btn-new" do + = link_to new_group_path, class: "btn btn-new btn-sm" do %i.fa.fa-plus New Group -%p.light - Group members have access to all group projects. -%hr .panel.panel-default .panel-heading %strong Groups diff --git a/app/views/dashboard/projects/starred.html.haml b/app/views/dashboard/projects/starred.html.haml index 8aaa0a7f071..98b8cde4766 100644 --- a/app/views/dashboard/projects/starred.html.haml +++ b/app/views/dashboard/projects/starred.html.haml @@ -1,4 +1,6 @@ - page_title "Starred Projects" += render 'dashboard/projects_head' + - if @projects.any? = render 'shared/show_aside' diff --git a/app/views/dashboard/show.html.haml b/app/views/dashboard/show.html.haml index 5001c2101e1..a3a32b6932f 100644 --- a/app/views/dashboard/show.html.haml +++ b/app/views/dashboard/show.html.haml @@ -2,6 +2,8 @@ - if current_user = auto_discovery_link_tag(:atom, dashboard_url(format: :atom, private_token: current_user.private_token), title: "All activity") += render 'dashboard/projects_head' + - if @projects.any? = render 'shared/show_aside' diff --git a/app/views/explore/groups/index.html.haml b/app/views/explore/groups/index.html.haml index f3f0b778539..7dcefd330a1 100644 --- a/app/views/explore/groups/index.html.haml +++ b/app/views/explore/groups/index.html.haml @@ -1,5 +1,7 @@ - page_title "Groups" -.clearfix +- if current_user + = render 'dashboard/groups_head' +.clearfix.append-bottom-10 .pull-left = form_tag explore_groups_path, method: :get, class: 'form-inline form-tiny' do |f| = hidden_field_tag :sort, @sort @@ -28,15 +30,12 @@ = link_to explore_groups_path(sort: sort_value_oldest_updated) do = sort_title_oldest_updated -%hr - %ul.bordered-list - @groups.each do |group| %li .clearfix %h4 = link_to group_path(id: group.path) do - %i.fa.fa-users = group.name .clearfix %p diff --git a/app/views/explore/projects/_dropdown.html.haml b/app/views/explore/projects/_dropdown.html.haml new file mode 100644 index 00000000000..b23a3c1e5c1 --- /dev/null +++ b/app/views/explore/projects/_dropdown.html.haml @@ -0,0 +1,27 @@ +.dropdown.inline + %button.dropdown-toggle.btn{type: 'button', 'data-toggle' => 'dropdown'} + %span.light sort: + - if @sort.present? + = sort_options_hash[@sort] + - elsif current_page?(trending_explore_projects_path) || current_page?(explore_root_path) + Trending projects + - elsif current_page?(starred_explore_projects_path) + Most stars + - else + = sort_title_recently_created + %b.caret + %ul.dropdown-menu + %li + = link_to trending_explore_projects_path do + Trending projects + = link_to starred_explore_projects_path do + Most stars + = link_to explore_projects_filter_path(sort: sort_value_recently_created) do + = sort_title_recently_created + = link_to explore_projects_filter_path(sort: sort_value_oldest_created) do + = sort_title_oldest_created + = link_to explore_projects_filter_path(sort: sort_value_recently_updated) do + = sort_title_recently_updated + = link_to explore_projects_filter_path(sort: sort_value_oldest_updated) do + = sort_title_oldest_updated + diff --git a/app/views/explore/projects/_filter.html.haml b/app/views/explore/projects/_filter.html.haml index 82622a58ed2..4b91291caf4 100644 --- a/app/views/explore/projects/_filter.html.haml +++ b/app/views/explore/projects/_filter.html.haml @@ -46,22 +46,4 @@ = link_to explore_projects_filter_path(tag: tag.name) do %i.fa.fa-tag = tag.name - - .dropdown.inline - %button.dropdown-toggle.btn{type: 'button', 'data-toggle' => 'dropdown'} - %span.light sort: - - if @sort.present? - = sort_options_hash[@sort] - - else - = sort_title_recently_created - %b.caret - %ul.dropdown-menu - %li - = link_to explore_projects_filter_path(sort: sort_value_recently_created) do - = sort_title_recently_created - = link_to explore_projects_filter_path(sort: sort_value_oldest_created) do - = sort_title_oldest_created - = link_to explore_projects_filter_path(sort: sort_value_recently_updated) do - = sort_title_recently_updated - = link_to explore_projects_filter_path(sort: sort_value_oldest_updated) do - = sort_title_oldest_updated + = render 'explore/projects/dropdown' diff --git a/app/views/explore/projects/index.html.haml b/app/views/explore/projects/index.html.haml index ba2276f51ce..4956081e1ed 100644 --- a/app/views/explore/projects/index.html.haml +++ b/app/views/explore/projects/index.html.haml @@ -1,8 +1,9 @@ - page_title "Projects" +- if current_user + = render 'dashboard/projects_head' .clearfix = render 'filter' - -%hr +%br .public-projects %ul.bordered-list.top-list = render @projects diff --git a/app/views/explore/projects/starred.html.haml b/app/views/explore/projects/starred.html.haml index b5d146b1f2f..fdccbe5692f 100644 --- a/app/views/explore/projects/starred.html.haml +++ b/app/views/explore/projects/starred.html.haml @@ -1,9 +1,12 @@ - page_title "Starred Projects" +- if current_user + = render 'dashboard/projects_head' .explore-trending-block - %p.lead + .lead %i.fa.fa-star See most starred projects - %hr + .pull-right + = render 'explore/projects/dropdown' .public-projects %ul.bordered-list = render @starred_projects diff --git a/app/views/explore/projects/trending.html.haml b/app/views/explore/projects/trending.html.haml index 5e24df76a63..98a4174b426 100644 --- a/app/views/explore/projects/trending.html.haml +++ b/app/views/explore/projects/trending.html.haml @@ -1,4 +1,6 @@ - page_title "Trending Projects" +- if current_user + = render 'dashboard/projects_head' .explore-title %h3 Explore GitLab @@ -6,10 +8,11 @@ Discover projects and groups. Share your projects with others %hr .explore-trending-block - %p.lead + .lead %i.fa.fa-comments-o See most discussed projects for last month - %hr + .pull-right + = render 'explore/projects/dropdown' .public-projects %ul.bordered-list = render @trending_projects diff --git a/app/views/groups/projects.html.haml b/app/views/groups/projects.html.haml index 6b7efa83dea..d06cfa7ff9f 100644 --- a/app/views/groups/projects.html.haml +++ b/app/views/groups/projects.html.haml @@ -12,11 +12,14 @@ - @projects.each do |project| %li .list-item-name - = visibility_level_icon(project.visibility_level) + %span{ class: visibility_level_color(project.visibility_level) } + = visibility_level_icon(project.visibility_level) %strong= link_to project.name_with_namespace, project + .pull-right + - if project.archived + %span.label.label-warning archived %span.label.label-gray = repository_size(project) - .pull-right = link_to 'Members', namespace_project_project_members_path(project.namespace, project), id: "edit_#{dom_id(project)}", class: "btn btn-sm" = link_to 'Edit', edit_namespace_project_path(project.namespace, project), id: "edit_#{dom_id(project)}", class: "btn btn-sm" = link_to 'Remove', project, data: { confirm: remove_project_message(project)}, method: :delete, class: "btn btn-sm btn-remove" diff --git a/app/views/layouts/explore.html.haml b/app/views/layouts/explore.html.haml index 56bb92a536e..17fee9c510d 100644 --- a/app/views/layouts/explore.html.haml +++ b/app/views/layouts/explore.html.haml @@ -1,5 +1,8 @@ - page_title "Explore" -- header_title "Explore GitLab", explore_root_path -- sidebar "explore" +- if current_user + - header_title "Dashboard", root_path +- else + - header_title "Explore GitLab", explore_root_path +- sidebar "dashboard" = render template: "layouts/application" diff --git a/app/views/layouts/header/_default.html.haml b/app/views/layouts/header/_default.html.haml index b3cd7b0e37b..12ddbe6f1b7 100644 --- a/app/views/layouts/header/_default.html.haml +++ b/app/views/layouts/header/_default.html.haml @@ -17,13 +17,13 @@ %li.visible-sm.visible-xs = link_to search_path, title: 'Search', data: {toggle: 'tooltip', placement: 'bottom'} do = icon('search') - %li.hidden-xs + -#%li.hidden-xs = link_to help_path, title: 'Help', data: {toggle: 'tooltip', placement: 'bottom'} do = icon('question-circle fw') - %li + -#%li = link_to explore_root_path, title: 'Explore', data: {toggle: 'tooltip', placement: 'bottom'} do = icon('globe fw') - %li + -#%li = link_to user_snippets_path(current_user), title: 'Your snippets', data: {toggle: 'tooltip', placement: 'bottom'} do = icon('clipboard fw') - if current_user.is_admin? @@ -34,7 +34,7 @@ %li.hidden-xs = link_to new_project_path, title: 'New project', data: {toggle: 'tooltip', placement: 'bottom'} do = icon('plus fw') - %li + -#%li = link_to profile_path, title: 'Profile settings', data: {toggle: 'tooltip', placement: 'bottom'} do = icon('cog fw') %li diff --git a/app/views/layouts/nav/_dashboard.html.haml b/app/views/layouts/nav/_dashboard.html.haml index 687c1fc3dd2..8f010196d1a 100644 --- a/app/views/layouts/nav/_dashboard.html.haml +++ b/app/views/layouts/nav/_dashboard.html.haml @@ -1,36 +1,43 @@ %ul.nav.nav-sidebar - = nav_link(path: ['dashboard#show', 'root#show'], html_options: {class: 'home'}) do - = link_to dashboard_path, title: 'Home', class: 'shortcuts-activity', data: {placement: 'right'} do + = nav_link(path: ['dashboard#show', 'root#show', 'projects#trending', 'projects#starred', 'projects#index'], html_options: {class: 'home'}) do + = link_to (current_user ? root_path : explore_root_path), title: 'Home', class: 'shortcuts-activity', data: {placement: 'right'} do = icon('dashboard fw') %span - Your Projects - = nav_link(path: 'projects#starred') do - = link_to starred_dashboard_projects_path, title: 'Starred Projects', data: {placement: 'right'} do - = icon('star fw') - %span - Starred Projects + Projects = nav_link(controller: :groups) do - = link_to dashboard_groups_path, title: 'Groups', data: {placement: 'right'} do + = link_to (current_user ? dashboard_groups_path : explore_groups_path), title: 'Groups', data: {placement: 'right'} do = icon('group fw') %span Groups - = nav_link(controller: :milestones) do - = link_to dashboard_milestones_path, title: 'Milestones', data: {placement: 'right'} do - = icon('clock-o fw') - %span - Milestones - = nav_link(path: 'dashboard#issues') do - = link_to assigned_issues_dashboard_path, title: 'Issues', class: 'shortcuts-issues', data: {placement: 'right'} do - = icon('exclamation-circle fw') - %span - Issues - %span.count= current_user.assigned_issues.opened.count - = nav_link(path: 'dashboard#merge_requests') do - = link_to assigned_mrs_dashboard_path, title: 'Merge Requests', class: 'shortcuts-merge_requests', data: {placement: 'right'} do - = icon('tasks fw') + - if current_user + = nav_link(controller: :milestones) do + = link_to dashboard_milestones_path, title: 'Milestones', data: {placement: 'right'} do + = icon('clock-o fw') + %span + Milestones + = nav_link(path: 'dashboard#issues') do + = link_to assigned_issues_dashboard_path, title: 'Issues', class: 'shortcuts-issues', data: {placement: 'right'} do + = icon('exclamation-circle fw') + %span + Issues + %span.count= current_user.assigned_issues.opened.count + = nav_link(path: 'dashboard#merge_requests') do + = link_to assigned_mrs_dashboard_path, title: 'Merge Requests', class: 'shortcuts-merge_requests', data: {placement: 'right'} do + = icon('tasks fw') + %span + Merge Requests + %span.count= current_user.assigned_merge_requests.opened.count + = nav_link(controller: :snippets) do + = link_to (current_user ? user_snippets_path(current_user) : snippets_path), title: 'Your snippets', data: {placement: 'right'} do + = icon('dashboard fw') %span - Merge Requests - %span.count= current_user.assigned_merge_requests.opened.count + Snippets + - if current_user + = nav_link(controller: :profile) do + = link_to profile_path, title: 'Profile settings', data: {toggle: 'tooltip', placement: 'bottom'} do + = icon('user fw') + %span + Profile = nav_link(controller: :help) do = link_to help_path, title: 'Help', data: {placement: 'right'} do = icon('question-circle fw') diff --git a/app/views/layouts/nav/_explore.html.haml b/app/views/layouts/nav/_explore.html.haml deleted file mode 100644 index 66870e84ceb..00000000000 --- a/app/views/layouts/nav/_explore.html.haml +++ /dev/null @@ -1,18 +0,0 @@ -%ul.nav.nav-sidebar - = nav_link(path: 'projects#trending') do - = link_to explore_root_path, title: 'Trending Projects', data: {placement: 'right'} do - = icon('comments fw') - %span Trending Projects - = nav_link(path: 'projects#starred') do - = link_to starred_explore_projects_path, title: 'Most-starred Projects', data: {placement: 'right'} do - = icon('star fw') - %span Most-starred Projects - = nav_link(path: 'projects#index') do - = link_to explore_projects_path, title: 'All Projects', data: {placement: 'right'} do - = icon('bookmark fw') - %span All Projects - = nav_link(controller: :groups) do - = link_to explore_groups_path, title: 'All Groups', data: {placement: 'right'} do - = icon('group fw') - %span All Groups - diff --git a/app/views/layouts/nav/_snippets.html.haml b/app/views/layouts/nav/_snippets.html.haml deleted file mode 100644 index 458b76a2c99..00000000000 --- a/app/views/layouts/nav/_snippets.html.haml +++ /dev/null @@ -1,12 +0,0 @@ -%ul.nav.nav-sidebar - - if current_user - = nav_link(path: user_snippets_path(current_user), html_options: {class: 'home'}) do - = link_to user_snippets_path(current_user), title: 'Your snippets', data: {placement: 'right'} do - = icon('dashboard fw') - %span - Your Snippets - = nav_link(path: snippets_path) do - = link_to snippets_path, title: 'Discover snippets', data: {placement: 'right'} do - = icon('globe fw') - %span - Discover Snippets diff --git a/app/views/layouts/snippets.html.haml b/app/views/layouts/snippets.html.haml index 9b0f40073ab..b77fe09fc2a 100644 --- a/app/views/layouts/snippets.html.haml +++ b/app/views/layouts/snippets.html.haml @@ -1,5 +1,8 @@ - page_title 'Snippets' -- header_title 'Snippets', snippets_path -- sidebar "snippets" +- if current_user + - header_title "Dashboard", root_path +- else + - header_title 'Snippets', snippets_path +- sidebar "dashboard" = render template: "layouts/application" diff --git a/app/views/profiles/two_factor_auths/_codes.html.haml b/app/views/profiles/two_factor_auths/_codes.html.haml index 1b1395eaa17..43b58be7f98 100644 --- a/app/views/profiles/two_factor_auths/_codes.html.haml +++ b/app/views/profiles/two_factor_auths/_codes.html.haml @@ -1,6 +1,8 @@ %p.slead Should you ever lose your phone, each of these recovery codes can be used one - time each to regain access to your account. Please save them in a safe place. + time each to regain access to your account. Please save them in a safe place, or you + %b will + lose access to your account. .codes.well %ul diff --git a/app/views/projects/_bitbucket_import_modal.html.haml b/app/views/projects/_bitbucket_import_modal.html.haml index 745163e79a7..2987f6b5b22 100644 --- a/app/views/projects/_bitbucket_import_modal.html.haml +++ b/app/views/projects/_bitbucket_import_modal.html.haml @@ -5,9 +5,9 @@ %a.close{href: "#", "data-dismiss" => "modal"} × %h3 Import projects from Bitbucket .modal-body - To enable importing projects from Bitbucket, + To enable importing projects from Bitbucket, - if current_user.admin? - you need to + as administrator you need to configure - else - your GitLab administrator needs to - == #{link_to 'setup OAuth integration', 'https://gitlab.com/gitlab-org/gitlab-ce/blob/master/doc/integration/bitbucket.md'}. + ask your GitLab administrator to configure + == #{link_to 'OAuth integration', help_page_path("integration", "bitbucket")}. diff --git a/app/views/projects/_github_import_modal.html.haml b/app/views/projects/_github_import_modal.html.haml index de58b27df23..46ad1559356 100644 --- a/app/views/projects/_github_import_modal.html.haml +++ b/app/views/projects/_github_import_modal.html.haml @@ -5,9 +5,9 @@ %a.close{href: "#", "data-dismiss" => "modal"} × %h3 Import projects from GitHub .modal-body - To enable importing projects from GitHub, + To enable importing projects from GitHub, - if current_user.admin? - you need to + as administrator you need to configure - else - your GitLab administrator needs to - == #{link_to 'setup OAuth integration', 'https://gitlab.com/gitlab-org/gitlab-ce/blob/master/doc/integration/github.md'}.
\ No newline at end of file + ask your Gitlab administrator to configure + == #{link_to 'OAuth integration', help_page_path("integration", "github")}. diff --git a/app/views/projects/_gitlab_import_modal.html.haml b/app/views/projects/_gitlab_import_modal.html.haml index ae6c25f9371..377cf0187b8 100644 --- a/app/views/projects/_gitlab_import_modal.html.haml +++ b/app/views/projects/_gitlab_import_modal.html.haml @@ -5,9 +5,9 @@ %a.close{href: "#", "data-dismiss" => "modal"} × %h3 Import projects from GitLab.com .modal-body - To enable importing projects from GitLab.com, + To enable importing projects from GitLab.com, - if current_user.admin? - you need to + as administrator you need to configure - else - your GitLab administrator needs to - == #{link_to 'setup OAuth integration', 'https://gitlab.com/gitlab-org/gitlab-ce/blob/master/doc/integration/gitlab.md'}.
\ No newline at end of file + ask your GitLab administrator to configure + == #{link_to 'OAuth integration', help_page_path("integration", "gitlab")}. diff --git a/app/views/projects/blob/_editor.html.haml b/app/views/projects/blob/_editor.html.haml index 96f188e4aa7..9c3e1703c89 100644 --- a/app/views/projects/blob/_editor.html.haml +++ b/app/views/projects/blob/_editor.html.haml @@ -12,8 +12,8 @@ \/ = text_field_tag 'file_name', params[:file_name], placeholder: "File name", required: true, class: 'form-control new-file-name' - .pull-right - = select_tag :encoding, options_for_select([ "base64", "text" ], "text"), class: 'form-control' + .pull-right + = select_tag :encoding, options_for_select([ "base64", "text" ], "text"), class: 'form-control' .file-content.code %pre.js-edit-mode-pane#editor diff --git a/app/views/projects/blob/new.html.haml b/app/views/projects/blob/new.html.haml index dac984f8c31..7c2a4fece94 100644 --- a/app/views/projects/blob/new.html.haml +++ b/app/views/projects/blob/new.html.haml @@ -6,11 +6,12 @@ = render 'shared/commit_message_container', params: params, placeholder: 'Add new file' - .form-group.branch - = label_tag 'branch', class: 'control-label' do - Branch - .col-sm-10 - = text_field_tag 'new_branch', @ref, class: "form-control" + - unless @project.empty_repo? + .form-group.branch + = label_tag 'branch', class: 'control-label' do + Branch + .col-sm-10 + = text_field_tag 'new_branch', @ref, class: "form-control" = hidden_field_tag 'content', '', id: 'file-content' = render 'projects/commit_button', ref: @ref, diff --git a/app/views/projects/merge_requests/_new_compare.html.haml b/app/views/projects/merge_requests/_new_compare.html.haml index ff9c0cdb283..7709330611a 100644 --- a/app/views/projects/merge_requests/_new_compare.html.haml +++ b/app/views/projects/merge_requests/_new_compare.html.haml @@ -35,7 +35,7 @@ - if @merge_request.compare_failed .alert.alert-danger %h4 Compare failed - %p We can't compare selected branches. It may be because of huge diff or satellite timeout. Please try again or select different branches. + %p We can't compare selected branches. It may be because of huge diff. Please try again or select different branches. - else .light-well .center diff --git a/app/views/projects/merge_requests/_new_submit.html.haml b/app/views/projects/merge_requests/_new_submit.html.haml index 633a54f3620..76f44211dac 100644 --- a/app/views/projects/merge_requests/_new_submit.html.haml +++ b/app/views/projects/merge_requests/_new_submit.html.haml @@ -24,7 +24,7 @@ = icon('history') Commits %span.badge= @commits.size - %li.diffs-tab + %li.diffs-tab.active = link_to url_for(params), data: {target: '#diffs', action: 'diffs', toggle: 'tab'} do = icon('list-alt') Changes @@ -33,7 +33,7 @@ .tab-content #commits.commits.tab-pane = render "projects/commits/commits", project: @project - #diffs.diffs.tab-pane + #diffs.diffs.tab-pane.active - if @diffs.present? = render "projects/diffs/diffs", diffs: @diffs, project: @project - elsif @commits.size > MergeRequestDiff::COMMITS_SAFE_SIZE diff --git a/app/views/projects/merge_requests/automerge.js.haml b/app/views/projects/merge_requests/merge.js.haml index 33321651e32..33321651e32 100644 --- a/app/views/projects/merge_requests/automerge.js.haml +++ b/app/views/projects/merge_requests/merge.js.haml diff --git a/app/views/projects/merge_requests/show/_commits.html.haml b/app/views/projects/merge_requests/show/_commits.html.haml index 3b7f283daf0..a71b181a6a5 100644 --- a/app/views/projects/merge_requests/show/_commits.html.haml +++ b/app/views/projects/merge_requests/show/_commits.html.haml @@ -1 +1 @@ -= render "projects/commits/commits", project: @merge_request.source_project += render "projects/commits/commits", project: @merge_request.project diff --git a/app/views/projects/merge_requests/show/_diffs.html.haml b/app/views/projects/merge_requests/show/_diffs.html.haml index 786b5f39063..626970f39be 100644 --- a/app/views/projects/merge_requests/show/_diffs.html.haml +++ b/app/views/projects/merge_requests/show/_diffs.html.haml @@ -1,5 +1,5 @@ - if @merge_request_diff.collected? - = render "projects/diffs/diffs", diffs: @merge_request.diffs, project: @merge_request.source_project + = render "projects/diffs/diffs", diffs: @merge_request.diffs, project: @merge_request.project - elsif @merge_request_diff.empty? .nothing-here-block Nothing to merge from #{@merge_request.source_branch} into #{@merge_request.target_branch} - else diff --git a/app/views/projects/merge_requests/widget/_open.html.haml b/app/views/projects/merge_requests/widget/_open.html.haml index 8c61e819374..0aad9bb3e88 100644 --- a/app/views/projects/merge_requests/widget/_open.html.haml +++ b/app/views/projects/merge_requests/widget/_open.html.haml @@ -3,8 +3,6 @@ .mr-widget-body - if @project.archived? = render 'projects/merge_requests/widget/open/archived' - - elsif !@project.satellite.exists? - = render 'projects/merge_requests/widget/open/no_satellite' - elsif @merge_request.commits.blank? = render 'projects/merge_requests/widget/open/nothing' - elsif @merge_request.branch_missing? diff --git a/app/views/projects/merge_requests/widget/_show.html.haml b/app/views/projects/merge_requests/widget/_show.html.haml index 263cab7a9e8..a489d4f9b24 100644 --- a/app/views/projects/merge_requests/widget/_show.html.haml +++ b/app/views/projects/merge_requests/widget/_show.html.haml @@ -11,10 +11,10 @@ var merge_request_widget; merge_request_widget = new MergeRequestWidget({ - url_to_automerge_check: "#{automerge_check_namespace_project_merge_request_path(@project.namespace, @project, @merge_request)}", + url_to_automerge_check: "#{merge_check_namespace_project_merge_request_path(@project.namespace, @project, @merge_request)}", check_enable: #{@merge_request.unchecked? ? "true" : "false"}, url_to_ci_check: "#{ci_status_namespace_project_merge_request_path(@project.namespace, @project, @merge_request)}", ci_enable: #{@project.ci_service ? "true" : "false"}, - current_status: "#{@merge_request.automerge_status}", + current_status: "#{@merge_request.gitlab_merge_status}", }); diff --git a/app/views/projects/merge_requests/widget/open/_accept.html.haml b/app/views/projects/merge_requests/widget/open/_accept.html.haml index df20205de1c..b61e193fc42 100644 --- a/app/views/projects/merge_requests/widget/open/_accept.html.haml +++ b/app/views/projects/merge_requests/widget/open/_accept.html.haml @@ -1,4 +1,4 @@ -= form_for [:automerge, @project.namespace.becomes(Namespace), @project, @merge_request], remote: true, method: :post, html: { class: 'accept-mr-form js-requires-input' } do |f| += form_for [:merge, @project.namespace.becomes(Namespace), @project, @merge_request], remote: true, method: :post, html: { class: 'accept-mr-form js-requires-input' } do |f| = hidden_field_tag :authenticity_token, form_authenticity_token .accept-merge-holder.clearfix.js-toggle-container .accept-action diff --git a/app/views/projects/merge_requests/widget/open/_no_satellite.html.haml b/app/views/projects/merge_requests/widget/open/_no_satellite.html.haml deleted file mode 100644 index 3718cfd8333..00000000000 --- a/app/views/projects/merge_requests/widget/open/_no_satellite.html.haml +++ /dev/null @@ -1,3 +0,0 @@ -%p - %span - %strong This repository does not have a satellite. Please ask an administrator to fix this issue! diff --git a/app/views/projects/new.html.haml b/app/views/projects/new.html.haml index d25fe68242b..636218368cc 100644 --- a/app/views/projects/new.html.haml +++ b/app/views/projects/new.html.haml @@ -22,70 +22,75 @@ .col-sm-10 = f.select :namespace_id, namespaces_options(params[:namespace_id] || :current_user), {}, {class: 'select2', tabindex: 2} - %hr + - if import_sources_enabled? + %hr - .project-import.js-toggle-container - .form-group - %label.control-label Import project from - .col-sm-10 - - if github_import_enabled? - = link_to status_import_github_path, class: 'btn' do - %i.fa.fa-github - GitHub - - else - = link_to '#', class: 'how_to_import_link light btn' do - %i.fa.fa-github - GitHub - = render 'github_import_modal' - - - - if bitbucket_import_enabled? - = link_to status_import_bitbucket_path, class: 'btn', "data-no-turbolink" => "true" do - %i.fa.fa-bitbucket - Bitbucket - - else - = link_to '#', class: 'how_to_import_link light btn' do - %i.fa.fa-bitbucket - Bitbucket - = render 'bitbucket_import_modal' - - - unless request.host == 'gitlab.com' - - if gitlab_import_enabled? - = link_to status_import_gitlab_path, class: 'btn' do - %i.fa.fa-heart - GitLab.com - - else - = link_to '#', class: 'how_to_import_link light btn' do - %i.fa.fa-heart - GitLab.com - = render 'gitlab_import_modal' - - = link_to new_import_gitorious_path, class: 'btn' do - %i.icon-gitorious.icon-gitorious-small - Gitorious.org - - = link_to new_import_google_code_path, class: 'btn' do - %i.fa.fa-google - Google Code - - = link_to "#", class: 'btn js-toggle-button' do - %i.fa.fa-git - %span Any repo by URL - - .js-toggle-content.hide - .form-group.import-url-data - = f.label :import_url, class: 'control-label' do - %span Git repository URL + .project-import.js-toggle-container + .form-group + %label.control-label Import project from .col-sm-10 - = f.text_field :import_url, class: 'form-control', placeholder: 'https://username:password@gitlab.company.com/group/project.git' - .well.prepend-top-20 - %ul - %li - The repository must be accessible over HTTP(S). If it is not publicly accessible, you can add authentication information to the URL: <code>https://username:password@gitlab.company.com/group/project.git</code>. - %li - The import will time out after 4 minutes. For big repositories, use a clone/push combination. - %li - To migrate an SVN repository, check out #{link_to "this document", "http://doc.gitlab.com/ce/workflow/importing/migrating_from_svn.html"}. + - if github_import_enabled? + - if github_import_configured? + = link_to status_import_github_path, class: 'btn import_github' do + %i.fa.fa-github + GitHub + - else + = link_to '#', class: 'how_to_import_link light btn import_github' do + %i.fa.fa-github + GitHub + = render 'github_import_modal' + + - if bitbucket_import_enabled? + - if bitbucket_import_configured? + = link_to status_import_bitbucket_path, class: 'btn import_bitbucket', "data-no-turbolink" => "true" do + %i.fa.fa-bitbucket + Bitbucket + - else + = link_to status_import_bitbucket_path, class: 'how_to_import_link light btn import_bitbucket', "data-no-turbolink" => "true" do + %i.fa.fa-bitbucket + Bitbucket + = render 'bitbucket_import_modal' + + - if gitlab_import_enabled? + - if gitlab_import_configured? + = link_to status_import_gitlab_path, class: 'btn import_gitlab' do + %i.fa.fa-heart + GitLab.com + - else + = link_to status_import_gitlab_path, class: 'how_to_import_link light btn import_gitlab' do + %i.fa.fa-heart + GitLab.com + = render 'gitlab_import_modal' + + - if gitorious_import_enabled? + = link_to new_import_gitorious_path, class: 'btn import_gitorious' do + %i.icon-gitorious.icon-gitorious-small + Gitorious.org + + - if google_code_import_enabled? + = link_to new_import_google_code_path, class: 'btn import_google_code' do + %i.fa.fa-google + Google Code + + - if git_import_enabled? + = link_to "#", class: 'btn js-toggle-button import_git' do + %i.fa.fa-git + %span Any repo by URL + + .js-toggle-content.hide + .form-group.import-url-data + = f.label :import_url, class: 'control-label' do + %span Git repository URL + .col-sm-10 + = f.text_field :import_url, class: 'form-control', placeholder: 'https://username:password@gitlab.company.com/group/project.git' + .well.prepend-top-20 + %ul + %li + The repository must be accessible over HTTP(S). If it is not publicly accessible, you can add authentication information to the URL: <code>https://username:password@gitlab.company.com/group/project.git</code>. + %li + The import will time out after 4 minutes. For big repositories, use a clone/push combination. + %li + To migrate an SVN repository, check out #{link_to "this document", "http://doc.gitlab.com/ce/workflow/importing/migrating_from_svn.html"}. %hr.prepend-botton-10 diff --git a/app/views/snippets/_head.html.haml b/app/views/snippets/_head.html.haml new file mode 100644 index 00000000000..0adf6b91f2c --- /dev/null +++ b/app/views/snippets/_head.html.haml @@ -0,0 +1,7 @@ +%ul.center-top-menu + = nav_link(page: user_snippets_path(current_user), html_options: {class: 'home'}) do + = link_to user_snippets_path(current_user), title: 'Your snippets', data: {placement: 'right'} do + Your Snippets + = nav_link(page: snippets_path) do + = link_to snippets_path, title: 'Explore snippets', data: {placement: 'right'} do + Explore Snippets diff --git a/app/views/snippets/current_user_index.html.haml b/app/views/snippets/current_user_index.html.haml index 0718f743828..62a967a2e06 100644 --- a/app/views/snippets/current_user_index.html.haml +++ b/app/views/snippets/current_user_index.html.haml @@ -1,13 +1,13 @@ - page_title "Your Snippets" -%h3.page-title - Your Snippets - .pull-right - = link_to new_snippet_path, class: "btn btn-new btn-grouped", title: "New Snippet" do - Add new snippet += render 'head' -%p.light +.slead Share code pastes with others out of git repository + .pull-right + = link_to new_snippet_path, class: "btn btn-new btn-sm", title: "New Snippet" do + Add new snippet + %ul.nav.nav-tabs = nav_tab :scope, nil do = link_to user_snippets_path(@user) do diff --git a/app/views/snippets/index.html.haml b/app/views/snippets/index.html.haml index e9bb6a908d3..8608815e0a6 100644 --- a/app/views/snippets/index.html.haml +++ b/app/views/snippets/index.html.haml @@ -1,17 +1,9 @@ - page_title "Public Snippets" -%h3.page-title - Public snippets +- if current_user + = render 'head' - .pull-right - - if current_user - = link_to new_snippet_path, class: "btn btn-new btn-grouped", title: "New Snippet" do - Add new snippet - = link_to user_snippets_path(current_user), class: "btn btn-grouped" do - Your snippets - -%p.light +.slead Public snippets created by you and other users are listed here -%hr = render 'snippets' diff --git a/app/views/snippets/show.html.haml b/app/views/snippets/show.html.haml index 089e8122918..aed00f9caeb 100644 --- a/app/views/snippets/show.html.haml +++ b/app/views/snippets/show.html.haml @@ -1,5 +1,5 @@ - page_title @snippet.title, "Snippets" -%h3.page-title +%h4.page-title = @snippet.title - if @snippet.private? @@ -8,17 +8,14 @@ private .pull-right - = link_to new_snippet_path, class: "btn btn-new", title: "New Snippet" do + = link_to new_snippet_path, class: "btn btn-new btn-sm", title: "New Snippet" do Add new snippet -%hr -.append-bottom-20 +.append-bottom-10.prepend-top-10 .pull-right - = "##{@snippet.id}" %span.light - by + created by = link_to user_snippets_path(@snippet.author) do - = image_tag avatar_icon(@snippet.author_email), class: "avatar avatar-inline s16", alt: '' = @snippet.author_name .back-link @@ -27,7 +24,7 @@ ← your snippets - else = link_to snippets_path do - ← discover snippets + ← explore snippets .file-holder .file-title diff --git a/app/views/snippets/user_index.html.haml b/app/views/snippets/user_index.html.haml index 23700eb39da..7af5352da34 100644 --- a/app/views/snippets/user_index.html.haml +++ b/app/views/snippets/user_index.html.haml @@ -1,14 +1,13 @@ - page_title "Snippets", @user.name -%h3.page-title - = image_tag avatar_icon(@user.email), class: "avatar s24" - = @user.name - %span - \/ - Snippets - - if current_user - = link_to new_snippet_path, class: "btn btn-sm add_new pull-right", title: "New Snippet" do - Add new snippet -%hr +%ol.breadcrumb + %li + = link_to snippets_path do + Snippets + %li + = @user.name + .pull-right.hidden-xs + = link_to user_path(@user) do + #{@user.name} profile page = render 'snippets' diff --git a/app/workers/auto_merge_worker.rb b/app/workers/auto_merge_worker.rb deleted file mode 100644 index a6dd73eee5f..00000000000 --- a/app/workers/auto_merge_worker.rb +++ /dev/null @@ -1,13 +0,0 @@ -class AutoMergeWorker - include Sidekiq::Worker - - sidekiq_options queue: :default - - def perform(merge_request_id, current_user_id, params) - params = params.with_indifferent_access - current_user = User.find(current_user_id) - merge_request = MergeRequest.find(merge_request_id) - merge_request.should_remove_source_branch = params[:should_remove_source_branch] - merge_request.automerge!(current_user, params[:commit_message]) - end -end diff --git a/app/workers/merge_worker.rb b/app/workers/merge_worker.rb new file mode 100644 index 00000000000..6a8665c179a --- /dev/null +++ b/app/workers/merge_worker.rb @@ -0,0 +1,19 @@ +class MergeWorker + include Sidekiq::Worker + + sidekiq_options queue: :default + + def perform(merge_request_id, current_user_id, params) + params = params.with_indifferent_access + current_user = User.find(current_user_id) + merge_request = MergeRequest.find(merge_request_id) + + result = MergeRequests::MergeService.new(merge_request.target_project, current_user). + execute(merge_request, params[:commit_message]) + + if result[:status] == :success && params[:should_remove_source_branch].present? + DeleteBranchService.new(merge_request.source_project, current_user). + execute(merge_request.source_branch) + end + end +end diff --git a/app/workers/repository_import_worker.rb b/app/workers/repository_import_worker.rb index 94832872d13..b546f8777e1 100644 --- a/app/workers/repository_import_worker.rb +++ b/app/workers/repository_import_worker.rb @@ -27,7 +27,6 @@ class RepositoryImportWorker project.import_finish project.save - project.satellite.create unless project.satellite.exists? ProjectCacheWorker.perform_async(project.id) Gitlab::BitbucketImport::KeyDeleter.new(project).execute if project.import_type == 'bitbucket' end |