diff options
Diffstat (limited to 'app/services')
-rw-r--r-- | app/services/create_snippet_service.rb | 9 | ||||
-rw-r--r-- | app/services/labels/promote_service.rb | 71 | ||||
-rw-r--r-- | app/services/merge_requests/build_service.rb | 129 | ||||
-rw-r--r-- | app/services/notification_service.rb | 8 | ||||
-rw-r--r-- | app/services/projects/update_service.rb | 2 | ||||
-rw-r--r-- | app/services/search/global_service.rb | 5 |
6 files changed, 161 insertions, 63 deletions
diff --git a/app/services/create_snippet_service.rb b/app/services/create_snippet_service.rb index 95cc9baf406..14f5ba064ff 100644 --- a/app/services/create_snippet_service.rb +++ b/app/services/create_snippet_service.rb @@ -1,5 +1,8 @@ class CreateSnippetService < BaseService def execute + request = params.delete(:request) + api = params.delete(:api) + snippet = if project project.snippets.build(params) else @@ -12,8 +15,12 @@ class CreateSnippetService < BaseService end snippet.author = current_user + snippet.spam = SpamService.new(snippet, request).check(api) + + if snippet.save + UserAgentDetailService.new(snippet, request).create + end - snippet.save snippet end end diff --git a/app/services/labels/promote_service.rb b/app/services/labels/promote_service.rb new file mode 100644 index 00000000000..76d0ba67b07 --- /dev/null +++ b/app/services/labels/promote_service.rb @@ -0,0 +1,71 @@ +module Labels + class PromoteService < BaseService + BATCH_SIZE = 1000 + + def execute(label) + return unless project.group && + label.is_a?(ProjectLabel) + + Label.transaction do + new_label = clone_label_to_group_label(label) + + label_ids_for_merge(new_label).find_in_batches(batch_size: BATCH_SIZE) do |batched_ids| + update_issuables(new_label, batched_ids) + update_issue_board_lists(new_label, batched_ids) + update_priorities(new_label, batched_ids) + # Order is important, project labels need to be last + update_project_labels(batched_ids) + end + + # We skipped validations during creation. Let's run them now, after deleting conflicting labels + raise ActiveRecord::RecordInvalid.new(new_label) unless new_label.valid? + new_label + end + end + + private + + def label_ids_for_merge(new_label) + LabelsFinder. + new(current_user, title: new_label.title, group_id: project.group.id). + execute(skip_authorization: true). + where.not(id: new_label). + select(:id) # Can't use pluck() to avoid object-creation because of the batching + end + + def update_issuables(new_label, label_ids) + LabelLink. + where(label: label_ids). + update_all(label_id: new_label) + end + + def update_issue_board_lists(new_label, label_ids) + List. + where(label: label_ids). + update_all(label_id: new_label) + end + + def update_priorities(new_label, label_ids) + LabelPriority. + where(label: label_ids). + update_all(label_id: new_label) + end + + def update_project_labels(label_ids) + Label.where(id: label_ids).delete_all + end + + def clone_label_to_group_label(label) + params = label.attributes.slice('title', 'description', 'color') + # Since the title of the new label has to be the same as the previous labels + # and we're merging old labels in batches we'll skip validation to omit 2-step + # merge process and do it in one batch + # We'll be forcing validation at the end of the transaction to ensure everything + # was merged correctly + new_label = GroupLabel.new(params.merge(group: project.group)) + new_label.save(validate: false) + + new_label + end + end +end diff --git a/app/services/merge_requests/build_service.rb b/app/services/merge_requests/build_service.rb index 6a7393a9921..1d6d2754559 100644 --- a/app/services/merge_requests/build_service.rb +++ b/app/services/merge_requests/build_service.rb @@ -1,62 +1,88 @@ module MergeRequests class BuildService < MergeRequests::BaseService def execute - merge_request = MergeRequest.new(params) - - # Set MR attributes - merge_request.can_be_created = true + self.merge_request = MergeRequest.new(params) + merge_request.can_be_created = true merge_request.compare_commits = [] - merge_request.source_project = project unless merge_request.source_project + merge_request.source_project = find_source_project + merge_request.target_project = find_target_project + merge_request.target_branch = find_target_branch + + if branches_specified? && branches_valid? + compare_branches + assign_title_and_description + else + merge_request.can_be_created = false + end + + merge_request + end - merge_request.target_project = nil unless can?(current_user, :read_project, merge_request.target_project) + private - merge_request.target_project ||= (project.forked_from_project || project) - merge_request.target_branch ||= merge_request.target_project.default_branch + attr_accessor :merge_request - messages = validate_branches(merge_request) - return build_failed(merge_request, messages) unless messages.empty? + delegate :target_branch, :source_branch, :source_project, :target_project, :compare_commits, :wip_title, :description, :errors, to: :merge_request + + def find_source_project + source_project || project + end + def find_target_project + return target_project if target_project.present? && can?(current_user, :read_project, target_project) + project.forked_from_project || project + end + + def find_target_branch + target_branch || target_project.default_branch + end + + def branches_specified? + params[:source_branch] && params[:target_branch] + end + + def branches_valid? + validate_branches + errors.blank? + end + + def compare_branches compare = CompareService.new.execute( - merge_request.source_project, - merge_request.source_branch, - merge_request.target_project, - merge_request.target_branch, + source_project, + source_branch, + target_project, + target_branch ) merge_request.compare_commits = compare.commits merge_request.compare = compare - - set_title_and_description(merge_request) end - private - - def validate_branches(merge_request) - messages = [] - - if merge_request.target_branch.blank? || merge_request.source_branch.blank? - messages << - if params[:source_branch] || params[:target_branch] - "You must select source and target branch" - end - end + def validate_branches + add_error('You must select source and target branch') unless branches_present? + add_error('You must select different branches') if same_source_and_target? + add_error("Source branch \"#{source_branch}\" does not exist") unless source_branch_exists? + add_error("Target branch \"#{target_branch}\" does not exist") unless target_branch_exists? + end - if merge_request.source_project == merge_request.target_project && - merge_request.target_branch == merge_request.source_branch + def add_error(message) + errors.add(:base, message) + end - messages << 'You must select different branches' - end + def branches_present? + target_branch.present? && source_branch.present? + end - # See if source and target branches exist - if merge_request.source_branch.present? && !merge_request.source_project.commit(merge_request.source_branch) - messages << "Source branch \"#{merge_request.source_branch}\" does not exist" - end + def same_source_and_target? + source_project == target_project && target_branch == source_branch + end - if merge_request.target_branch.present? && !merge_request.target_project.commit(merge_request.target_branch) - messages << "Target branch \"#{merge_request.target_branch}\" does not exist" - end + def source_branch_exists? + source_branch.blank? || source_project.commit(source_branch) + end - messages + def target_branch_exists? + target_branch.blank? || target_project.commit(target_branch) end # When your branch name starts with an iid followed by a dash this pattern will be @@ -71,17 +97,17 @@ module MergeRequests # - Setting the title as 'Resolves "Emoji don't show up in commit title"' if there is # more than one commit in the MR # - def set_title_and_description(merge_request) - if match = merge_request.source_branch.match(/\A(\d+)-/) + def assign_title_and_description + if match = source_branch.match(/\A(\d+)-/) iid = match[1] end - commits = merge_request.compare_commits + commits = compare_commits if commits && commits.count == 1 commit = commits.first merge_request.title = commit.title merge_request.description ||= commit.description.try(:strip) - elsif iid && issue = merge_request.target_project.get_issue(iid, current_user) + elsif iid && issue = target_project.get_issue(iid, current_user) case issue when Issue merge_request.title = "Resolve \"#{issue.title}\"" @@ -89,31 +115,20 @@ module MergeRequests merge_request.title = "Resolve #{issue.title}" end else - merge_request.title = merge_request.source_branch.titleize.humanize + merge_request.title = source_branch.titleize.humanize end if iid closes_issue = "Closes ##{iid}" - if merge_request.description.present? + if description.present? merge_request.description += closes_issue.prepend("\n\n") else merge_request.description = closes_issue end end - merge_request.title = merge_request.wip_title if commits.empty? - - merge_request - end - - def build_failed(merge_request, messages) - messages.compact.each do |message| - merge_request.errors.add(:base, message) - end - merge_request.compare_commits = [] - merge_request.can_be_created = false - merge_request + merge_request.title = wip_title if commits.empty? end end end diff --git a/app/services/notification_service.rb b/app/services/notification_service.rb index f74e6cac174..b2cc39763f3 100644 --- a/app/services/notification_service.rb +++ b/app/services/notification_service.rb @@ -365,7 +365,7 @@ class NotificationService users = users_with_global_level_watch([users_with_project_level_global, users_with_group_level_global].flatten.uniq) users_with_project_setting = select_project_member_setting(project, users_with_project_level_global, users) - users_with_group_setting = select_group_member_setting(project, project_members, users_with_group_level_global, users) + users_with_group_setting = select_group_member_setting(project.group, project_members, users_with_group_level_global, users) User.where(id: users_with_project_setting.concat(users_with_group_setting).uniq).to_a end @@ -415,8 +415,8 @@ class NotificationService end # Build a list of users based on group notification settings - def select_group_member_setting(project, project_members, global_setting, users_global_level_watch) - uids = notification_settings_for(project, :watch) + def select_group_member_setting(group, project_members, global_setting, users_global_level_watch) + uids = notification_settings_for(group, :watch) # Group setting is watch, add to users list if user is not project member users = [] @@ -473,7 +473,7 @@ class NotificationService setting = user.notification_settings_for(project) - if !setting && project.group + if project.group && (setting.nil? || setting.global?) setting = user.notification_settings_for(project.group) end diff --git a/app/services/projects/update_service.rb b/app/services/projects/update_service.rb index 842e23eb6b6..55d9cb13ae4 100644 --- a/app/services/projects/update_service.rb +++ b/app/services/projects/update_service.rb @@ -22,6 +22,8 @@ module Projects if project.update_attributes(params.except(:default_branch)) if project.previous_changes.include?('path') project.rename_repo + else + system_hook_service.execute_hooks_for(project, :update) end success diff --git a/app/services/search/global_service.rb b/app/services/search/global_service.rb index aa9837038a6..781cd13b44b 100644 --- a/app/services/search/global_service.rb +++ b/app/services/search/global_service.rb @@ -9,7 +9,10 @@ module Search def execute group = Group.find_by(id: params[:group_id]) if params[:group_id].present? projects = ProjectsFinder.new.execute(current_user) - projects = projects.in_namespace(group.id) if group + + if group + projects = projects.inside_path(group.full_path) + end Gitlab::SearchResults.new(current_user, projects, params[:search]) end |