summaryrefslogtreecommitdiff
path: root/app/services
diff options
context:
space:
mode:
Diffstat (limited to 'app/services')
-rw-r--r--app/services/archive_repository_service.rb23
-rw-r--r--app/services/ci/image_for_build_service.rb19
-rw-r--r--app/services/create_branch_service.rb6
-rw-r--r--app/services/create_spam_log_service.rb13
-rw-r--r--app/services/delete_branch_service.rb6
-rw-r--r--app/services/git_push_service.rb115
-rw-r--r--app/services/projects/destroy_service.rb14
-rw-r--r--app/services/system_note_service.rb19
8 files changed, 111 insertions, 104 deletions
diff --git a/app/services/archive_repository_service.rb b/app/services/archive_repository_service.rb
deleted file mode 100644
index 2160bf13e6d..00000000000
--- a/app/services/archive_repository_service.rb
+++ /dev/null
@@ -1,23 +0,0 @@
-class ArchiveRepositoryService
- attr_reader :project, :ref, :format
-
- def initialize(project, ref, format)
- format ||= 'tar.gz'
- @project, @ref, @format = project, ref, format.downcase
- end
-
- def execute(options = {})
- RepositoryArchiveCacheWorker.perform_async
-
- metadata = project.repository.archive_metadata(ref, storage_path, format)
- raise "Repository or ref not found" if metadata.empty?
-
- metadata
- end
-
- private
-
- def storage_path
- Gitlab.config.gitlab.repository_downloads_path
- end
-end
diff --git a/app/services/ci/image_for_build_service.rb b/app/services/ci/image_for_build_service.rb
index f469b13e902..005a5c4661c 100644
--- a/app/services/ci/image_for_build_service.rb
+++ b/app/services/ci/image_for_build_service.rb
@@ -1,28 +1,23 @@
module Ci
class ImageForBuildService
- def execute(project, params)
- sha = params[:sha]
- sha ||=
- if params[:ref]
- project.commit(params[:ref]).try(:sha)
- end
+ def execute(project, opts)
+ sha = opts[:sha] || ref_sha(project, opts[:ref])
commit = project.ci_commits.ordered.find_by(sha: sha)
image_name = image_for_commit(commit)
image_path = Rails.root.join('public/ci', image_name)
-
- OpenStruct.new(
- path: image_path,
- name: image_name
- )
+ OpenStruct.new(path: image_path, name: image_name)
end
private
+ def ref_sha(project, ref)
+ project.commit(ref).try(:sha) if ref
+ end
+
def image_for_commit(commit)
return 'build-unknown.svg' unless commit
-
'build-' + commit.status + ".svg"
end
end
diff --git a/app/services/create_branch_service.rb b/app/services/create_branch_service.rb
index c0e08a151f2..707c2f7ff85 100644
--- a/app/services/create_branch_service.rb
+++ b/app/services/create_branch_service.rb
@@ -29,11 +29,7 @@ class CreateBranchService < BaseService
end
if new_branch
- push_data = build_push_data(project, current_user, new_branch)
-
- project.execute_hooks(push_data.dup, :push_hooks)
- project.execute_services(push_data.dup, :push_hooks)
-
+ # GitPushService handles execution of services and hooks for branch pushes
success(new_branch)
else
error('Invalid reference name')
diff --git a/app/services/create_spam_log_service.rb b/app/services/create_spam_log_service.rb
new file mode 100644
index 00000000000..59a66fde47a
--- /dev/null
+++ b/app/services/create_spam_log_service.rb
@@ -0,0 +1,13 @@
+class CreateSpamLogService < BaseService
+ def initialize(project, user, params)
+ super(project, user, params)
+ end
+
+ def execute
+ spam_params = params.merge({ user_id: @current_user.id,
+ project_id: @project.id } )
+ spam_log = SpamLog.new(spam_params)
+ spam_log.save
+ spam_log
+ end
+end
diff --git a/app/services/delete_branch_service.rb b/app/services/delete_branch_service.rb
index 004b3ce7286..fae069ee4a5 100644
--- a/app/services/delete_branch_service.rb
+++ b/app/services/delete_branch_service.rb
@@ -25,11 +25,7 @@ class DeleteBranchService < BaseService
end
if repository.rm_branch(current_user, branch_name)
- push_data = build_push_data(branch)
-
- project.execute_hooks(push_data.dup, :push_hooks)
- project.execute_services(push_data.dup, :push_hooks)
-
+ # GitPushService handles execution of services and hooks for branch pushes
success('Branch was removed')
else
error('Failed to remove branch')
diff --git a/app/services/git_push_service.rb b/app/services/git_push_service.rb
index d7ea30bc315..a1711d234ff 100644
--- a/app/services/git_push_service.rb
+++ b/app/services/git_push_service.rb
@@ -1,10 +1,10 @@
-class GitPushService
- attr_accessor :project, :user, :push_data, :push_commits
+class GitPushService < BaseService
+ attr_accessor :push_data, :push_commits
include Gitlab::CurrentSettings
include Gitlab::Access
# This method will be called after each git update
- # and only if the provided user and project is present in GitLab.
+ # and only if the provided user and project are present in GitLab.
#
# All callbacks for post receive action should be placed here.
#
@@ -15,62 +15,67 @@ class GitPushService
# 4. Executes the project's web hooks
# 5. Executes the project's services
#
- def execute(project, user, oldrev, newrev, ref)
- @project, @user = project, user
+ def execute
+ @project.repository.expire_cache(branch_name)
- project.repository.expire_cache
-
- if push_remove_branch?(ref, newrev)
+ if push_remove_branch?
+ @project.repository.expire_has_visible_content_cache
@push_commits = []
- elsif push_to_new_branch?(ref, oldrev)
+ elsif push_to_new_branch?
+ @project.repository.expire_has_visible_content_cache
+
# Re-find the pushed commits.
- if is_default_branch?(ref)
+ if is_default_branch?
# Initial push to the default branch. Take the full history of that branch as "newly pushed".
- @push_commits = project.repository.commits(newrev)
-
- # Ensure HEAD points to the default branch in case it is not master
- branch_name = Gitlab::Git.ref_name(ref)
- project.change_head(branch_name)
-
- # Set protection on the default branch if configured
- if (current_application_settings.default_branch_protection != PROTECTION_NONE)
- developers_can_push = current_application_settings.default_branch_protection == PROTECTION_DEV_CAN_PUSH ? true : false
- project.protected_branches.create({ name: project.default_branch, developers_can_push: developers_can_push })
- end
+ process_default_branch
else
# Use the pushed commits that aren't reachable by the default branch
# as a heuristic. This may include more commits than are actually pushed, but
# that shouldn't matter because we check for existing cross-references later.
- @push_commits = project.repository.commits_between(project.default_branch, newrev)
+ @push_commits = @project.repository.commits_between(@project.default_branch, params[:newrev])
# don't process commits for the initial push to the default branch
- process_commit_messages(ref)
+ process_commit_messages
end
- elsif push_to_existing_branch?(ref, oldrev)
+ elsif push_to_existing_branch?
# Collect data for this git push
- @push_commits = project.repository.commits_between(oldrev, newrev)
- process_commit_messages(ref)
+ @push_commits = @project.repository.commits_between(params[:oldrev], params[:newrev])
+ process_commit_messages
end
-
# Update merge requests that may be affected by this push. A new branch
# could cause the last commit of a merge request to change.
- project.update_merge_requests(oldrev, newrev, ref, @user)
+ update_merge_requests
+ end
+
+ protected
- @push_data = build_push_data(oldrev, newrev, ref)
+ def update_merge_requests
+ @project.update_merge_requests(params[:oldrev], params[:newrev], params[:ref], current_user)
- EventCreateService.new.push(project, user, @push_data)
- project.execute_hooks(@push_data.dup, :push_hooks)
- project.execute_services(@push_data.dup, :push_hooks)
- CreateCommitBuildsService.new.execute(project, @user, @push_data)
- ProjectCacheWorker.perform_async(project.id)
+ EventCreateService.new.push(@project, current_user, build_push_data)
+ @project.execute_hooks(build_push_data.dup, :push_hooks)
+ @project.execute_services(build_push_data.dup, :push_hooks)
+ CreateCommitBuildsService.new.execute(@project, current_user, build_push_data)
+ ProjectCacheWorker.perform_async(@project.id)
end
- protected
+ def process_default_branch
+ @push_commits = project.repository.commits(params[:newrev])
+
+ # Ensure HEAD points to the default branch in case it is not master
+ project.change_head(branch_name)
+
+ # Set protection on the default branch if configured
+ if (current_application_settings.default_branch_protection != PROTECTION_NONE)
+ developers_can_push = current_application_settings.default_branch_protection == PROTECTION_DEV_CAN_PUSH ? true : false
+ @project.protected_branches.create({ name: @project.default_branch, developers_can_push: developers_can_push })
+ end
+ end
# Extract any GFM references from the pushed commit messages. If the configured issue-closing regex is matched,
# close the referenced Issue. Create cross-reference Notes corresponding to any other referenced Mentionables.
- def process_commit_messages(ref)
- is_default_branch = is_default_branch?(ref)
+ def process_commit_messages
+ is_default_branch = is_default_branch?
authors = Hash.new do |hash, commit|
email = commit.author_email
@@ -89,7 +94,7 @@ class GitPushService
# Close issues if these commits were pushed to the project's default branch and the commit message matches the
# closing regex. Exclude any mentioned Issues from cross-referencing even if the commits are being pushed to
# a different branch.
- closed_issues = commit.closes_issues(user)
+ closed_issues = commit.closes_issues(current_user)
closed_issues.each do |issue|
Issues::CloseService.new(project, authors[commit], {}).execute(issue, commit)
end
@@ -99,34 +104,38 @@ class GitPushService
end
end
- def build_push_data(oldrev, newrev, ref)
- Gitlab::PushDataBuilder.
- build(project, user, oldrev, newrev, ref, push_commits)
+ def build_push_data
+ @push_data ||= Gitlab::PushDataBuilder.
+ build(@project, current_user, params[:oldrev], params[:newrev], params[:ref], push_commits)
end
- def push_to_existing_branch?(ref, oldrev)
+ def push_to_existing_branch?
# Return if this is not a push to a branch (e.g. new commits)
- Gitlab::Git.branch_ref?(ref) && !Gitlab::Git.blank_ref?(oldrev)
+ Gitlab::Git.branch_ref?(params[:ref]) && !Gitlab::Git.blank_ref?(params[:oldrev])
end
- def push_to_new_branch?(ref, oldrev)
- Gitlab::Git.branch_ref?(ref) && Gitlab::Git.blank_ref?(oldrev)
+ def push_to_new_branch?
+ Gitlab::Git.branch_ref?(params[:ref]) && Gitlab::Git.blank_ref?(params[:oldrev])
end
- def push_remove_branch?(ref, newrev)
- Gitlab::Git.branch_ref?(ref) && Gitlab::Git.blank_ref?(newrev)
+ def push_remove_branch?
+ Gitlab::Git.branch_ref?(params[:ref]) && Gitlab::Git.blank_ref?(params[:newrev])
end
- def push_to_branch?(ref)
- Gitlab::Git.branch_ref?(ref)
+ def push_to_branch?
+ Gitlab::Git.branch_ref?(params[:ref])
end
- def is_default_branch?(ref)
- Gitlab::Git.branch_ref?(ref) &&
- (Gitlab::Git.ref_name(ref) == project.default_branch || project.default_branch.nil?)
+ def is_default_branch?
+ Gitlab::Git.branch_ref?(params[:ref]) &&
+ (Gitlab::Git.ref_name(params[:ref]) == project.default_branch || project.default_branch.nil?)
end
def commit_user(commit)
- commit.author || user
+ commit.author || current_user
+ end
+
+ def branch_name
+ @branch_name ||= Gitlab::Git.ref_name(params[:ref])
end
end
diff --git a/app/services/projects/destroy_service.rb b/app/services/projects/destroy_service.rb
index 294157b4f0e..f4dcb142850 100644
--- a/app/services/projects/destroy_service.rb
+++ b/app/services/projects/destroy_service.rb
@@ -16,11 +16,15 @@ module Projects
return false unless can?(current_user, :remove_project, project)
project.team.truncate
- project.repository.expire_cache unless project.empty_repo?
repo_path = project.path_with_namespace
wiki_path = repo_path + '.wiki'
+ # Flush the cache for both repositories. This has to be done _before_
+ # removing the physical repositories as some expiration code depends on
+ # Git data (e.g. a list of branch names).
+ flush_caches(project, wiki_path)
+
Project.transaction do
project.destroy!
@@ -70,5 +74,13 @@ module Projects
def removal_path(path)
"#{path}+#{project.id}#{DELETED_FLAG}"
end
+
+ def flush_caches(project, wiki_path)
+ project.repository.expire_all_caches! if project.repository.exists?
+
+ wiki_repo = Repository.new(wiki_path, project)
+
+ wiki_repo.expire_all_caches! if wiki_repo.exists?
+ end
end
end
diff --git a/app/services/system_note_service.rb b/app/services/system_note_service.rb
index 1083bcec054..edced010811 100644
--- a/app/services/system_note_service.rb
+++ b/app/services/system_note_service.rb
@@ -274,12 +274,15 @@ class SystemNoteService
# Check if a cross reference to a noteable from a mentioner already exists
#
# This method is used to prevent multiple notes being created for a mention
- # when a issue is updated, for example.
+ # when a issue is updated, for example. The method also calls notes_for_mentioner
+ # to check if the mentioner is a commit, and return matches only on commit hash
+ # instead of project + commit, to avoid repeated mentions from forks.
#
# noteable - Noteable object being referenced
# mentioner - Mentionable object
#
# Returns Boolean
+
def self.cross_reference_exists?(noteable, mentioner)
# Initial scope should be system notes of this noteable type
notes = Note.system.where(noteable_type: noteable.class)
@@ -291,14 +294,20 @@ class SystemNoteService
notes = notes.where(noteable_id: noteable.id)
end
- gfm_reference = mentioner.gfm_reference(noteable.project)
- notes = notes.where(note: cross_reference_note_content(gfm_reference))
-
- notes.count > 0
+ notes_for_mentioner(mentioner, noteable, notes).count > 0
end
private
+ def self.notes_for_mentioner(mentioner, noteable, notes)
+ if mentioner.is_a?(Commit)
+ notes.where('note LIKE ?', "#{cross_reference_note_prefix}%#{mentioner.to_reference(nil)}")
+ else
+ gfm_reference = mentioner.gfm_reference(noteable.project)
+ notes.where(note: cross_reference_note_content(gfm_reference))
+ end
+ end
+
def self.create_note(args = {})
Note.create(args.merge(system: true))
end