Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
885a1dc757
commit
ecdd26856c
|
|
@ -1 +1 @@
|
|||
144dca53fcf99bd9064cb2f6e2631f6367f0eafe
|
||||
73920c7baa9ace55ba51d555e309897fd331c1b4
|
||||
|
|
|
|||
6
Gemfile
6
Gemfile
|
|
@ -133,11 +133,11 @@ gem 'gitlab_omniauth-ldap', '~> 2.2.0', require: 'omniauth-ldap' # rubocop:todo
|
|||
gem 'net-ldap', '~> 0.17.1' # rubocop:todo Gemfile/MissingFeatureCategory
|
||||
|
||||
# API
|
||||
gem 'grape', '~> 2.0.0', feature_category: :api
|
||||
gem 'grape', '~> 1.7.1', feature_category: :api
|
||||
gem 'grape-entity', '~> 0.10.0', feature_category: :api
|
||||
gem 'grape-swagger', '~> 2.0.0', group: [:development, :test], feature_category: :api
|
||||
gem 'grape-swagger', '~> 1.6.1', group: [:development, :test], feature_category: :api
|
||||
gem 'grape-swagger-entity', '~> 0.5.1', group: [:development, :test], feature_category: :api
|
||||
gem 'grape-path-helpers', '~> 2.0.0', feature_category: :api
|
||||
gem 'grape-path-helpers', '~> 1.7.1', feature_category: :api
|
||||
gem 'rack-cors', '~> 2.0.1', require: 'rack/cors' # rubocop:todo Gemfile/MissingFeatureCategory
|
||||
|
||||
# GraphQL API
|
||||
|
|
|
|||
|
|
@ -128,7 +128,7 @@
|
|||
{"name":"doorkeeper-openid_connect","version":"1.8.7","platform":"ruby","checksum":"71edaf33118deefe25674ba3f8280c32835f057351f70e9beb222c0fd6b8e786"},
|
||||
{"name":"dotenv","version":"2.7.6","platform":"ruby","checksum":"2451ed5e8e43776d7a787e51d6f8903b98e446146c7ad143d5678cc2c409d547"},
|
||||
{"name":"dry-cli","version":"1.0.0","platform":"ruby","checksum":"28ead169f872954dd08910eb8ead59cf86cd18b4aab321e8eeefe945749569f0"},
|
||||
{"name":"dry-core","version":"1.0.1","platform":"ruby","checksum":"f32f4245e0f54e787f3708584ed8f7545aaf8dd99072e36f169312468ec5450d"},
|
||||
{"name":"dry-core","version":"1.0.0","platform":"ruby","checksum":"7a92099870967f0d2c9997950608cb8bb622dafeea20b2fe1dd49e9ba1d0f305"},
|
||||
{"name":"dry-inflector","version":"1.0.0","platform":"ruby","checksum":"6ad22361ca2d6f3f001ae3037ffcfea01163f644280d13a9195d3c3a94dd1626"},
|
||||
{"name":"dry-logic","version":"1.5.0","platform":"ruby","checksum":"99ed2180f1970c3d8247004f277a01dffbe8e82cf6680de9c7209312d86cd416"},
|
||||
{"name":"dry-types","version":"1.7.1","platform":"ruby","checksum":"12165841145a18dd22151f143707b90c8093f71e5ae06ee0f2301f5321f8cdb8"},
|
||||
|
|
@ -258,10 +258,10 @@
|
|||
{"name":"googleapis-common-protos-types","version":"1.5.0","platform":"ruby","checksum":"5769cf7376abc86ef7f5897a4aaca1d5c5a3c49ddabeddd2c251fcf8155f858b"},
|
||||
{"name":"googleauth","version":"1.3.0","platform":"ruby","checksum":"51dd7362353cf1e90a2d01e1fb94321ae3926c776d4dc4a79db65230217ffcc2"},
|
||||
{"name":"gpgme","version":"2.0.23","platform":"ruby","checksum":"c87bbafdb8719da7c58ebcac08297aa1fb227022ac6cd2972829ba68adc91c04"},
|
||||
{"name":"grape","version":"2.0.0","platform":"ruby","checksum":"3aeff94c17e84ccead4ff98833df691e7da0c108878cc128ca31f80c1047494a"},
|
||||
{"name":"grape","version":"1.7.1","platform":"ruby","checksum":"6b679d8918ee3dc19b0da95a5069dc95a71a15cf5788f5f787bb2ededf58cbb6"},
|
||||
{"name":"grape-entity","version":"0.10.0","platform":"ruby","checksum":"9aed1e7cbbc96d9e73f72e5f32c776d4ba8a5baf54c3acda2682008dba2b2cfe"},
|
||||
{"name":"grape-path-helpers","version":"2.0.1","platform":"ruby","checksum":"ad5216e52c6e796738a9118087352ab4c962900dbad1d8f8c0f96e093c6702d7"},
|
||||
{"name":"grape-swagger","version":"2.0.0","platform":"ruby","checksum":"28c1ddacc84b0e272387c87bba5d6c03db954b5680606d39aab321d5803ce011"},
|
||||
{"name":"grape-path-helpers","version":"1.7.1","platform":"ruby","checksum":"2e27271a20d4073e3a3b2b955425c7f803e198be3ba8f6e59e3d59643c5381e2"},
|
||||
{"name":"grape-swagger","version":"1.6.1","platform":"ruby","checksum":"0fd2d38476524b66e8d06de71e6c481d34286d895b12161f5df4427d66d5c69f"},
|
||||
{"name":"grape-swagger-entity","version":"0.5.1","platform":"ruby","checksum":"f51e372d00ac96cf90d948f87b3f4eb287ab053976ca57ad503d442ad8605523"},
|
||||
{"name":"grape_logging","version":"1.8.4","platform":"ruby","checksum":"efcc3e322dbd5d620a68f078733b7db043cf12680144cd03c982f14115c792d1"},
|
||||
{"name":"graphiql-rails","version":"1.8.0","platform":"ruby","checksum":"02e2c5098be2c6c29219a0e9b2910a2cd3c494301587a3199a7c4484d8038ed1"},
|
||||
|
|
|
|||
23
Gemfile.lock
23
Gemfile.lock
|
|
@ -501,7 +501,7 @@ GEM
|
|||
jwt (>= 2.5)
|
||||
dotenv (2.7.6)
|
||||
dry-cli (1.0.0)
|
||||
dry-core (1.0.1)
|
||||
dry-core (1.0.0)
|
||||
concurrent-ruby (~> 1.0)
|
||||
zeitwerk (~> 2.6)
|
||||
dry-inflector (1.0.0)
|
||||
|
|
@ -815,24 +815,23 @@ GEM
|
|||
signet (>= 0.16, < 2.a)
|
||||
gpgme (2.0.23)
|
||||
mini_portile2 (~> 2.7)
|
||||
grape (2.0.0)
|
||||
activesupport (>= 5)
|
||||
grape (1.7.1)
|
||||
activesupport
|
||||
builder
|
||||
dry-types (>= 1.1)
|
||||
mustermann-grape (~> 1.0.0)
|
||||
rack (>= 1.3.0)
|
||||
rack (>= 1.3.0, < 3)
|
||||
rack-accept
|
||||
grape-entity (0.10.0)
|
||||
activesupport (>= 3.0.0)
|
||||
multi_json (>= 1.3.2)
|
||||
grape-path-helpers (2.0.1)
|
||||
grape-path-helpers (1.7.1)
|
||||
activesupport
|
||||
grape (~> 2.0)
|
||||
grape (~> 1.3)
|
||||
rake (> 12)
|
||||
ruby2_keywords (~> 0.0.2)
|
||||
grape-swagger (2.0.0)
|
||||
grape (>= 1.7, < 3.0)
|
||||
rack-test (~> 2)
|
||||
grape-swagger (1.6.1)
|
||||
grape (~> 1.3)
|
||||
grape-swagger-entity (0.5.1)
|
||||
grape-entity (>= 0.6.0)
|
||||
grape-swagger (>= 1.2.0)
|
||||
|
|
@ -1922,10 +1921,10 @@ DEPENDENCIES
|
|||
google-cloud-storage (~> 1.45.0)
|
||||
google-protobuf (~> 3.25, >= 3.25.1)
|
||||
gpgme (~> 2.0.23)
|
||||
grape (~> 2.0.0)
|
||||
grape (~> 1.7.1)
|
||||
grape-entity (~> 0.10.0)
|
||||
grape-path-helpers (~> 2.0.0)
|
||||
grape-swagger (~> 2.0.0)
|
||||
grape-path-helpers (~> 1.7.1)
|
||||
grape-swagger (~> 1.6.1)
|
||||
grape-swagger-entity (~> 0.5.1)
|
||||
grape_logging (~> 1.8)
|
||||
graphiql-rails (~> 1.8.0)
|
||||
|
|
|
|||
|
|
@ -38,6 +38,6 @@ module ConfirmEmailWarning
|
|||
end
|
||||
|
||||
def email_to_display
|
||||
html_escape(email)
|
||||
ERB::Util.html_escape(email)
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -175,7 +175,7 @@ class SearchController < ApplicationController
|
|||
return false unless commit.present?
|
||||
|
||||
link = search_path(safe_params.merge(force_search_results: true))
|
||||
flash[:notice] = html_escape(_("You have been redirected to the only result; see the %{a_start}search results%{a_end} instead.")) % { a_start: "<a href=\"#{link}\"><u>".html_safe, a_end: '</u></a>'.html_safe }
|
||||
flash[:notice] = ERB::Util.html_escape(_("You have been redirected to the only result; see the %{a_start}search results%{a_end} instead.")) % { a_start: "<a href=\"#{link}\"><u>".html_safe, a_end: '</u></a>'.html_safe }
|
||||
redirect_to project_commit_path(@project, commit)
|
||||
|
||||
true
|
||||
|
|
|
|||
|
|
@ -2,13 +2,6 @@
|
|||
|
||||
module Ci
|
||||
module BuildsHelper
|
||||
def sidebar_build_class(build, current_build)
|
||||
build_class = []
|
||||
build_class << 'active' if build.id === current_build.id
|
||||
build_class << 'retried' if build.retried?
|
||||
build_class.join(' ')
|
||||
end
|
||||
|
||||
def build_failed_issue_options
|
||||
{
|
||||
title: _("Job Failed #%{build_id}") % { build_id: @build.id },
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ module FormHelper
|
|||
# user"), use the message as-is
|
||||
message = error.message if custom_message.include?(attribute)
|
||||
|
||||
message = html_escape_once(message).html_safe
|
||||
message = ERB::Util.html_escape_once(message).html_safe
|
||||
message = tag.span(message, class: 'str-truncated-100') if truncate.include?(attribute)
|
||||
message = append_help_page_link(message, error.options) if error.options[:help_page_url].present?
|
||||
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ module Groups::GroupMembersHelper
|
|||
end
|
||||
|
||||
def group_member_header_subtext(group)
|
||||
html_escape(_("You're viewing members of %{strong_start}%{group_name}%{strong_end}.").html_safe) % {
|
||||
ERB::Util.html_escape(_("You're viewing members of %{strong_start}%{group_name}%{strong_end}.").html_safe) % {
|
||||
group_name: group.name,
|
||||
strong_start: '<strong>'.html_safe,
|
||||
strong_end: '</strong>'.html_safe
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ module ImportHelper
|
|||
link_url = 'https://github.com/settings/tokens'
|
||||
link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: link_url }
|
||||
|
||||
html_escape(_('Create and provide your GitHub %{link_start}Personal Access Token%{link_end}. You will need to select the %{code_open}repo%{code_close} scope, so we can display a list of your public and private repositories which are available to import.')) % { link_start: link_start, link_end: '</a>'.html_safe, code_open: '<code>'.html_safe, code_close: '</code>'.html_safe }
|
||||
ERB::Util.html_escape(_('Create and provide your GitHub %{link_start}Personal Access Token%{link_end}. You will need to select the %{code_open}repo%{code_close} scope, so we can display a list of your public and private repositories which are available to import.')) % { link_start: link_start, link_end: '</a>'.html_safe, code_open: '<code>'.html_safe, code_close: '</code>'.html_safe }
|
||||
end
|
||||
|
||||
def import_configure_github_admin_message
|
||||
|
|
|
|||
|
|
@ -253,13 +253,13 @@ module MergeRequestsHelper
|
|||
end
|
||||
|
||||
branch = if merge_request.for_fork?
|
||||
html_escape(_('%{fork_icon} %{source_project_path}:%{source_branch}')) % { fork_icon: fork_icon.html_safe, source_project_path: merge_request.source_project_path, source_branch: merge_request.source_branch }
|
||||
ERB::Util.html_escape(_('%{fork_icon} %{source_project_path}:%{source_branch}')) % { fork_icon: fork_icon.html_safe, source_project_path: merge_request.source_project_path, source_branch: merge_request.source_branch }
|
||||
else
|
||||
merge_request.source_branch
|
||||
end
|
||||
|
||||
branch_title = if merge_request.for_fork?
|
||||
html_escape(_('%{source_project_path}:%{source_branch}')) % { source_project_path: merge_request.source_project_path, source_branch: merge_request.source_branch }
|
||||
ERB::Util.html_escape(_('%{source_project_path}:%{source_branch}')) % { source_project_path: merge_request.source_project_path, source_branch: merge_request.source_branch }
|
||||
else
|
||||
merge_request.source_branch
|
||||
end
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ module MirrorHelper
|
|||
docs_link_url = help_page_path('topics/git/lfs/index')
|
||||
docs_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: docs_link_url }
|
||||
|
||||
html_escape(_('Git LFS objects will be synced if LFS is %{docs_link_start}enabled for the project%{docs_link_end}. Push mirrors will %{strong_open}not%{strong_close} sync LFS objects over SSH.')) %
|
||||
ERB::Util.html_escape(_('Git LFS objects will be synced if LFS is %{docs_link_start}enabled for the project%{docs_link_end}. Push mirrors will %{strong_open}not%{strong_close} sync LFS objects over SSH.')) %
|
||||
{ docs_link_start: docs_link_start, docs_link_end: '</a>'.html_safe, strong_open: '<strong>'.html_safe, strong_close: '</strong>'.html_safe }
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ module Projects::ProjectMembersHelper
|
|||
if can?(current_user, :admin_project_member, project)
|
||||
share_project_description(project)
|
||||
else
|
||||
html_escape(_("Members can be added by project " \
|
||||
ERB::Util.html_escape(_("Members can be added by project " \
|
||||
"%{i_open}Maintainers%{i_close} or %{i_open}Owners%{i_close}")) % {
|
||||
i_open: '<i>'.html_safe, i_close: '</i>'.html_safe
|
||||
}
|
||||
|
|
@ -41,7 +41,7 @@ module Projects::ProjectMembersHelper
|
|||
_("You can invite a new member to %{project_name}.")
|
||||
end
|
||||
|
||||
html_escape(description) % { project_name: tag.strong(project.name) }
|
||||
ERB::Util.html_escape(description) % { project_name: tag.strong(project.name) }
|
||||
end
|
||||
|
||||
def project_members_serialized(project, members)
|
||||
|
|
|
|||
|
|
@ -191,7 +191,7 @@ module ProjectsHelper
|
|||
end
|
||||
|
||||
def autodeploy_flash_notice(branch_name)
|
||||
html_escape(_("Branch %{branch_name} was created. To set up auto deploy, choose a GitLab CI Yaml template and commit your changes. %{link_to_autodeploy_doc}")) %
|
||||
ERB::Util.html_escape(_("Branch %{branch_name} was created. To set up auto deploy, choose a GitLab CI Yaml template and commit your changes. %{link_to_autodeploy_doc}")) %
|
||||
{ branch_name: tag.strong(truncate(sanitize(branch_name))), link_to_autodeploy_doc: link_to_autodeploy_doc }
|
||||
end
|
||||
|
||||
|
|
@ -252,7 +252,7 @@ module ProjectsHelper
|
|||
_('Your account is authenticated with SSO or SAML. To %{push_pull_link_start}push and pull%{link_end} over %{protocol} with Git using this account, you must %{set_up_pat_link_start}set up a Personal Access Token%{link_end} to use instead of a password. For more information, see %{clone_with_https_link_start}Clone with HTTPS%{link_end}.')
|
||||
end
|
||||
|
||||
html_escape(message) % {
|
||||
ERB::Util.html_escape(message) % {
|
||||
push_pull_link_start: push_pull_link_start,
|
||||
protocol: gitlab_config.protocol.upcase,
|
||||
clone_with_https_link_start: clone_with_https_link_start,
|
||||
|
|
@ -768,7 +768,7 @@ module ProjectsHelper
|
|||
message = _("You're about to reduce the visibility of the project %{strong_start}%{project_name}%{strong_end} in %{strong_start}%{group_name}%{strong_end}.")
|
||||
end
|
||||
|
||||
html_escape(message) % { strong_start: strong_start, strong_end: strong_end, project_name: project.name, group_name: project.group ? project.group.name : nil }
|
||||
ERB::Util.html_escape(message) % { strong_start: strong_start, strong_end: strong_end, project_name: project.name, group_name: project.group ? project.group.name : nil }
|
||||
end
|
||||
|
||||
def visibility_confirm_modal_data(project, target_form_id = nil)
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ module ReminderEmailsHelper
|
|||
|
||||
body = invitation_reminder_body_text(reminder_index)
|
||||
|
||||
(format == :html ? html_escape(body) : body) % options
|
||||
(format == :html ? ERB::Util.html_escape(body) : body) % options
|
||||
end
|
||||
|
||||
def invitation_reminder_accept_link(token, format: nil)
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
module SafeFormatHelper
|
||||
# Returns a HTML-safe String.
|
||||
#
|
||||
# @param [String] format is escaped via `html_escape_once`
|
||||
# @param [Array<Hash>] args are escaped via `html_escape` if they are not marked as HTML-safe
|
||||
# @param [String] format is escaped via `ERB::Util.html_escape_once`
|
||||
# @param [Array<Hash>] args are escaped via `ERB::Util.html_escape` if they are not marked as HTML-safe
|
||||
#
|
||||
# @example
|
||||
# safe_format('See %{user_input}', user_input: '<b>bold</b>')
|
||||
|
|
|
|||
|
|
@ -136,15 +136,15 @@ module SearchHelper
|
|||
# - group
|
||||
# - group: nil, project: nil
|
||||
if project
|
||||
html_escape(_("We couldn't find any %{scope} matching %{term} in project %{project}")) % options.merge(
|
||||
ERB::Util.html_escape(_("We couldn't find any %{scope} matching %{term} in project %{project}")) % options.merge(
|
||||
project: link_to(project.full_name, project_path(project), target: '_blank', rel: 'noopener noreferrer').html_safe
|
||||
)
|
||||
elsif group
|
||||
html_escape(_("We couldn't find any %{scope} matching %{term} in group %{group}")) % options.merge(
|
||||
ERB::Util.html_escape(_("We couldn't find any %{scope} matching %{term} in group %{group}")) % options.merge(
|
||||
group: link_to(group.full_name, group_path(group), target: '_blank', rel: 'noopener noreferrer').html_safe
|
||||
)
|
||||
else
|
||||
html_escape(_("We couldn't find any %{scope} matching %{term}")) % options
|
||||
ERB::Util.html_escape(_("We couldn't find any %{scope} matching %{term}")) % options
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -326,7 +326,7 @@ module UsersHelper
|
|||
job_title = '<span itemprop="jobTitle">'.html_safe + job_title + "</span>".html_safe
|
||||
organization = '<span itemprop="worksFor">'.html_safe + organization + "</span>".html_safe
|
||||
|
||||
html_escape(s_('Profile|%{job_title} at %{organization}')) % { job_title: job_title, organization: organization }
|
||||
ERB::Util.html_escape(s_('Profile|%{job_title} at %{organization}')) % { job_title: job_title, organization: organization }
|
||||
else
|
||||
s_('Profile|%{job_title} at %{organization}') % { job_title: job_title, organization: organization }
|
||||
end
|
||||
|
|
|
|||
|
|
@ -15,6 +15,6 @@ module WikiPageVersionHelper
|
|||
name = "<strong>".html_safe + wiki_page_version.author_name + "</strong>".html_safe
|
||||
link_start = "<a href='".html_safe + wiki_page_version_author_url(wiki_page_version) + "'>".html_safe
|
||||
|
||||
html_escape(_("Last edited by %{link_start}%{avatar} %{name}%{link_end}")) % { avatar: avatar, name: name, link_start: link_start, link_end: '</a>'.html_safe }
|
||||
ERB::Util.html_escape(_("Last edited by %{link_start}%{avatar} %{name}%{link_end}")) % { avatar: avatar, name: name, link_start: link_start, link_end: '</a>'.html_safe }
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -31,10 +31,10 @@ module RestrictedSignup
|
|||
def error_message
|
||||
{
|
||||
admin: {
|
||||
allowlist: html_escape_once(_("Go to the 'Admin area > Sign-up restrictions', and check 'Allowed domains for sign-ups'.")).html_safe,
|
||||
denylist: html_escape_once(_("Go to the 'Admin area > Sign-up restrictions', and check the 'Domain denylist'.")).html_safe,
|
||||
restricted: html_escape_once(_("Go to the 'Admin area > Sign-up restrictions', and check 'Email restrictions for sign-ups'.")).html_safe,
|
||||
group_setting: html_escape_once(_("Go to the group’s 'Settings > General' page, and check 'Restrict membership by email domain'.")).html_safe
|
||||
allowlist: ERB::Util.html_escape_once(_("Go to the 'Admin area > Sign-up restrictions', and check 'Allowed domains for sign-ups'.")).html_safe,
|
||||
denylist: ERB::Util.html_escape_once(_("Go to the 'Admin area > Sign-up restrictions', and check the 'Domain denylist'.")).html_safe,
|
||||
restricted: ERB::Util.html_escape_once(_("Go to the 'Admin area > Sign-up restrictions', and check 'Email restrictions for sign-ups'.")).html_safe,
|
||||
group_setting: ERB::Util.html_escape_once(_("Go to the group’s 'Settings > General' page, and check 'Restrict membership by email domain'.")).html_safe
|
||||
},
|
||||
nonadmin: {
|
||||
allowlist: error_nonadmin,
|
||||
|
|
|
|||
|
|
@ -22,14 +22,15 @@ class BlobPresenter < Gitlab::View::Presenter::Delegated
|
|||
)
|
||||
end
|
||||
|
||||
def highlight(to: nil, plain: nil)
|
||||
def highlight(to: nil, plain: nil, used_on: :blob)
|
||||
load_all_blob_data
|
||||
|
||||
Gitlab::Highlight.highlight(
|
||||
blob.path,
|
||||
blob_data(to),
|
||||
language: blob_language,
|
||||
plain: plain
|
||||
plain: plain,
|
||||
used_on: used_on
|
||||
)
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -155,11 +155,11 @@ class BuildDetailsEntity < Ci::JobEntity
|
|||
# We do not return the invalid_dependencies for all scenarios see https://gitlab.com/gitlab-org/gitlab/-/issues/287772#note_914406387
|
||||
punctuation = invalid_dependencies.empty? ? '.' : ': '
|
||||
_("This job could not start because it could not retrieve the needed artifacts%{punctuation}%{invalid_dependencies}") %
|
||||
{ invalid_dependencies: html_escape(invalid_dependencies), punctuation: punctuation }
|
||||
{ invalid_dependencies: ERB::Util.html_escape(invalid_dependencies), punctuation: punctuation }
|
||||
end
|
||||
|
||||
def help_message(docs_url, troubleshooting_url)
|
||||
html_escape(_("Learn more about <a href=\"#{docs_url}\">dependencies</a> and <a href=\"#{troubleshooting_url}\">common causes</a> of this error.</a>".html_safe))
|
||||
ERB::Util.html_escape(_("Learn more about <a href=\"#{docs_url}\">dependencies</a> and <a href=\"#{troubleshooting_url}\">common causes</a> of this error.</a>".html_safe))
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,8 @@
|
|||
= f.label :email
|
||||
= f.email_field :email, class: "form-control gl-form-input", required: true, autocomplete: 'off', title: _('Please provide a valid email address.'), value: nil
|
||||
.form-text.gl-text-secondary
|
||||
= _('Requires your primary GitLab email address.')
|
||||
- emails_link = link_to('', profile_emails_url, target: '_blank', rel: 'noopener noreferrer')
|
||||
= safe_format(s_('Requires your primary GitLab email address. If you want to confirm a secondary email address, go to %{emails_link_start}Emails%{emails_link_end}'), tag_pair(emails_link, :emails_link_start, :emails_link_end))
|
||||
|
||||
%div
|
||||
- if recaptcha_enabled?
|
||||
|
|
|
|||
|
|
@ -6,4 +6,4 @@ introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/135451
|
|||
milestone: '16.6'
|
||||
queued_migration_version: 20231030071209
|
||||
finalize_after: '2023-12-23'
|
||||
finalized_by: # version of the migration that ensured this bbm
|
||||
finalized_by: 20231114015857
|
||||
|
|
|
|||
|
|
@ -15,4 +15,4 @@ swap:
|
|||
e\. g\.: for example
|
||||
i\.e\.: that is
|
||||
i\. e\.: that is
|
||||
via: "Use 'with', 'through', or 'by using' instead."
|
||||
via: "with', 'through', or 'by using"
|
||||
|
|
|
|||
|
|
@ -1210,10 +1210,9 @@ For more information on synchronizing users and groups between LDAP and GitLab,
|
|||
|
||||
## Move from LDAP to SAML
|
||||
|
||||
1. [Configure SAML](../../../integration/saml.md). Add `auto_link_ldap_user` to:
|
||||
1. [Add SAML configuration](../../../integration/saml.md) to:
|
||||
- [`gitlab.rb` for Linux package installations](../../../integration/saml.html?tab=Linux+package+%28Omnibus%29).
|
||||
- [`values.yml` for Helm chart installations](../../../integration/saml.html?tab=Helm+chart+%28Kubernetes%29).
|
||||
For more information, see the [initial settings for all providers](../../../integration/omniauth.md#configure-initial-settings).
|
||||
|
||||
1. Optional. [Disable the LDAP auth from the sign-in page](#disable-ldap-web-sign-in).
|
||||
|
||||
|
|
|
|||
|
|
@ -180,6 +180,8 @@ The following metrics are available:
|
|||
| `gitlab_connection_pool_size` | Gauge | 16.7 | Size of connection pool |
|
||||
| `gitlab_connection_pool_available_count` | Gauge | 16.7 | Number of available connections in the pool |
|
||||
| `gitlab_security_policies_scan_result_process_duration_seconds` | Histogram | 16.7 | The amount of time to process scan result policies |
|
||||
| `gitlab_highlight_usage` | Counter | 16.8 | The number of times `Gitlab::Highlight` is used | `used_on` |
|
||||
| `dependency_linker_usage` | Counter | 16.8 | The number of times dependency linker is used | `used_on` |
|
||||
|
||||
## Metrics controlled by a feature flag
|
||||
|
||||
|
|
|
|||
|
|
@ -554,6 +554,7 @@ Parameters:
|
|||
| `bio` | No | User's biography |
|
||||
| `can_create_group` | No | User can create top-level groups - true or false |
|
||||
| `color_scheme_id` | No | User's color scheme for the file viewer (for more information, see the [user preference documentation](../user/profile/preferences.md#change-the-syntax-highlighting-theme)) |
|
||||
| `commit_email` | No | User's commit email address |
|
||||
| `email` | Yes | Email |
|
||||
| `extern_uid` | No | External UID |
|
||||
| `external` | No | Flags the user as external - true or false (default) |
|
||||
|
|
@ -568,7 +569,9 @@ Parameters:
|
|||
| `password` | No | Password |
|
||||
| `private_profile` | No | User's profile is private - true or false. The default value is determined by [this](../administration/settings/account_and_limit_settings.md#set-profiles-of-new-users-to-private-by-default) setting. |
|
||||
| `projects_limit` | No | Number of projects user can create |
|
||||
| `pronouns` | No | User's pronouns |
|
||||
| `provider` | No | External provider name |
|
||||
| `public_email` | No | User's public email address |
|
||||
| `reset_password` | No | Send user password reset link - true or false(default) |
|
||||
| `shared_runners_minutes_limit` **(PREMIUM ALL)** | No | Can be set by administrators only. Maximum number of monthly compute minutes for this user. Can be `nil` (default; inherit system default), `0` (unlimited), or `> 0`. |
|
||||
| `skip_confirmation` | No | Skip confirmation - true or false (default) |
|
||||
|
|
|
|||
|
|
@ -322,13 +322,13 @@ The `repository_xray` report collects information about your repository for use
|
|||
|
||||
> [Moved](https://gitlab.com/groups/gitlab-org/-/epics/2098) from GitLab Ultimate to GitLab Free in 13.3.
|
||||
|
||||
The `sast` report collects [SAST vulnerabilities](../../user/application_security/sast/index.md). The collected SAST
|
||||
report uploads to GitLab as an artifact.
|
||||
The `sast` report collects [SAST vulnerabilities](../../user/application_security/sast/index.md).
|
||||
The collected SAST report uploads to GitLab as an artifact.
|
||||
|
||||
GitLab can display the results of one or more reports in:
|
||||
For more information, see:
|
||||
|
||||
- The merge request [SAST widget](../../user/application_security/sast/index.md).
|
||||
- The [security dashboard](../../user/application_security/security_dashboard/index.md).
|
||||
- [View SAST results](../../user/application_security/sast/index.md#view-sast-results)
|
||||
- [SAST output](../../user/application_security/sast/index.md#output)
|
||||
|
||||
## `artifacts:reports:secret_detection`
|
||||
|
||||
|
|
|
|||
|
|
@ -288,7 +288,7 @@ The report is a JSON document that combines vulnerabilities with possible remedi
|
|||
This documentation gives an overview of the report JSON format,
|
||||
as well as recommendations and examples to help integrators set its fields.
|
||||
The format is extensively described in the documentation of
|
||||
[SAST](../../user/application_security/sast/index.md#reports-json-format),
|
||||
[SAST](../../user/application_security/sast/index.md#output),
|
||||
[DAST](../../user/application_security/dast/proxy-based.md#reports),
|
||||
[Dependency Scanning](../../user/application_security/dependency_scanning/index.md#reports-json-format),
|
||||
and [Container Scanning](../../user/application_security/container_scanning/index.md#reports-json-format)
|
||||
|
|
|
|||
|
|
@ -87,7 +87,7 @@ and complete an integration with the Secure stage.
|
|||
- Read about [job artifacts](../../ci/jobs/job_artifacts.md).
|
||||
- Your report artifact must be in one of our currently supported formats.
|
||||
For more information, see the [documentation on reports](secure.md#report).
|
||||
- Documentation for [SAST reports](../../user/application_security/sast/index.md#reports-json-format).
|
||||
- Documentation for [SAST output](../../user/application_security/sast/index.md#output).
|
||||
- Documentation for [Dependency Scanning reports](../../user/application_security/dependency_scanning/index.md#reports-json-format).
|
||||
- Documentation for [Container Scanning reports](../../user/application_security/container_scanning/index.md#reports-json-format).
|
||||
- See this [example secure job definition that also defines the artifact created](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Jobs/Container-Scanning.gitlab-ci.yml).
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ support the following features:
|
|||
- [Scan projects](index.md#supported-languages-and-frameworks)
|
||||
- [Multi-project support](index.md#multi-project-support)
|
||||
- [Offline support](index.md#running-sast-in-an-offline-environment)
|
||||
- [Emits JSON report format](index.md#reports-json-format)
|
||||
- [Output results in JSON report format](index.md#output)
|
||||
- [SELinux support](index.md#running-sast-in-selinux)
|
||||
|
||||
## Post analyzers
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ You can disable predefined rules for any SAST analyzer.
|
|||
|
||||
When you disable a rule:
|
||||
|
||||
- Most analyzers still scan for the vulnerability. The results are removed as a processing step after the scan completes, and they don't appear in the [`gl-sast-report.json` artifact](index.md#reports-json-format).
|
||||
- Most analyzers still scan for the vulnerability. The results are removed as a processing step after the scan completes, and they don't appear in the [`gl-sast-report.json` artifact](index.md#output).
|
||||
- Findings for the disabled rule no longer appear in the [pipeline security tab](../index.md#pipeline-security-tab).
|
||||
- Existing findings for the disabled rule on the default branch are marked as [`No longer detected`](../vulnerability_report/index.md#activity-filter) in the [vulnerability report](../index.md#vulnerability-report).
|
||||
|
||||
|
|
@ -196,7 +196,7 @@ rule that you wish to modify.
|
|||
| `value` | The value of the identifier used by the predefined rule. |
|
||||
|
||||
You can look up the correct values for `type` and `value` by viewing the
|
||||
[`gl-sast-report.json`](index.md#reports-json-format) produced by the analyzer.
|
||||
[`gl-sast-report.json`](index.md#output) produced by the analyzer.
|
||||
You can download this file as a job artifact from the analyzer's CI job.
|
||||
|
||||
For example, the snippet below shows a finding from a `semgrep` rule with three
|
||||
|
|
|
|||
|
|
@ -220,7 +220,7 @@ as shown in the following table:
|
|||
| Automatically scan code with [appropriate analyzers](#supported-languages-and-frameworks) | **{check-circle}** | **{check-circle}** |
|
||||
| [Configure SAST scanners](#configuration) | **{check-circle}** | **{check-circle}** |
|
||||
| [Customize SAST settings](#available-cicd-variables) | **{check-circle}** | **{check-circle}** |
|
||||
| Download [JSON Report](#reports-json-format) | **{check-circle}** | **{check-circle}** |
|
||||
| Download [SAST output](#output) | **{check-circle}** | **{check-circle}** |
|
||||
| See new findings in merge request widget | **{dotted-circle}** | **{check-circle}** |
|
||||
| See new findings in merge request changes | **{dotted-circle}** | **{check-circle}** |
|
||||
| [Manage vulnerabilities](../vulnerabilities/index.md) | **{dotted-circle}** | **{check-circle}** |
|
||||
|
|
@ -230,13 +230,25 @@ as shown in the following table:
|
|||
| [Detect False Positives](#false-positive-detection) | **{dotted-circle}** | **{check-circle}** |
|
||||
| [Track moved vulnerabilities](#advanced-vulnerability-tracking) | **{dotted-circle}** | **{check-circle}** |
|
||||
|
||||
## Output
|
||||
|
||||
SAST outputs the file `gl-sast-report.json` as a job artifact. The file contains details of all
|
||||
detected vulnerabilities. You can
|
||||
[download](../../../ci/jobs/job_artifacts.md#download-job-artifacts) the file for processing
|
||||
outside GitLab.
|
||||
|
||||
For more information, see:
|
||||
|
||||
- [SAST report file schema](https://gitlab.com/gitlab-org/security-products/security-report-schemas/-/blob/master/dist/sast-report-format.json)
|
||||
- [Example SAST report file](https://gitlab.com/gitlab-org/security-products/analyzers/semgrep/-/blob/main/qa/expect/js/default/gl-sast-report.json)
|
||||
|
||||
## View SAST results
|
||||
|
||||
SAST results are shown in the:
|
||||
The [SAST report file](#output) is processed by GitLab and the details are shown in the UI:
|
||||
|
||||
- Merge request widget
|
||||
- Merge request changes view
|
||||
- Vulnerability Report
|
||||
- Vulnerability report
|
||||
|
||||
### Merge request widget **(ULTIMATE ALL)**
|
||||
|
||||
|
|
@ -647,21 +659,6 @@ variables:
|
|||
SAST_EXPERIMENTAL_FEATURES: "true"
|
||||
```
|
||||
|
||||
## Reports JSON format
|
||||
|
||||
SAST outputs a report file in JSON format. The report file contains details of all found vulnerabilities.
|
||||
To download the report file, you can either:
|
||||
|
||||
- Download the file from the CI/CD pipelines page.
|
||||
- In the pipelines tab on merge requests, set [`artifacts: paths`](../../../ci/yaml/index.md#artifactspaths) to `gl-sast-report.json`.
|
||||
|
||||
For information, see [Download job artifacts](../../../ci/jobs/job_artifacts.md#download-job-artifacts).
|
||||
|
||||
For details of the report file's schema, see
|
||||
[SAST report file schema](https://gitlab.com/gitlab-org/security-products/security-report-schemas/-/blob/master/dist/sast-report-format.json).
|
||||
|
||||
For an example SAST report file, see [`gl-sast-report.json`](https://gitlab.com/gitlab-org/security-products/analyzers/semgrep/-/blob/main/qa/expect/js/default/gl-sast-report.json) example.
|
||||
|
||||
## Running SAST in an offline environment
|
||||
|
||||
For self-managed GitLab instances in an environment with limited, restricted, or intermittent access
|
||||
|
|
|
|||
|
|
@ -56,17 +56,17 @@ If you operate a cloud or SaaS product and you're interested in partnering with
|
|||
|
||||
Different features are available in different [GitLab tiers](https://about.gitlab.com/pricing/).
|
||||
|
||||
| Capability | In Free & Premium | In Ultimate |
|
||||
|:---------------------------------------------------------------- |:-----------------------|:-----------------------|
|
||||
| [Configure Secret Detection scanner](#enable-secret-detection) | **{check-circle}** Yes | **{check-circle}** Yes |
|
||||
| [Customize Secret Detection settings](#configure-scan-settings) | **{check-circle}** Yes | **{check-circle}** Yes |
|
||||
| Download [JSON Report](../sast/index.md#reports-json-format) | **{check-circle}** Yes | **{check-circle}** Yes |
|
||||
| Capability | In Free & Premium | In Ultimate |
|
||||
|:-----------------------------------------------------------------------------------------------------|:-----------------------|:-----------------------|
|
||||
| [Configure Secret Detection scanner](#enable-secret-detection) | **{check-circle}** Yes | **{check-circle}** Yes |
|
||||
| [Customize Secret Detection settings](#configure-scan-settings) | **{check-circle}** Yes | **{check-circle}** Yes |
|
||||
| Download [SAST output](../sast/index.md#output) | **{check-circle}** Yes | **{check-circle}** Yes |
|
||||
| [Check text for potential secrets](#warnings-for-potential-leaks-in-text-content) before it's posted | **{check-circle}** Yes | **{check-circle}** Yes |
|
||||
| See new findings in the merge request widget | **{dotted-circle}** No | **{check-circle}** Yes |
|
||||
| View identified secrets in the pipelines' **Security** tab | **{dotted-circle}** No | **{check-circle}** Yes |
|
||||
| [Manage vulnerabilities](../vulnerability_report/index.md) | **{dotted-circle}** No | **{check-circle}** Yes |
|
||||
| [Access the Security Dashboard](../security_dashboard/index.md) | **{dotted-circle}** No | **{check-circle}** Yes |
|
||||
| [Customize Secret Detection rulesets](#custom-rulesets) | **{dotted-circle}** No | **{check-circle}** Yes |
|
||||
| See new findings in the merge request widget | **{dotted-circle}** No | **{check-circle}** Yes |
|
||||
| View identified secrets in the pipelines' **Security** tab | **{dotted-circle}** No | **{check-circle}** Yes |
|
||||
| [Manage vulnerabilities](../vulnerability_report/index.md) | **{dotted-circle}** No | **{check-circle}** Yes |
|
||||
| [Access the Security Dashboard](../security_dashboard/index.md) | **{dotted-circle}** No | **{check-circle}** Yes |
|
||||
| [Customize Secret Detection rulesets](#custom-rulesets) | **{dotted-circle}** No | **{check-circle}** Yes |
|
||||
|
||||
## Coverage
|
||||
|
||||
|
|
|
|||
|
|
@ -54,3 +54,7 @@ xray:
|
|||
- The added rules restrict the job to the default branch only. Restricting the job this way ensures development changes do not impact the baseline X-Ray data used for production code suggestions.
|
||||
|
||||
After the initial x-ray job completes and uploads the repository analysis reports, no further action is required. Repository X-Ray automatically enriches all code generation requests from that point forward.
|
||||
|
||||
The X-Ray data for your project updates each time a CI/CD pipeline containing the `xray`
|
||||
job is run. To learn more about pipeline configuration and triggers, see the
|
||||
[pipelines documentation](../../../../ci/pipelines/merge_request_pipelines.md).
|
||||
|
|
|
|||
|
|
@ -22,11 +22,19 @@ module Gitlab
|
|||
LINKERS.find { |linker| linker.support?(blob_name) }
|
||||
end
|
||||
|
||||
def self.link(blob_name, plain_text, highlighted_text)
|
||||
def self.link(blob_name, plain_text, highlighted_text, used_on: :blob)
|
||||
linker = linker(blob_name)
|
||||
return highlighted_text unless linker
|
||||
|
||||
usage_counter.increment(used_on: used_on)
|
||||
linker.link(plain_text, highlighted_text)
|
||||
end
|
||||
|
||||
def self.usage_counter
|
||||
Gitlab::Metrics.counter(
|
||||
:dependency_linker_usage,
|
||||
'The number of times dependency linker is used'
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -90,7 +90,8 @@ module Gitlab
|
|||
rich_line = syntax_highlighter(diff_line).highlight(
|
||||
diff_line.text(prefix: false),
|
||||
plain: plain,
|
||||
context: { line_number: diff_line.line }
|
||||
context: { line_number: diff_line.line },
|
||||
used_on: :diff
|
||||
)
|
||||
|
||||
# Only update text if line is found. This will prevent
|
||||
|
|
@ -143,7 +144,7 @@ module Gitlab
|
|||
|
||||
blob.load_all_data!
|
||||
|
||||
blob.present.highlight.lines
|
||||
blob.present.highlight(used_on: :diff).lines
|
||||
end
|
||||
|
||||
def blobs_too_large?
|
||||
|
|
|
|||
|
|
@ -2,9 +2,9 @@
|
|||
|
||||
module Gitlab
|
||||
class Highlight
|
||||
def self.highlight(blob_name, blob_content, language: nil, plain: false, context: {})
|
||||
def self.highlight(blob_name, blob_content, language: nil, plain: false, context: {}, used_on: :blob)
|
||||
new(blob_name, blob_content, language: language)
|
||||
.highlight(blob_content, continue: false, plain: plain, context: context)
|
||||
.highlight(blob_content, continue: false, plain: plain, context: context, used_on: used_on)
|
||||
end
|
||||
|
||||
def self.too_large?(size)
|
||||
|
|
@ -18,15 +18,19 @@ module Gitlab
|
|||
@language = language
|
||||
@blob_name = blob_name
|
||||
@blob_content = blob_content
|
||||
@gitlab_highlight_usage_counter = Gitlab::Metrics.counter(
|
||||
:gitlab_highlight_usage,
|
||||
'The number of times Gitlab::Highlight is used'
|
||||
)
|
||||
end
|
||||
|
||||
def highlight(text, continue: false, plain: false, context: {})
|
||||
def highlight(text, continue: false, plain: false, context: {}, used_on: :blob)
|
||||
@context = context
|
||||
|
||||
plain ||= self.class.too_large?(text.length)
|
||||
|
||||
highlighted_text = highlight_text(text, continue: continue, plain: plain)
|
||||
highlighted_text = link_dependencies(text, highlighted_text) if blob_name
|
||||
highlighted_text = highlight_text(text, continue: continue, plain: plain, used_on: used_on)
|
||||
highlighted_text = link_dependencies(text, highlighted_text, used_on: used_on) if blob_name
|
||||
highlighted_text
|
||||
end
|
||||
|
||||
|
|
@ -54,7 +58,9 @@ module Gitlab
|
|||
Rouge::Lexer.find_fancy(@language)
|
||||
end
|
||||
|
||||
def highlight_text(text, continue: true, plain: false)
|
||||
def highlight_text(text, continue: true, plain: false, used_on: :blob)
|
||||
@gitlab_highlight_usage_counter.increment(used_on: used_on)
|
||||
|
||||
if plain
|
||||
highlight_plain(text)
|
||||
else
|
||||
|
|
@ -77,8 +83,8 @@ module Gitlab
|
|||
highlight_plain(text)
|
||||
end
|
||||
|
||||
def link_dependencies(text, highlighted_text)
|
||||
Gitlab::DependencyLinker.link(blob_name, text, highlighted_text)
|
||||
def link_dependencies(text, highlighted_text, used_on: :blob)
|
||||
Gitlab::DependencyLinker.link(blob_name, text, highlighted_text, used_on: used_on)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -41079,7 +41079,7 @@ msgstr ""
|
|||
msgid "Requires you to deploy or set up cloud-hosted Sentry."
|
||||
msgstr ""
|
||||
|
||||
msgid "Requires your primary GitLab email address."
|
||||
msgid "Requires your primary GitLab email address. If you want to confirm a secondary email address, go to %{emails_link_start}Emails%{emails_link_end}"
|
||||
msgstr ""
|
||||
|
||||
msgid "Resend"
|
||||
|
|
|
|||
|
|
@ -3,28 +3,6 @@
|
|||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Ci::BuildsHelper, feature_category: :continuous_integration do
|
||||
describe '#sidebar_build_class' do
|
||||
using RSpec::Parameterized::TableSyntax
|
||||
|
||||
where(:build_id, :current_build_id, :retried, :expected_result) do
|
||||
1 | 1 | true | 'active retried'
|
||||
1 | 1 | false | 'active'
|
||||
1 | 2 | false | ''
|
||||
1 | 2 | true | 'retried'
|
||||
end
|
||||
|
||||
let(:build) { instance_double(Ci::Build, retried?: retried, id: build_id) }
|
||||
let(:current_build) { instance_double(Ci::Build, retried?: true, id: current_build_id ) }
|
||||
|
||||
subject { helper.sidebar_build_class(build, current_build) }
|
||||
|
||||
with_them do
|
||||
it 'builds sidebar html class' do
|
||||
expect(subject).to eq(expected_result)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#build_failed_issue_options' do
|
||||
subject { helper.build_failed_issue_options }
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'fast_spec_helper'
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Gitlab::DependencyLinker do
|
||||
describe '.link' do
|
||||
|
|
@ -107,5 +107,16 @@ RSpec.describe Gitlab::DependencyLinker do
|
|||
|
||||
described_class.link(blob_name, nil, nil)
|
||||
end
|
||||
|
||||
it 'increments usage counter based on specified used_on', :prometheus do
|
||||
allow(described_class::GemfileLinker).to receive(:link)
|
||||
|
||||
described_class.link('Gemfile', nil, nil, used_on: :diff)
|
||||
|
||||
dependency_linker_usage_counter = Gitlab::Metrics.registry.get(:dependency_linker_usage)
|
||||
|
||||
expect(dependency_linker_usage_counter.get(used_on: :diff)).to eq(1)
|
||||
expect(dependency_linker_usage_counter.get(used_on: :blob)).to eq(0)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -25,119 +25,131 @@ RSpec.describe Gitlab::Diff::Highlight, feature_category: :source_code_managemen
|
|||
end
|
||||
|
||||
describe '#highlight' do
|
||||
context "with a diff file" do
|
||||
let(:subject) { described_class.new(diff_file, repository: project.repository).highlight }
|
||||
shared_examples_for 'diff highlighter' do
|
||||
context "with a diff file" do
|
||||
let(:subject) { described_class.new(diff_file, repository: project.repository).highlight }
|
||||
|
||||
it 'returns Gitlab::Diff::Line elements' do
|
||||
expect(subject.first).to be_an_instance_of(Gitlab::Diff::Line)
|
||||
it 'returns Gitlab::Diff::Line elements' do
|
||||
expect(subject.first).to be_an_instance_of(Gitlab::Diff::Line)
|
||||
end
|
||||
|
||||
it 'does not modify "match" lines' do
|
||||
expect(subject[0].text).to eq('@@ -6,12 +6,18 @@ module Popen')
|
||||
expect(subject[22].text).to eq('@@ -19,6 +25,7 @@ module Popen')
|
||||
end
|
||||
|
||||
it 'highlights and marks unchanged lines' do
|
||||
code = %{ <span id="LC7" class="line" lang="ruby"> <span class="k">def</span> <span class="nf">popen</span><span class="p">(</span><span class="n">cmd</span><span class="p">,</span> <span class="n">path</span><span class="o">=</span><span class="kp">nil</span><span class="p">)</span></span>\n}
|
||||
|
||||
expect(subject[2].rich_text).to eq(code)
|
||||
end
|
||||
|
||||
it 'highlights and marks removed lines' do
|
||||
code = %(-<span id="LC9" class="line" lang="ruby"> <span class="k">raise</span> <span class="s2">"System commands must be given as an array of strings"</span></span>\n)
|
||||
|
||||
expect(subject[4].rich_text).to eq(code)
|
||||
end
|
||||
|
||||
it 'highlights and marks added lines' do
|
||||
code = %(+<span id="LC9" class="line" lang="ruby"> <span class="k">raise</span> <span class="no"><span class="idiff left addition">RuntimeError</span></span><span class="p"><span class="idiff addition">,</span></span><span class="idiff right addition"> </span><span class="s2">"System commands must be given as an array of strings"</span></span>\n)
|
||||
|
||||
expect(subject[5].rich_text).to eq(code)
|
||||
end
|
||||
|
||||
context 'when no diff_refs' do
|
||||
before do
|
||||
allow(diff_file).to receive(:diff_refs).and_return(nil)
|
||||
end
|
||||
|
||||
context 'when no inline diffs' do
|
||||
it_behaves_like 'without inline diffs'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
it 'does not modify "match" lines' do
|
||||
expect(subject[0].text).to eq('@@ -6,12 +6,18 @@ module Popen')
|
||||
expect(subject[22].text).to eq('@@ -19,6 +25,7 @@ module Popen')
|
||||
end
|
||||
context "with diff lines" do
|
||||
let(:subject) { described_class.new(diff_file.diff_lines, repository: project.repository).highlight }
|
||||
|
||||
it 'highlights and marks unchanged lines' do
|
||||
code = %{ <span id="LC7" class="line" lang="ruby"> <span class="k">def</span> <span class="nf">popen</span><span class="p">(</span><span class="n">cmd</span><span class="p">,</span> <span class="n">path</span><span class="o">=</span><span class="kp">nil</span><span class="p">)</span></span>\n}
|
||||
it 'returns Gitlab::Diff::Line elements' do
|
||||
expect(subject.first).to be_an_instance_of(Gitlab::Diff::Line)
|
||||
end
|
||||
|
||||
expect(subject[2].rich_text).to eq(code)
|
||||
end
|
||||
it 'does not modify "match" lines' do
|
||||
expect(subject[0].text).to eq('@@ -6,12 +6,18 @@ module Popen')
|
||||
expect(subject[22].text).to eq('@@ -19,6 +25,7 @@ module Popen')
|
||||
end
|
||||
|
||||
it 'highlights and marks removed lines' do
|
||||
code = %(-<span id="LC9" class="line" lang="ruby"> <span class="k">raise</span> <span class="s2">"System commands must be given as an array of strings"</span></span>\n)
|
||||
it 'marks unchanged lines' do
|
||||
code = %q{ def popen(cmd, path=nil)}
|
||||
|
||||
expect(subject[4].rich_text).to eq(code)
|
||||
end
|
||||
expect(subject[2].text).to eq(code)
|
||||
expect(subject[2].text).not_to be_html_safe
|
||||
end
|
||||
|
||||
it 'highlights and marks added lines' do
|
||||
code = %(+<span id="LC9" class="line" lang="ruby"> <span class="k">raise</span> <span class="no"><span class="idiff left addition">RuntimeError</span></span><span class="p"><span class="idiff addition">,</span></span><span class="idiff right addition"> </span><span class="s2">"System commands must be given as an array of strings"</span></span>\n)
|
||||
it 'marks removed lines' do
|
||||
code = %q(- raise "System commands must be given as an array of strings")
|
||||
|
||||
expect(subject[5].rich_text).to eq(code)
|
||||
end
|
||||
expect(subject[4].text).to eq(code)
|
||||
expect(subject[4].text).not_to be_html_safe
|
||||
end
|
||||
|
||||
context 'when no diff_refs' do
|
||||
before do
|
||||
allow(diff_file).to receive(:diff_refs).and_return(nil)
|
||||
it 'marks added lines' do
|
||||
code = %q(+ raise <span class="idiff left right addition">RuntimeError, </span>"System commands must be given as an array of strings")
|
||||
|
||||
expect(subject[5].rich_text).to eq(code)
|
||||
expect(subject[5].rich_text).to be_html_safe
|
||||
end
|
||||
|
||||
context 'when the inline diff marker has an invalid range' do
|
||||
before do
|
||||
allow_any_instance_of(Gitlab::Diff::InlineDiffMarker).to receive(:mark).and_raise(RangeError)
|
||||
end
|
||||
|
||||
it 'keeps the original rich line' do
|
||||
allow(Gitlab::ErrorTracking).to receive(:track_and_raise_for_dev_exception)
|
||||
|
||||
code = %q(+ raise RuntimeError, "System commands must be given as an array of strings")
|
||||
|
||||
expect(subject[5].text).to eq(code)
|
||||
expect(subject[5].text).not_to be_html_safe
|
||||
end
|
||||
|
||||
it 'reports to Sentry if configured' do
|
||||
expect(Gitlab::ErrorTracking).to receive(:track_and_raise_for_dev_exception).and_call_original
|
||||
|
||||
expect { subject }.to raise_exception(RangeError)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when no inline diffs' do
|
||||
it_behaves_like 'without inline diffs'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "with diff lines" do
|
||||
let(:subject) { described_class.new(diff_file.diff_lines, repository: project.repository).highlight }
|
||||
context 'when blob is too large' do
|
||||
let(:subject) { described_class.new(diff_file, repository: project.repository).highlight }
|
||||
|
||||
it 'returns Gitlab::Diff::Line elements' do
|
||||
expect(subject.first).to be_an_instance_of(Gitlab::Diff::Line)
|
||||
end
|
||||
|
||||
it 'does not modify "match" lines' do
|
||||
expect(subject[0].text).to eq('@@ -6,12 +6,18 @@ module Popen')
|
||||
expect(subject[22].text).to eq('@@ -19,6 +25,7 @@ module Popen')
|
||||
end
|
||||
|
||||
it 'marks unchanged lines' do
|
||||
code = %q{ def popen(cmd, path=nil)}
|
||||
|
||||
expect(subject[2].text).to eq(code)
|
||||
expect(subject[2].text).not_to be_html_safe
|
||||
end
|
||||
|
||||
it 'marks removed lines' do
|
||||
code = %q(- raise "System commands must be given as an array of strings")
|
||||
|
||||
expect(subject[4].text).to eq(code)
|
||||
expect(subject[4].text).not_to be_html_safe
|
||||
end
|
||||
|
||||
it 'marks added lines' do
|
||||
code = %q(+ raise <span class="idiff left right addition">RuntimeError, </span>"System commands must be given as an array of strings")
|
||||
|
||||
expect(subject[5].rich_text).to eq(code)
|
||||
expect(subject[5].rich_text).to be_html_safe
|
||||
end
|
||||
|
||||
context 'when the inline diff marker has an invalid range' do
|
||||
before do
|
||||
allow_any_instance_of(Gitlab::Diff::InlineDiffMarker).to receive(:mark).and_raise(RangeError)
|
||||
allow(Gitlab::Highlight).to receive(:too_large?).and_return(true)
|
||||
end
|
||||
|
||||
it 'keeps the original rich line' do
|
||||
allow(Gitlab::ErrorTracking).to receive(:track_and_raise_for_dev_exception)
|
||||
it 'blobs are highlighted as plain text without loading all data' do
|
||||
expect(diff_file.blob).not_to receive(:load_all_data!)
|
||||
|
||||
code = %q(+ raise RuntimeError, "System commands must be given as an array of strings")
|
||||
|
||||
expect(subject[5].text).to eq(code)
|
||||
expect(subject[5].text).not_to be_html_safe
|
||||
expect(subject[2].rich_text).to eq(%{ <span id="LC7" class="line" lang=""> def popen(cmd, path=nil)</span>\n})
|
||||
expect(subject[2].rich_text).to be_html_safe
|
||||
end
|
||||
|
||||
it 'reports to Sentry if configured' do
|
||||
expect(Gitlab::ErrorTracking).to receive(:track_and_raise_for_dev_exception).and_call_original
|
||||
|
||||
expect { subject }.to raise_exception(RangeError)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when no inline diffs' do
|
||||
it_behaves_like 'without inline diffs'
|
||||
end
|
||||
end
|
||||
|
||||
context 'when blob is too large' do
|
||||
let(:subject) { described_class.new(diff_file, repository: project.repository).highlight }
|
||||
it_behaves_like 'diff highlighter'
|
||||
|
||||
context 'when diff_line_syntax_highlighting feature flag is disabled' do
|
||||
before do
|
||||
allow(Gitlab::Highlight).to receive(:too_large?).and_return(true)
|
||||
stub_feature_flags(diff_line_syntax_highlighting: false)
|
||||
end
|
||||
|
||||
it 'blobs are highlighted as plain text without loading all data' do
|
||||
expect(diff_file.blob).not_to receive(:load_all_data!)
|
||||
|
||||
expect(subject[2].rich_text).to eq(%{ <span id="LC7" class="line" lang=""> def popen(cmd, path=nil)</span>\n})
|
||||
expect(subject[2].rich_text).to be_html_safe
|
||||
end
|
||||
it_behaves_like 'diff highlighter'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -116,7 +116,7 @@ RSpec.describe Gitlab::Highlight do
|
|||
|
||||
it 'links dependencies via DependencyLinker' do
|
||||
expect(Gitlab::DependencyLinker).to receive(:link)
|
||||
.with('file.name', 'Contents', anything).and_call_original
|
||||
.with('file.name', 'Contents', anything, used_on: :blob).and_call_original
|
||||
|
||||
described_class.highlight('file.name', 'Contents')
|
||||
end
|
||||
|
|
@ -133,5 +133,32 @@ RSpec.describe Gitlab::Highlight do
|
|||
highlight
|
||||
end
|
||||
end
|
||||
|
||||
it 'increments usage counter', :prometheus do
|
||||
described_class.highlight(file_name, content)
|
||||
|
||||
gitlab_highlight_usage_counter = Gitlab::Metrics.registry.get(:gitlab_highlight_usage)
|
||||
|
||||
expect(gitlab_highlight_usage_counter.get(used_on: :blob)).to eq(1)
|
||||
expect(gitlab_highlight_usage_counter.get(used_on: :diff)).to eq(0)
|
||||
end
|
||||
|
||||
context 'when used_on is specified' do
|
||||
it 'increments usage counter', :prometheus do
|
||||
described_class.highlight(file_name, content, used_on: :diff)
|
||||
|
||||
gitlab_highlight_usage_counter = Gitlab::Metrics.registry.get(:gitlab_highlight_usage)
|
||||
|
||||
expect(gitlab_highlight_usage_counter.get(used_on: :diff)).to eq(1)
|
||||
expect(gitlab_highlight_usage_counter.get(used_on: :blob)).to eq(0)
|
||||
end
|
||||
|
||||
it 'links dependencies via DependencyLinker' do
|
||||
expect(Gitlab::DependencyLinker).to receive(:link)
|
||||
.with(file_name, content, anything, used_on: :diff).and_call_original
|
||||
|
||||
described_class.highlight(file_name, content, used_on: :diff)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -312,13 +312,13 @@ RSpec.describe BlobPresenter do
|
|||
let(:git_blob) { blob.__getobj__ }
|
||||
|
||||
it 'returns highlighted content' do
|
||||
expect(Gitlab::Highlight).to receive(:highlight).with('files/ruby/regex.rb', git_blob.data, plain: nil, language: 'ruby')
|
||||
expect(Gitlab::Highlight).to receive(:highlight).with('files/ruby/regex.rb', git_blob.data, plain: nil, language: 'ruby', used_on: :blob)
|
||||
|
||||
presenter.highlight
|
||||
end
|
||||
|
||||
it 'returns plain content when :plain is true' do
|
||||
expect(Gitlab::Highlight).to receive(:highlight).with('files/ruby/regex.rb', git_blob.data, plain: true, language: 'ruby')
|
||||
expect(Gitlab::Highlight).to receive(:highlight).with('files/ruby/regex.rb', git_blob.data, plain: true, language: 'ruby', used_on: :blob)
|
||||
|
||||
presenter.highlight(plain: true)
|
||||
end
|
||||
|
|
@ -331,7 +331,7 @@ RSpec.describe BlobPresenter do
|
|||
end
|
||||
|
||||
it 'returns limited highlighted content' do
|
||||
expect(Gitlab::Highlight).to receive(:highlight).with('files/ruby/regex.rb', "line one\n", plain: nil, language: 'ruby')
|
||||
expect(Gitlab::Highlight).to receive(:highlight).with('files/ruby/regex.rb', "line one\n", plain: nil, language: 'ruby', used_on: :blob)
|
||||
|
||||
presenter.highlight(to: 1)
|
||||
end
|
||||
|
|
@ -343,11 +343,19 @@ RSpec.describe BlobPresenter do
|
|||
end
|
||||
|
||||
it 'passes language to inner call' do
|
||||
expect(Gitlab::Highlight).to receive(:highlight).with('files/ruby/regex.rb', git_blob.data, plain: nil, language: 'ruby')
|
||||
expect(Gitlab::Highlight).to receive(:highlight).with('files/ruby/regex.rb', git_blob.data, plain: nil, language: 'ruby', used_on: :blob)
|
||||
|
||||
presenter.highlight
|
||||
end
|
||||
end
|
||||
|
||||
context 'when used_on param is present' do
|
||||
it 'returns highlighted content' do
|
||||
expect(Gitlab::Highlight).to receive(:highlight).with('files/ruby/regex.rb', git_blob.data, plain: nil, language: 'ruby', used_on: :diff)
|
||||
|
||||
presenter.highlight(used_on: :diff)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#highlight_and_trim' do
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ RSpec.describe Blobs::NotebookPresenter do
|
|||
subject(:presenter) { described_class.new(blob, current_user: user) }
|
||||
|
||||
it 'highlight receives markdown' do
|
||||
expect(Gitlab::Highlight).to receive(:highlight).with('files/ruby/regex.rb', git_blob.data, plain: nil, language: 'md')
|
||||
expect(Gitlab::Highlight).to receive(:highlight).with('files/ruby/regex.rb', git_blob.data, plain: nil, language: 'md', used_on: :blob)
|
||||
|
||||
presenter.highlight
|
||||
end
|
||||
|
|
|
|||
Loading…
Reference in New Issue