Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/api/branches.rb7
-rw-r--r--lib/banzai/filter/abstract_reference_filter.rb5
-rw-r--r--lib/banzai/filter/issue_reference_filter.rb2
-rw-r--r--lib/banzai/filter/reference_filter.rb4
-rw-r--r--lib/banzai/filter/syntax_highlight_filter.rb6
-rw-r--r--lib/banzai/filter/user_reference_filter.rb4
-rw-r--r--lib/banzai/filter/video_link_filter.rb3
-rw-r--r--lib/banzai/pipeline/gfm_pipeline.rb6
-rw-r--r--lib/banzai/renderer.rb4
-rw-r--r--lib/ci/api/builds.rb25
-rw-r--r--lib/gitlab/job_waiter.rb27
-rw-r--r--lib/gitlab/sidekiq_status.rb66
-rw-r--r--lib/gitlab/sidekiq_status/client_middleware.rb10
-rw-r--r--lib/gitlab/sidekiq_status/server_middleware.rb13
-rw-r--r--lib/gitlab/visibility_level.rb1
-rw-r--r--lib/tasks/gitlab/info.rake5
16 files changed, 162 insertions, 26 deletions
diff --git a/lib/api/branches.rb b/lib/api/branches.rb
index 0950c3d2e88..be659fa4a6a 100644
--- a/lib/api/branches.rb
+++ b/lib/api/branches.rb
@@ -129,12 +129,7 @@ module API
end
end
- # Delete all merged branches
- #
- # Parameters:
- # id (required) - The ID of a project
- # Example Request:
- # DELETE /projects/:id/repository/branches/delete_merged
+ desc 'Delete all merged branches'
delete ":id/repository/merged_branches" do
DeleteMergedBranchesService.new(user_project, current_user).async_execute
diff --git a/lib/banzai/filter/abstract_reference_filter.rb b/lib/banzai/filter/abstract_reference_filter.rb
index 6d04f68c8f9..a3d495a5da0 100644
--- a/lib/banzai/filter/abstract_reference_filter.rb
+++ b/lib/banzai/filter/abstract_reference_filter.rb
@@ -153,7 +153,7 @@ module Banzai
title = object_link_title(object)
klass = reference_class(object_sym)
- data = data_attributes_for(link_content || match, project, object)
+ data = data_attributes_for(link_content || match, project, object, link: !!link_content)
if matches.names.include?("url") && matches[:url]
url = matches[:url]
@@ -172,9 +172,10 @@ module Banzai
end
end
- def data_attributes_for(text, project, object)
+ def data_attributes_for(text, project, object, link: false)
data_attribute(
original: text,
+ link: link,
project: project.id,
object_sym => object.id
)
diff --git a/lib/banzai/filter/issue_reference_filter.rb b/lib/banzai/filter/issue_reference_filter.rb
index 4d1bc687696..fd6b9704132 100644
--- a/lib/banzai/filter/issue_reference_filter.rb
+++ b/lib/banzai/filter/issue_reference_filter.rb
@@ -62,7 +62,7 @@ module Banzai
end
end
- def data_attributes_for(text, project, object)
+ def data_attributes_for(text, project, object, link: false)
if object.is_a?(ExternalIssue)
data_attribute(
project: project.id,
diff --git a/lib/banzai/filter/reference_filter.rb b/lib/banzai/filter/reference_filter.rb
index ab7af1cad21..6640168bfa2 100644
--- a/lib/banzai/filter/reference_filter.rb
+++ b/lib/banzai/filter/reference_filter.rb
@@ -53,6 +53,10 @@ module Banzai
context[:project]
end
+ def skip_project_check?
+ context[:skip_project_check]
+ end
+
def reference_class(type)
"gfm gfm-#{type} has-tooltip"
end
diff --git a/lib/banzai/filter/syntax_highlight_filter.rb b/lib/banzai/filter/syntax_highlight_filter.rb
index 026b81ac175..a447e2b8bff 100644
--- a/lib/banzai/filter/syntax_highlight_filter.rb
+++ b/lib/banzai/filter/syntax_highlight_filter.rb
@@ -20,17 +20,19 @@ module Banzai
code = node.text
css_classes = "code highlight"
lexer = lexer_for(language)
+ lang = lexer.tag
begin
code = format(lex(lexer, code))
- css_classes << " js-syntax-highlight #{lexer.tag}"
+ css_classes << " js-syntax-highlight #{lang}"
rescue
+ lang = nil
# Gracefully handle syntax highlighter bugs/errors to ensure
# users can still access an issue/comment/etc.
end
- highlighted = %(<pre class="#{css_classes}" v-pre="true"><code>#{code}</code></pre>)
+ highlighted = %(<pre class="#{css_classes}" lang="#{lang}" v-pre="true"><code>#{code}</code></pre>)
# Extracted to a method to measure it
replace_parent_pre_element(node, highlighted)
diff --git a/lib/banzai/filter/user_reference_filter.rb b/lib/banzai/filter/user_reference_filter.rb
index f842b1fb779..1aa9355b256 100644
--- a/lib/banzai/filter/user_reference_filter.rb
+++ b/lib/banzai/filter/user_reference_filter.rb
@@ -24,7 +24,7 @@ module Banzai
end
def call
- return doc if project.nil?
+ return doc if project.nil? && !skip_project_check?
ref_pattern = User.reference_pattern
ref_pattern_start = /\A#{ref_pattern}\z/
@@ -58,7 +58,7 @@ module Banzai
# have `gfm` and `gfm-project_member` class names attached for styling.
def user_link_filter(text, link_content: nil)
self.class.references_in(text) do |match, username|
- if username == 'all'
+ if username == 'all' && !skip_project_check?
link_to_all(link_content: link_content)
elsif namespace = namespaces[username]
link_to_namespace(namespace, link_content: link_content) || match
diff --git a/lib/banzai/filter/video_link_filter.rb b/lib/banzai/filter/video_link_filter.rb
index ac7bbcb0d10..b64a1287d4d 100644
--- a/lib/banzai/filter/video_link_filter.rb
+++ b/lib/banzai/filter/video_link_filter.rb
@@ -35,7 +35,8 @@ module Banzai
src: element['src'],
width: '400',
controls: true,
- 'data-setup' => '{}')
+ 'data-setup' => '{}',
+ 'data-title' => element['title'] || element['alt'])
link = doc.document.create_element(
'a',
diff --git a/lib/banzai/pipeline/gfm_pipeline.rb b/lib/banzai/pipeline/gfm_pipeline.rb
index 5a1f873496c..ac95a79009b 100644
--- a/lib/banzai/pipeline/gfm_pipeline.rb
+++ b/lib/banzai/pipeline/gfm_pipeline.rb
@@ -1,6 +1,12 @@
module Banzai
module Pipeline
class GfmPipeline < BasePipeline
+ # These filters convert GitLab Flavored Markdown (GFM) to HTML.
+ # The handlers defined in app/assets/javascripts/copy_as_gfm.js.es6
+ # consequently convert that same HTML to GFM to be copied to the clipboard.
+ # Every filter that generates HTML from GFM should have a handler in
+ # app/assets/javascripts/copy_as_gfm.js.es6, in reverse order.
+ # The GFM-to-HTML-to-GFM cycle is tested in spec/features/copy_as_gfm_spec.rb.
def self.filters
@filters ||= FilterArray[
Filter::SyntaxHighlightFilter,
diff --git a/lib/banzai/renderer.rb b/lib/banzai/renderer.rb
index f31fb6c3f71..74663556cbb 100644
--- a/lib/banzai/renderer.rb
+++ b/lib/banzai/renderer.rb
@@ -52,9 +52,9 @@ module Banzai
end
# Same as +render_field+, but without consulting or updating the cache field
- def cacheless_render_field(object, field)
+ def cacheless_render_field(object, field, options = {})
text = object.__send__(field)
- context = object.banzai_render_context(field)
+ context = object.banzai_render_context(field).merge(options)
cacheless_render(text, context)
end
diff --git a/lib/ci/api/builds.rb b/lib/ci/api/builds.rb
index c4bdef781f7..8b939663ffd 100644
--- a/lib/ci/api/builds.rb
+++ b/lib/ci/api/builds.rb
@@ -18,24 +18,31 @@ module Ci
if current_runner.is_runner_queue_value_latest?(params[:last_update])
header 'X-GitLab-Last-Update', params[:last_update]
+ Gitlab::Metrics.add_event(:build_not_found_cached)
return build_not_found!
end
new_update = current_runner.ensure_runner_queue_value
- build = Ci::RegisterBuildService.new.execute(current_runner)
+ result = Ci::RegisterBuildService.new(current_runner).execute
- if build
- Gitlab::Metrics.add_event(:build_found,
- project: build.project.path_with_namespace)
+ if result.valid?
+ if result.build
+ Gitlab::Metrics.add_event(:build_found,
+ project: result.build.project.path_with_namespace)
- present build, with: Entities::BuildDetails
- else
- Gitlab::Metrics.add_event(:build_not_found)
+ present result.build, with: Entities::BuildDetails
+ else
+ Gitlab::Metrics.add_event(:build_not_found)
- header 'X-GitLab-Last-Update', new_update
+ header 'X-GitLab-Last-Update', new_update
- build_not_found!
+ build_not_found!
+ end
+ else
+ # We received build that is invalid due to concurrency conflict
+ Gitlab::Metrics.add_event(:build_invalid)
+ conflict!
end
end
diff --git a/lib/gitlab/job_waiter.rb b/lib/gitlab/job_waiter.rb
new file mode 100644
index 00000000000..8db91d25a4b
--- /dev/null
+++ b/lib/gitlab/job_waiter.rb
@@ -0,0 +1,27 @@
+module Gitlab
+ # JobWaiter can be used to wait for a number of Sidekiq jobs to complete.
+ class JobWaiter
+ # The sleep interval between checking keys, in seconds.
+ INTERVAL = 0.1
+
+ # jobs - The job IDs to wait for.
+ def initialize(jobs)
+ @jobs = jobs
+ end
+
+ # Waits for all the jobs to be completed.
+ #
+ # timeout - The maximum amount of seconds to block the caller for. This
+ # ensures we don't indefinitely block a caller in case a job takes
+ # long to process, or is never processed.
+ def wait(timeout = 60)
+ start = Time.current
+
+ while (Time.current - start) <= timeout
+ break if SidekiqStatus.all_completed?(@jobs)
+
+ sleep(INTERVAL) # to not overload Redis too much.
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/sidekiq_status.rb b/lib/gitlab/sidekiq_status.rb
new file mode 100644
index 00000000000..aadc401ff8d
--- /dev/null
+++ b/lib/gitlab/sidekiq_status.rb
@@ -0,0 +1,66 @@
+module Gitlab
+ # The SidekiqStatus module and its child classes can be used for checking if a
+ # Sidekiq job has been processed or not.
+ #
+ # To check if a job has been completed, simply pass the job ID to the
+ # `completed?` method:
+ #
+ # job_id = SomeWorker.perform_async(...)
+ #
+ # if Gitlab::SidekiqStatus.completed?(job_id)
+ # ...
+ # end
+ #
+ # For each job ID registered a separate key is stored in Redis, making lookups
+ # much faster than using Sidekiq's built-in job finding/status API. These keys
+ # expire after a certain period of time to prevent storing too many keys in
+ # Redis.
+ module SidekiqStatus
+ STATUS_KEY = 'gitlab-sidekiq-status:%s'.freeze
+
+ # The default time (in seconds) after which a status key is expired
+ # automatically. The default of 30 minutes should be more than sufficient
+ # for most jobs.
+ DEFAULT_EXPIRATION = 30.minutes.to_i
+
+ # Starts tracking of the given job.
+ #
+ # jid - The Sidekiq job ID
+ # expire - The expiration time of the Redis key.
+ def self.set(jid, expire = DEFAULT_EXPIRATION)
+ Sidekiq.redis do |redis|
+ redis.set(key_for(jid), 1, ex: expire)
+ end
+ end
+
+ # Stops the tracking of the given job.
+ #
+ # jid - The Sidekiq job ID to remove.
+ def self.unset(jid)
+ Sidekiq.redis do |redis|
+ redis.del(key_for(jid))
+ end
+ end
+
+ # Returns true if all the given job have been completed.
+ #
+ # jids - The Sidekiq job IDs to check.
+ #
+ # Returns true or false.
+ def self.all_completed?(jids)
+ keys = jids.map { |jid| key_for(jid) }
+
+ responses = Sidekiq.redis do |redis|
+ redis.pipelined do
+ keys.each { |key| redis.exists(key) }
+ end
+ end
+
+ responses.all? { |value| !value }
+ end
+
+ def self.key_for(jid)
+ STATUS_KEY % jid
+ end
+ end
+end
diff --git a/lib/gitlab/sidekiq_status/client_middleware.rb b/lib/gitlab/sidekiq_status/client_middleware.rb
new file mode 100644
index 00000000000..779a9998b22
--- /dev/null
+++ b/lib/gitlab/sidekiq_status/client_middleware.rb
@@ -0,0 +1,10 @@
+module Gitlab
+ module SidekiqStatus
+ class ClientMiddleware
+ def call(_, job, _, _)
+ SidekiqStatus.set(job['jid'])
+ yield
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/sidekiq_status/server_middleware.rb b/lib/gitlab/sidekiq_status/server_middleware.rb
new file mode 100644
index 00000000000..31dfa46ff9d
--- /dev/null
+++ b/lib/gitlab/sidekiq_status/server_middleware.rb
@@ -0,0 +1,13 @@
+module Gitlab
+ module SidekiqStatus
+ class ServerMiddleware
+ def call(worker, job, queue)
+ ret = yield
+
+ SidekiqStatus.unset(job['jid'])
+
+ ret
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/visibility_level.rb b/lib/gitlab/visibility_level.rb
index 9462f3368e6..c7953af29dd 100644
--- a/lib/gitlab/visibility_level.rb
+++ b/lib/gitlab/visibility_level.rb
@@ -11,6 +11,7 @@ module Gitlab
included do
scope :public_only, -> { where(visibility_level: PUBLIC) }
scope :public_and_internal_only, -> { where(visibility_level: [PUBLIC, INTERNAL] ) }
+ scope :non_public_only, -> { where.not(visibility_level: PUBLIC) }
scope :public_to_user, -> (user) { user && !user.external ? public_and_internal_only : public_only }
end
diff --git a/lib/tasks/gitlab/info.rake b/lib/tasks/gitlab/info.rake
index dffea8ed155..f7c831892ee 100644
--- a/lib/tasks/gitlab/info.rake
+++ b/lib/tasks/gitlab/info.rake
@@ -11,8 +11,10 @@ namespace :gitlab do
gem_version = run_command(%W(gem --version))
# check Bundler version
bunder_version = run_and_match(%W(bundle --version), /[\d\.]+/).try(:to_s)
- # check Bundler version
+ # check Rake version
rake_version = run_and_match(%W(rake --version), /[\d\.]+/).try(:to_s)
+ # check redis version
+ redis_version = run_and_match(%W(redis-cli --version), /redis-cli (\d+\.\d+\.\d+)/).to_a
puts ""
puts "System information".color(:yellow)
@@ -24,6 +26,7 @@ namespace :gitlab do
puts "Gem Version:\t#{gem_version || "unknown".color(:red)}"
puts "Bundler Version:#{bunder_version || "unknown".color(:red)}"
puts "Rake Version:\t#{rake_version || "unknown".color(:red)}"
+ puts "Redis Version:\t#{redis_version[1] || "unknown".color(:red)}"
puts "Sidekiq Version:#{Sidekiq::VERSION}"