Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
3e0178f80c
commit
b8ff7c8f92
|
|
@ -289,7 +289,7 @@ export default {
|
|||
</div>
|
||||
</fieldset>
|
||||
<template v-else>
|
||||
<p class="gl-m-0 gl-py-1">
|
||||
<p class="gl-m-0 gl-pb-1">
|
||||
{{ $options.i18n.startDate }}:
|
||||
<span data-testid="start-date-value" :class="{ 'gl-text-secondary': !startDate }">
|
||||
{{ startDateValue }}
|
||||
|
|
|
|||
|
|
@ -260,18 +260,19 @@ export default {
|
|||
</span>
|
||||
</template>
|
||||
<template #readonly>
|
||||
<gl-label
|
||||
v-for="label in localLabels"
|
||||
:key="label.id"
|
||||
class="gl-mr-2 gl-mb-2"
|
||||
:title="label.title"
|
||||
:description="label.description"
|
||||
:background-color="label.color"
|
||||
:scoped="scopedLabel(label)"
|
||||
:show-close-button="canUpdate"
|
||||
:target="labelFilterUrl(label)"
|
||||
@close="removeLabel(label)"
|
||||
/>
|
||||
<div class="gl-display-flex gl-gap-2 gl-flex-wrap gl-mt-1">
|
||||
<gl-label
|
||||
v-for="label in localLabels"
|
||||
:key="label.id"
|
||||
:title="label.title"
|
||||
:description="label.description"
|
||||
:background-color="label.color"
|
||||
:scoped="scopedLabel(label)"
|
||||
:show-close-button="canUpdate"
|
||||
:target="labelFilterUrl(label)"
|
||||
@close="removeLabel(label)"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
</work-item-sidebar-dropdown-widget-with-edit>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -259,7 +259,7 @@ class Milestone < ApplicationRecord
|
|||
if project
|
||||
"#{project.to_reference_base(from, full: full)}#{reference}"
|
||||
else
|
||||
reference
|
||||
"#{group.to_reference_base(from, full: full)}#{reference}"
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -1001,6 +1001,7 @@ class Project < ApplicationRecord
|
|||
def reference_pattern
|
||||
%r{
|
||||
(?<!#{Gitlab::PathRegex::PATH_START_CHAR})
|
||||
(?<absolute_path>/)?
|
||||
((?<namespace>#{Gitlab::PathRegex::FULL_NAMESPACE_FORMAT_REGEX})/)?
|
||||
(?<project>#{Gitlab::PathRegex::PROJECT_PATH_FORMAT_REGEX})
|
||||
}xo
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
---
|
||||
description: Counts Download Payload button clicks
|
||||
category: InternalEventTracking
|
||||
internal_events: true
|
||||
action: usage_data_download_payload_clicked
|
||||
identifiers:
|
||||
- user
|
||||
|
|
|
|||
|
|
@ -22,19 +22,20 @@ All event definitions are stored in the following directories:
|
|||
|
||||
Each event is defined in a separate YAML file consisting of the following fields:
|
||||
|
||||
| Field | Required | Additional information |
|
||||
|------------------------|----------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| `description` | yes | A description of the event. |
|
||||
| `category` | yes | Always InternalEventTracking (only different for legacy events). |
|
||||
| `action` | yes | A unique name for the event. Only lowercase, numbers, and underscores are allowed. Use the format `<operation>_<target_of_operation>_<where/when>`. <br/><br/> Ex: `publish_go_module_to_the_registry_from_pipeline` <br/>`<operation> = publish`<br/>`<target> = go_module`<br/>`<when/where> = to_the_registry_from_pipeline`. |
|
||||
| `identifiers` | no | A list of identifiers sent with the event. Can be set to one or more of `project`, `user`, or `namespace`. |
|
||||
| `product_section` | yes | The [section](https://gitlab.com/gitlab-com/www-gitlab-com/-/blob/master/data/sections.yml). |
|
||||
| `product_stage` | no | The [stage](https://gitlab.com/gitlab-com/www-gitlab-com/blob/master/data/stages.yml) for the event. |
|
||||
| `product_group` | yes | The [group](https://gitlab.com/gitlab-com/www-gitlab-com/blob/master/data/stages.yml) that owns the event. |
|
||||
| `milestone` | no | The milestone when the event is introduced. |
|
||||
| `introduced_by_url` | no | The URL to the merge request that introduced the event. |
|
||||
| `distributions` | yes | The [distributions](https://handbook.gitlab.com/handbook/marketing/brand-and-product-marketing/product-and-solution-marketing/tiers/#definitions) where the tracked feature is available. Can be set to one or more of `ce` or `ee`. |
|
||||
| `tiers` | yes | The [tiers](https://handbook.gitlab.com/handbook/marketing/brand-and-product-marketing/product-and-solution-marketing/tiers/) where the tracked feature is available. Can be set to one or more of `free`, `premium`, or `ultimate`. |
|
||||
| Field | Required | Additional information |
|
||||
|---------------------|----------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| `description` | yes | A description of the event. |
|
||||
| `internal_events` | no | Always `true` for events used in Internal Events. |
|
||||
| `category` | no | Required for legacy events. Should not be used for Internal Events. |
|
||||
| `action` | yes | A unique name for the event. Only lowercase, numbers, and underscores are allowed. Use the format `<operation>_<target_of_operation>_<where/when>`. <br/><br/> Ex: `publish_go_module_to_the_registry_from_pipeline` <br/>`<operation> = publish`<br/>`<target> = go_module`<br/>`<when/where> = to_the_registry_from_pipeline`. |
|
||||
| `identifiers` | no | A list of identifiers sent with the event. Can be set to one or more of `project`, `user`, or `namespace`. |
|
||||
| `product_section` | yes | The [section](https://gitlab.com/gitlab-com/www-gitlab-com/-/blob/master/data/sections.yml). |
|
||||
| `product_stage` | no | The [stage](https://gitlab.com/gitlab-com/www-gitlab-com/blob/master/data/stages.yml) for the event. |
|
||||
| `product_group` | yes | The [group](https://gitlab.com/gitlab-com/www-gitlab-com/blob/master/data/stages.yml) that owns the event. |
|
||||
| `milestone` | no | The milestone when the event is introduced. |
|
||||
| `introduced_by_url` | no | The URL to the merge request that introduced the event. |
|
||||
| `distributions` | yes | The [distributions](https://handbook.gitlab.com/handbook/marketing/brand-and-product-marketing/product-and-solution-marketing/tiers/#definitions) where the tracked feature is available. Can be set to one or more of `ce` or `ee`. |
|
||||
| `tiers` | yes | The [tiers](https://handbook.gitlab.com/handbook/marketing/brand-and-product-marketing/product-and-solution-marketing/tiers/) where the tracked feature is available. Can be set to one or more of `free`, `premium`, or `ultimate`. |
|
||||
|
||||
### Example event definition
|
||||
|
||||
|
|
@ -42,7 +43,7 @@ This is an example YAML file for an internal event:
|
|||
|
||||
```yaml
|
||||
description: A user visited a product analytics dashboard
|
||||
category: InternalEventTracking
|
||||
internal_events: true
|
||||
action: visit_product_analytics_dashboard
|
||||
identifiers:
|
||||
- project
|
||||
|
|
|
|||
|
|
@ -712,9 +712,9 @@ GitLab Flavored Markdown recognizes the following:
|
|||
| Label by name (one word) | `~bug` | `namespace/project~bug` | `project~bug` |
|
||||
| Label by name (multiple words) | `~"feature request"` | `namespace/project~"feature request"` | `project~"feature request"` |
|
||||
| Label by name (scoped) | `~"priority::high"` | `namespace/project~"priority::high"` | `project~"priority::high"` |
|
||||
| Project milestone by ID | `%123` | `namespace/project%123` | `project%123` |
|
||||
| Milestone by name (one word) | `%v1.23` | `namespace/project%v1.23` | `project%v1.23` |
|
||||
| Milestone by name (multiple words) | `%"release candidate"` | `namespace/project%"release candidate"` | `project%"release candidate"` |
|
||||
| Project milestone by ID <sup>2</sup> | `%123` | `namespace/project%123` | `project%123` |
|
||||
| Milestone by name (one word) <sup>2</sup> | `%v1.23` | `namespace/project%v1.23` | `project%v1.23` |
|
||||
| Milestone by name (multiple words) <sup>2</sup> | `%"release candidate"` | `namespace/project%"release candidate"` | `project%"release candidate"` |
|
||||
| Commit (specific) | `9ba12248` | `namespace/project@9ba12248` | `project@9ba12248` |
|
||||
| Commit range comparison | `9ba12248...b19a04f5` | `namespace/project@9ba12248...b19a04f5` | `project@9ba12248...b19a04f5` |
|
||||
| Repository file reference | `[README](doc/README.md)` | | |
|
||||
|
|
@ -722,14 +722,14 @@ GitLab Flavored Markdown recognizes the following:
|
|||
| [Alert](../operations/incident_management/alerts.md) | `^alert#123` | `namespace/project^alert#123` | `project^alert#123` |
|
||||
| [Contact](crm/index.md#contacts) | `[contact:test@example.com]` | | |
|
||||
|
||||
<ol>
|
||||
<li>
|
||||
<small>
|
||||
<a href="https://gitlab.com/gitlab-org/gitlab/-/issues/384885">Introduced</a> in GitLab 16.9. Iteration cadence references are always rendered following the format <code>[cadence:<ID>]</code>.
|
||||
For example, the text reference <code>[cadence:"plan"]</code> renders as <code>[cadence:1]</code> if the referenced iterations cadence's ID is <code>1</code>.
|
||||
</small>
|
||||
</li>
|
||||
</ol>
|
||||
**Footnotes:**
|
||||
|
||||
1. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/384885) in GitLab 16.9.
|
||||
Iteration cadence references are always rendered following the format `[cadence:<ID>]`.
|
||||
For example, the text reference `[cadence:"plan"]` renders as `[cadence:1]` if the referenced
|
||||
iterations cadence's ID is `1`.
|
||||
1. For milestones, prepend a `/` before `namespace/project` to specify the exact milestone,
|
||||
removing any possible ambiguity.
|
||||
|
||||
For example, referencing an issue by using `#123` formats the output as a link
|
||||
to issue number 123 with text `#123`. Likewise, a link to issue number 123 is
|
||||
|
|
|
|||
|
|
@ -17,6 +17,13 @@ module Gitlab
|
|||
# @attr [Float] duration
|
||||
Result = Struct.new(:stdout, :stderr, :status, :duration, keyword_init: true)
|
||||
|
||||
# Result data structure from running a command in single pipeline mode
|
||||
#
|
||||
# @attr [String] stderr
|
||||
# @attr [Process::Status] status
|
||||
# @attr [Float] duration
|
||||
SinglePipelineResult = Struct.new(:stderr, :status, :duration, keyword_init: true)
|
||||
|
||||
# @example Usage
|
||||
# Shell.new('echo', 'Some amazing output').capture
|
||||
# @param [Array<String>] cmd_args
|
||||
|
|
@ -36,6 +43,33 @@ module Gitlab
|
|||
|
||||
Result.new(stdout: stdout, stderr: stderr, status: status, duration: duration)
|
||||
end
|
||||
|
||||
# Run single command in pipeline mode with optional input or output redirection
|
||||
#
|
||||
# @param [IO|String|Array] input stdin redirection
|
||||
# @param [IO|String|Array] output stdout redirection
|
||||
# @return [Command::SinglePipelineResult]
|
||||
def run_single_pipeline!(input: nil, output: nil)
|
||||
start = Time.now
|
||||
# Open3 writes on `err_write` and we receive from `err_read`
|
||||
err_read, err_write = IO.pipe
|
||||
|
||||
# Pipeline accepts custom {Process.spawn} options
|
||||
# stderr capture is always performed, stdin and stdout redirection
|
||||
# are performed only when either `input` or `output` are present
|
||||
options = { err: err_write } # redirect stderr to IO pipe
|
||||
options[:in] = input if input # redirect stdin
|
||||
options[:out] = output if output # redirect stdout
|
||||
|
||||
status_list = Open3.pipeline(cmd_args, **options)
|
||||
duration = Time.now - start
|
||||
|
||||
err_write.close # close the pipe before reading
|
||||
stderr = err_read.read
|
||||
err_read.close # close after reading to avoid leaking file descriptors
|
||||
|
||||
SinglePipelineResult.new(stderr: stderr, status: status_list[0], duration: duration)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
---
|
||||
description: <%= args.last %>
|
||||
category: InternalEventTracking
|
||||
internal_events: true
|
||||
action: <%= event %>
|
||||
label_description:
|
||||
property_description:
|
||||
|
|
|
|||
|
|
@ -725,7 +725,7 @@ module API
|
|||
Gitlab::AppLogger.warn("Redis tracking event failed for event: #{event_name}, message: #{error.message}")
|
||||
end
|
||||
|
||||
def track_event(event_name, user:, send_snowplow_event: true, namespace_id: nil, project_id: nil)
|
||||
def track_event(event_name, user:, send_snowplow_event: true, namespace_id: nil, project_id: nil, additional_properties: Gitlab::InternalEvents::DEFAULT_ADDITIONAL_PROPERTIES)
|
||||
return unless user.present?
|
||||
|
||||
namespace = Namespace.find(namespace_id) if namespace_id
|
||||
|
|
@ -734,6 +734,7 @@ module API
|
|||
Gitlab::InternalEvents.track_event(
|
||||
event_name,
|
||||
send_snowplow_event: send_snowplow_event,
|
||||
additional_properties: additional_properties,
|
||||
user: user,
|
||||
namespace: namespace,
|
||||
project: project
|
||||
|
|
|
|||
|
|
@ -104,13 +104,16 @@ module API
|
|||
event_name = params[:event]
|
||||
namespace_id = params[:namespace_id]
|
||||
project_id = params[:project_id]
|
||||
default_additional_properties = Gitlab::InternalEvents::DEFAULT_ADDITIONAL_PROPERTIES
|
||||
additional_properties = params.fetch(:additional_properties, default_additional_properties)
|
||||
|
||||
track_event(
|
||||
event_name,
|
||||
send_snowplow_event: false,
|
||||
user: current_user,
|
||||
namespace_id: namespace_id,
|
||||
project_id: project_id
|
||||
project_id: project_id,
|
||||
additional_properties: additional_properties.symbolize_keys
|
||||
)
|
||||
|
||||
status :ok
|
||||
|
|
|
|||
|
|
@ -5,6 +5,9 @@ module Backup
|
|||
FILE_NAME_SUFFIX = '_gitlab_backup.tar'
|
||||
MANIFEST_NAME = 'backup_information.yml'
|
||||
|
||||
# Use the content from stdin instead of an actual filepath (used by tar as input or output)
|
||||
USE_STDIN = '-'
|
||||
|
||||
attr_reader :progress, :remote_storage, :options
|
||||
|
||||
def initialize(progress, backup_tasks: nil)
|
||||
|
|
@ -237,10 +240,20 @@ module Backup
|
|||
Dir.chdir(backup_path) do
|
||||
# create archive
|
||||
puts_time "Creating backup archive: #{tar_file} ... ".color(:blue)
|
||||
|
||||
tar_utils = ::Gitlab::Backup::Cli::Utils::Tar.new
|
||||
tar_command = tar_utils.pack_cmd(
|
||||
archive_file: USE_STDIN,
|
||||
target_directory: backup_path,
|
||||
target: backup_contents)
|
||||
|
||||
# Set file permissions on open to prevent chmod races.
|
||||
archive_permissions = Gitlab.config.backup.archive_permissions
|
||||
tar_system_options = { out: [tar_file, 'w', archive_permissions] }
|
||||
if Kernel.system('tar', '-cf', '-', *backup_contents, tar_system_options)
|
||||
archive_file = [tar_file, 'w', archive_permissions]
|
||||
|
||||
result = tar_command.run_single_pipeline!(output: archive_file)
|
||||
|
||||
if result.status.success?
|
||||
puts_time "Creating backup archive: #{tar_file} ... ".color(:blue) + 'done'.color(:green)
|
||||
else
|
||||
puts_time "Creating archive #{tar_file} failed".color(:red)
|
||||
|
|
|
|||
|
|
@ -10,8 +10,8 @@ module Backup
|
|||
|
||||
DEFAULT_EXCLUDE = ['lost+found'].freeze
|
||||
|
||||
# Use the content from a PIPE instead of an actual filepath (used by tar as input or output)
|
||||
USE_PIPE_INSTEAD_OF_FILE = '-'
|
||||
# Use the content from stdin instead of an actual filepath (used by tar as input or output)
|
||||
USE_STDIN = '-'
|
||||
|
||||
attr_reader :excludes
|
||||
|
||||
|
|
@ -54,7 +54,7 @@ module Backup
|
|||
|
||||
archive_file = [backup_tarball, 'w', 0o600]
|
||||
tar_command = tar_utils.pack_cmd(
|
||||
archive_file: USE_PIPE_INSTEAD_OF_FILE,
|
||||
archive_file: USE_STDIN,
|
||||
target_directory: backup_files_realpath,
|
||||
target: '.',
|
||||
excludes: excludes)
|
||||
|
|
@ -64,7 +64,7 @@ module Backup
|
|||
else
|
||||
archive_file = [backup_tarball, 'w', 0o600]
|
||||
tar_command = tar_utils.pack_cmd(
|
||||
archive_file: USE_PIPE_INSTEAD_OF_FILE,
|
||||
archive_file: USE_STDIN,
|
||||
target_directory: storage_realpath,
|
||||
target: '.',
|
||||
excludes: excludes)
|
||||
|
|
@ -91,7 +91,7 @@ module Backup
|
|||
|
||||
archive_file = backup_tarball.to_s
|
||||
tar_command = tar_utils.extract_cmd(
|
||||
archive_file: USE_PIPE_INSTEAD_OF_FILE,
|
||||
archive_file: USE_STDIN,
|
||||
target_directory: storage_realpath)
|
||||
|
||||
result = shell_pipeline.new(decompress_command, tar_command).run_pipeline!(input: archive_file)
|
||||
|
|
|
|||
|
|
@ -184,7 +184,7 @@ module Banzai
|
|||
parent_path = if parent_type == :group
|
||||
reference_cache.full_group_path(namespace_ref)
|
||||
else
|
||||
reference_cache.full_project_path(namespace_ref, project_ref)
|
||||
reference_cache.full_project_path(namespace_ref, project_ref, matches)
|
||||
end
|
||||
|
||||
parent = from_ref_cached(parent_path)
|
||||
|
|
|
|||
|
|
@ -109,7 +109,7 @@ module Banzai
|
|||
parent = project || group
|
||||
|
||||
if project || full_path_ref?(matches)
|
||||
project_path = reference_cache.full_project_path(matches[:namespace], matches[:project])
|
||||
project_path = reference_cache.full_project_path(matches[:namespace], matches[:project], matches)
|
||||
parent_from_ref = from_ref_cached(project_path)
|
||||
reference = parent_from_ref.to_human_reference(parent)
|
||||
|
||||
|
|
|
|||
|
|
@ -11,17 +11,24 @@ module Banzai
|
|||
def parent_records(parent, ids)
|
||||
return Milestone.none unless valid_context?(parent)
|
||||
|
||||
milestone_iids = ids.map { |y| y[:milestone_iid] }.compact
|
||||
unless milestone_iids.empty?
|
||||
iid_relation = find_milestones(parent, true).where(iid: milestone_iids)
|
||||
relation = []
|
||||
|
||||
# We need to handle relative and absolute paths separately
|
||||
milestones_absolute_indexed = ids.group_by { |id| id[:absolute_path] }
|
||||
milestones_absolute_indexed.each do |absolute_path, fitered_ids|
|
||||
milestone_iids = fitered_ids&.pluck(:milestone_iid)&.compact
|
||||
|
||||
if milestone_iids.present?
|
||||
relation << find_milestones(parent, true, absolute_path: absolute_path).where(iid: milestone_iids)
|
||||
end
|
||||
|
||||
milestone_names = fitered_ids&.pluck(:milestone_name)&.compact
|
||||
if milestone_names.present?
|
||||
relation << find_milestones(parent, false, absolute_path: absolute_path).where(name: milestone_names)
|
||||
end
|
||||
end
|
||||
|
||||
milestone_names = ids.map { |y| y[:milestone_name] }.compact
|
||||
unless milestone_names.empty?
|
||||
milestone_relation = find_milestones(parent, false).where(name: milestone_names)
|
||||
end
|
||||
|
||||
relation = [iid_relation, milestone_relation].compact
|
||||
relation.compact!
|
||||
return Milestone.none if relation.all?(Milestone.none)
|
||||
|
||||
Milestone.from_union(relation).includes(:project, :group)
|
||||
|
|
@ -44,12 +51,14 @@ module Banzai
|
|||
# or the milestone_name, but not both. But below, we have both pieces of information.
|
||||
# But it's accounted for in `find_object`
|
||||
def parse_symbol(symbol, match_data)
|
||||
absolute_path = !!match_data&.named_captures&.fetch('absolute_path')
|
||||
|
||||
if symbol
|
||||
# when parsing links, there is no `match_data[:milestone_iid]`, but `symbol`
|
||||
# holds the iid
|
||||
{ milestone_iid: symbol.to_i, milestone_name: nil }
|
||||
{ milestone_iid: symbol.to_i, milestone_name: nil, absolute_path: absolute_path }
|
||||
else
|
||||
{ milestone_iid: match_data[:milestone_iid]&.to_i, milestone_name: match_data[:milestone_name]&.tr('"', '') }
|
||||
{ milestone_iid: match_data[:milestone_iid]&.to_i, milestone_name: match_data[:milestone_name]&.tr('"', ''), absolute_path: absolute_path }
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -97,27 +106,27 @@ module Banzai
|
|||
escape_with_placeholders(unescaped_html, milestones)
|
||||
end
|
||||
|
||||
def find_milestones(parent, find_by_iid = false)
|
||||
finder_params = milestone_finder_params(parent, find_by_iid)
|
||||
def find_milestones(parent, find_by_iid = false, absolute_path: false)
|
||||
finder_params = milestone_finder_params(parent, find_by_iid, absolute_path)
|
||||
|
||||
MilestonesFinder.new(finder_params).execute
|
||||
end
|
||||
|
||||
def milestone_finder_params(parent, find_by_iid)
|
||||
def milestone_finder_params(parent, find_by_iid, absolute_path)
|
||||
{ order: nil, state: 'all' }.tap do |params|
|
||||
params[:project_ids] = parent.id if project_context?(parent)
|
||||
|
||||
# We don't support IID lookups because IIDs can clash between
|
||||
# group/project milestones and group/subgroup milestones.
|
||||
params[:group_ids] = group_and_ancestors_ids(parent) unless find_by_iid
|
||||
params[:group_ids] = group_and_ancestors_ids(parent, absolute_path) unless find_by_iid
|
||||
end
|
||||
end
|
||||
|
||||
def group_and_ancestors_ids(parent)
|
||||
def group_and_ancestors_ids(parent, absolute_path)
|
||||
if group_context?(parent)
|
||||
parent.self_and_ancestors.select(:id)
|
||||
absolute_path ? parent.id : parent.self_and_ancestors.select(:id)
|
||||
elsif project_context?(parent)
|
||||
parent.group&.self_and_ancestors&.select(:id)
|
||||
absolute_path ? nil : parent.group&.self_and_ancestors&.select(:id)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -45,11 +45,17 @@ module Banzai
|
|||
end
|
||||
end
|
||||
|
||||
def full_project_path(namespace, project_ref)
|
||||
def full_project_path(namespace, project_ref, matches = nil)
|
||||
return current_parent_path unless project_ref
|
||||
|
||||
namespace_ref = namespace || current_project_namespace_path
|
||||
"#{namespace_ref}/#{project_ref}"
|
||||
matched_absolute_path = matches&.named_captures&.fetch('absolute_path')
|
||||
namespace ||= current_project_namespace_path unless matched_absolute_path
|
||||
|
||||
full_path = []
|
||||
full_path << '/' if matched_absolute_path
|
||||
full_path << "#{namespace}/" if namespace
|
||||
full_path << project_ref
|
||||
full_path.join
|
||||
end
|
||||
|
||||
def full_group_path(group_ref)
|
||||
|
|
@ -80,10 +86,10 @@ module Banzai
|
|||
next unless pattern
|
||||
|
||||
prepare_doc_for_scan.to_enum(:scan, pattern).each do
|
||||
parent_path = if parent_type == :project
|
||||
full_project_path($~[:namespace], $~[:project])
|
||||
else
|
||||
parent_path = if parent_type == :group
|
||||
full_group_path($~[:group])
|
||||
else
|
||||
full_project_path($~[:namespace], $~[:project], $~)
|
||||
end
|
||||
|
||||
ident = filter.identifier($~)
|
||||
|
|
@ -101,7 +107,7 @@ module Banzai
|
|||
@per_reference ||= {}
|
||||
|
||||
@per_reference[parent_type] ||= begin
|
||||
refs = references_per_parent.keys
|
||||
refs = references_per_parent.keys.compact
|
||||
parent_ref = {}
|
||||
|
||||
# if we already have a parent, no need to query it again
|
||||
|
|
@ -117,7 +123,12 @@ module Banzai
|
|||
refs -= [ref] if parent_ref[ref]
|
||||
end
|
||||
|
||||
find_for_paths(refs).index_by(&:full_path).merge(parent_ref)
|
||||
absolute_paths = refs.filter_map { |ref| ref if ref[0] == '/' }
|
||||
relative_paths = refs - absolute_paths
|
||||
|
||||
find_for_paths(relative_paths, false).index_by(&:full_path)
|
||||
.merge(find_for_paths(absolute_paths, true).index_by { |object| "/#{object.full_path}" })
|
||||
.merge(parent_ref)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -140,41 +151,60 @@ module Banzai
|
|||
end
|
||||
|
||||
# Returns projects for the given paths.
|
||||
def find_for_paths(paths)
|
||||
def find_for_paths(paths, absolute_path = false)
|
||||
return [] if paths.empty?
|
||||
|
||||
if Gitlab::SafeRequestStore.active?
|
||||
cache = refs_cache
|
||||
to_query = paths - cache.keys
|
||||
|
||||
unless to_query.empty?
|
||||
records = objects_for_paths(to_query)
|
||||
|
||||
found = []
|
||||
records.each do |record|
|
||||
ref = record.full_path
|
||||
get_or_set_cache(cache, ref) { record }
|
||||
found << ref
|
||||
end
|
||||
|
||||
not_found = to_query - found
|
||||
not_found.each do |ref|
|
||||
get_or_set_cache(cache, ref) { nil }
|
||||
end
|
||||
end
|
||||
|
||||
cache.slice(*paths).values.compact
|
||||
cached_objects_for_paths(paths, absolute_path)
|
||||
else
|
||||
objects_for_paths(paths)
|
||||
objects_for_paths(paths, absolute_path)
|
||||
end
|
||||
end
|
||||
|
||||
def objects_for_paths(paths)
|
||||
def cached_objects_for_paths(paths, absolute_path)
|
||||
cache = refs_cache
|
||||
to_query = paths - cache.keys
|
||||
|
||||
unless to_query.empty?
|
||||
records = objects_for_paths(to_query, absolute_path)
|
||||
|
||||
found = []
|
||||
records.each do |record|
|
||||
ref = absolute_path ? "/#{record.full_path}" : record.full_path
|
||||
get_or_set_cache(cache, ref) { record }
|
||||
found << ref
|
||||
end
|
||||
|
||||
not_found = to_query - found
|
||||
not_found.each do |ref|
|
||||
get_or_set_cache(cache, ref) { nil }
|
||||
end
|
||||
end
|
||||
|
||||
cache.slice(*paths).values.compact
|
||||
end
|
||||
|
||||
def objects_for_paths(paths, absolute_path)
|
||||
search_paths = absolute_path ? paths.pluck(1..-1) : paths
|
||||
|
||||
klass = parent_type.to_s.camelize.constantize
|
||||
result = klass.where_full_path_in(paths)
|
||||
result = klass.where_full_path_in(search_paths)
|
||||
return result if parent_type == :group
|
||||
return unless parent_type == :project
|
||||
|
||||
result.includes(namespace: :route)
|
||||
projects = result.includes(namespace: :route)
|
||||
.allow_cross_joins_across_databases(url: "https://gitlab.com/gitlab-org/gitlab/-/issues/420046")
|
||||
|
||||
return projects unless absolute_path
|
||||
|
||||
# If we make it to here, then we're handling absolute path(s).
|
||||
# Which means we need to also search groups as well as projects.
|
||||
# Possible future optimization might be to use Route along the lines of:
|
||||
# Routable.where_full_path_in(paths).includes(:source)
|
||||
# See `routable.rb`
|
||||
groups = Group.where_full_path_in(search_paths)
|
||||
|
||||
projects.to_a + groups.to_a
|
||||
end
|
||||
|
||||
def refs_cache
|
||||
|
|
|
|||
|
|
@ -232,6 +232,7 @@ semgrep-sast:
|
|||
- '**/*.html'
|
||||
- '**/*.scala'
|
||||
- '**/*.sc'
|
||||
- '**/*.php'
|
||||
|
||||
sobelow-sast:
|
||||
extends: .sast-analyzer
|
||||
|
|
|
|||
|
|
@ -287,6 +287,7 @@ semgrep-sast:
|
|||
- '**/*.cs'
|
||||
- '**/*.scala'
|
||||
- '**/*.sc'
|
||||
- '**/*.php'
|
||||
- if: $CI_OPEN_MERGE_REQUESTS # Don't add it to a *branch* pipeline if it's already in a merge request pipeline.
|
||||
when: never
|
||||
- if: $CI_COMMIT_BRANCH # If there's no open merge request, add it to a *branch* pipeline instead.
|
||||
|
|
@ -303,6 +304,7 @@ semgrep-sast:
|
|||
- '**/*.cs'
|
||||
- '**/*.scala'
|
||||
- '**/*.sc'
|
||||
- '**/*.php'
|
||||
|
||||
sobelow-sast:
|
||||
extends: .sast-analyzer
|
||||
|
|
|
|||
|
|
@ -12,13 +12,16 @@ module Gitlab
|
|||
property: [String],
|
||||
value: [Integer, Float]
|
||||
}.freeze
|
||||
DEFAULT_ADDITIONAL_PROPERTIES = {}.freeze
|
||||
|
||||
class << self
|
||||
include Gitlab::Tracking::Helpers
|
||||
include Gitlab::Utils::StrongMemoize
|
||||
include Gitlab::UsageDataCounters::RedisCounter
|
||||
|
||||
def track_event(event_name, category: nil, send_snowplow_event: true, additional_properties: {}, **kwargs)
|
||||
def track_event(
|
||||
event_name, category: nil, send_snowplow_event: true,
|
||||
additional_properties: DEFAULT_ADDITIONAL_PROPERTIES, **kwargs)
|
||||
raise UnknownEventError, "Unknown event: #{event_name}" unless EventDefinitions.known_event?(event_name)
|
||||
|
||||
validate_properties!(additional_properties, kwargs)
|
||||
|
|
|
|||
|
|
@ -45234,6 +45234,9 @@ msgstr ""
|
|||
msgid "SecurityOrchestration|Merge request approval policy"
|
||||
msgstr ""
|
||||
|
||||
msgid "SecurityOrchestration|Merge result policy syntax changes"
|
||||
msgstr ""
|
||||
|
||||
msgid "SecurityOrchestration|New merge request approval policy"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -45410,6 +45413,9 @@ msgstr ""
|
|||
msgid "SecurityOrchestration|Select users"
|
||||
msgstr ""
|
||||
|
||||
msgid "SecurityOrchestration|Several merge result policy criteria have been deprecated. Policies using these elements will not work after GitLab 17.0 (May 10, 2024). You must edit these policies to remove the deprecated criteria."
|
||||
msgstr ""
|
||||
|
||||
msgid "SecurityOrchestration|Severity is %{severity}."
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -45443,6 +45449,9 @@ msgstr ""
|
|||
msgid "SecurityOrchestration|Summary"
|
||||
msgstr ""
|
||||
|
||||
msgid "SecurityOrchestration|Summary of syntax changes:"
|
||||
msgstr ""
|
||||
|
||||
msgid "SecurityOrchestration|The %{oldNameStart}Scan result policy%{oldNameEnd} is now called the %{newNameStart}Merge request approval policy%{newNameEnd} to better align with its purpose."
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -45635,12 +45644,21 @@ msgstr ""
|
|||
msgid "SecurityOrchestration|have no fix available"
|
||||
msgstr ""
|
||||
|
||||
msgid "SecurityOrchestration|match_on_inclusion is replaced by %{linkStart}match_on_inclusion_license%{linkEnd}"
|
||||
msgstr ""
|
||||
|
||||
msgid "SecurityOrchestration|more than %{allowed}"
|
||||
msgstr ""
|
||||
|
||||
msgid "SecurityOrchestration|newly_deprecated is replaced by %{firstLinkStart}New::Needs Triage%{firstLinkEnd} and %{secondLinkStart}New::Dismissed%{secondLinkEnd}"
|
||||
msgstr ""
|
||||
|
||||
msgid "SecurityOrchestration|or from:"
|
||||
msgstr ""
|
||||
|
||||
msgid "SecurityOrchestration|project.networkpolicies will be removed (GraphQL API associated with the network policies)"
|
||||
msgstr ""
|
||||
|
||||
msgid "SecurityOrchestration|projects with compliance frameworks"
|
||||
msgstr ""
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
module InternalEventsCli
|
||||
NEW_EVENT_FIELDS = [
|
||||
:description,
|
||||
:internal_events,
|
||||
:category,
|
||||
:action,
|
||||
:label_description,
|
||||
|
|
@ -21,11 +22,11 @@ module InternalEventsCli
|
|||
].freeze
|
||||
|
||||
EVENT_DEFAULTS = {
|
||||
internal_events: true,
|
||||
product_section: nil,
|
||||
product_stage: nil,
|
||||
product_group: nil,
|
||||
introduced_by_url: 'TODO',
|
||||
category: 'InternalEventTracking'
|
||||
introduced_by_url: 'TODO'
|
||||
}.freeze
|
||||
|
||||
Event = Struct.new(*NEW_EVENT_FIELDS, keyword_init: true) do
|
||||
|
|
|
|||
|
|
@ -18,7 +18,9 @@ module InternalEventsCli
|
|||
|
||||
options.sort_by do |option|
|
||||
category = events.dig(option[:value], 'category')
|
||||
event_sort_param(category, option[:name])
|
||||
internal_events = events.dig(option[:value], 'internal_events')
|
||||
|
||||
event_sort_param(internal_events, category, option[:name])
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -37,23 +39,18 @@ module InternalEventsCli
|
|||
end
|
||||
|
||||
def format_event_name(event)
|
||||
case event.category
|
||||
when 'InternalEventTracking', 'default'
|
||||
if event.internal_events || event.category == 'default'
|
||||
event.action
|
||||
else
|
||||
"#{event.category}:#{event.action}"
|
||||
end
|
||||
end
|
||||
|
||||
def event_sort_param(category, name)
|
||||
case category
|
||||
when 'InternalEventTracking'
|
||||
"0#{name}"
|
||||
when 'default'
|
||||
"1#{name}"
|
||||
else
|
||||
"2#{category}#{name}"
|
||||
end
|
||||
def event_sort_param(internal_events, category, name)
|
||||
return "0#{name}" if internal_events
|
||||
return "1#{name}" if category == 'default'
|
||||
|
||||
"2#{category}#{name}"
|
||||
end
|
||||
|
||||
def get_existing_events_for_paths(event_paths)
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ module InternalEventsCli
|
|||
Find one? Create a new metric for the event.
|
||||
Otherwise? Create a new event.
|
||||
|
||||
If you find a relevant event that has a different category from 'InternalEventTracking', it can be migrated to
|
||||
If you find a relevant event that does not have the property `internal_events: true`, it can be migrated to
|
||||
Internal Events. See https://docs.gitlab.com/ee/development/internal_analytics/internal_event_instrumentation/migration.html
|
||||
|
||||
TEXT
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
---
|
||||
description: Internal Event CLI is opened
|
||||
category: InternalEventTracking
|
||||
internal_events: true
|
||||
action: internal_events_cli_opened
|
||||
product_section: analytics
|
||||
product_stage: monitor
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
---
|
||||
description: Engineer uses Internal Event CLI to define a new event
|
||||
category: InternalEventTracking
|
||||
internal_events: true
|
||||
action: internal_events_cli_used
|
||||
identifiers:
|
||||
- project
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
---
|
||||
description: random event string
|
||||
category: InternalEventTracking
|
||||
internal_events: true
|
||||
action: random_name
|
||||
identifiers:
|
||||
- project
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
---
|
||||
description: Engineer closes Internal Event CLI
|
||||
category: InternalEventTracking
|
||||
internal_events: true
|
||||
action: internal_events_cli_closed
|
||||
identifiers:
|
||||
- project
|
||||
|
|
|
|||
|
|
@ -866,6 +866,7 @@ RSpec.describe API::Helpers, feature_category: :shared do
|
|||
expect(Gitlab::InternalEvents).to receive(:track_event).with(
|
||||
event_name,
|
||||
send_snowplow_event: true,
|
||||
additional_properties: {},
|
||||
user: user,
|
||||
namespace: namespace,
|
||||
project: project
|
||||
|
|
@ -882,6 +883,7 @@ RSpec.describe API::Helpers, feature_category: :shared do
|
|||
expect(Gitlab::InternalEvents).to receive(:track_event).with(
|
||||
event_name,
|
||||
send_snowplow_event: false,
|
||||
additional_properties: {},
|
||||
user: user,
|
||||
namespace: namespace,
|
||||
project: project
|
||||
|
|
@ -895,6 +897,24 @@ RSpec.describe API::Helpers, feature_category: :shared do
|
|||
)
|
||||
end
|
||||
|
||||
it 'passes additional_properties on to InternalEvents.track_event' do
|
||||
expect(Gitlab::InternalEvents).to receive(:track_event).with(
|
||||
event_name,
|
||||
send_snowplow_event: true,
|
||||
additional_properties: { label: 'label2' },
|
||||
user: user,
|
||||
namespace: namespace,
|
||||
project: project
|
||||
)
|
||||
|
||||
helper.track_event(event_name,
|
||||
user: user,
|
||||
namespace_id: namespace.id,
|
||||
project_id: project.id,
|
||||
additional_properties: { label: 'label2' }
|
||||
)
|
||||
end
|
||||
|
||||
it 'tracks an exception and renders 422 for unknown event', :aggregate_failures do
|
||||
expect(Gitlab::InternalEvents).to receive(:track_event).and_raise(Gitlab::InternalEvents::UnknownEventError, "Unknown event: #{unknown_event}")
|
||||
|
||||
|
|
|
|||
|
|
@ -194,21 +194,10 @@ RSpec.describe Backup::Manager, feature_category: :backup_restore do
|
|||
let(:backup_id) { "1546300800_2019_01_01_#{Gitlab::VERSION}" }
|
||||
let(:full_backup_id) { backup_id }
|
||||
let(:pack_tar_file) { "#{backup_id}_gitlab_backup.tar" }
|
||||
let(:pack_tar_system_options) { { out: [pack_tar_file, 'w', Gitlab.config.backup.archive_permissions] } }
|
||||
let(:pack_tar_cmdline) { ['tar', '-cf', '-', *expected_backup_contents, pack_tar_system_options] }
|
||||
|
||||
let(:lfs) do
|
||||
Backup::Tasks::Lfs.new(progress: progress, options: options)
|
||||
.tap { |task| allow(task).to receive(:target).and_return(target1) }
|
||||
end
|
||||
let(:lfs) { Backup::Tasks::Lfs.new(progress: progress, options: options) }
|
||||
let(:pages) { Backup::Tasks::Pages.new(progress: progress, options: options) }
|
||||
|
||||
let(:pages) do
|
||||
Backup::Tasks::Pages.new(progress: progress, options: options)
|
||||
.tap { |task| allow(task).to receive(:target).and_return(target2) }
|
||||
end
|
||||
|
||||
let(:target1) { instance_double(Backup::Targets::Target) }
|
||||
let(:target2) { instance_double(Backup::Targets::Target) }
|
||||
let(:backup_tasks) do
|
||||
{ 'lfs' => lfs, 'pages' => pages }
|
||||
end
|
||||
|
|
@ -217,10 +206,6 @@ RSpec.describe Backup::Manager, feature_category: :backup_restore do
|
|||
stub_env('INCREMENTAL', incremental_env)
|
||||
allow(ApplicationRecord.connection).to receive(:reconnect!)
|
||||
allow(Gitlab::BackupLogger).to receive(:info)
|
||||
allow(Kernel).to receive(:system).and_return(true)
|
||||
|
||||
allow(target1).to receive(:dump).with(backup_path.join('lfs.tar.gz'), backup_id)
|
||||
allow(target2).to receive(:dump).with(backup_path.join('pages.tar.gz'), backup_id)
|
||||
end
|
||||
|
||||
it 'creates a backup tar' do
|
||||
|
|
@ -228,7 +213,8 @@ RSpec.describe Backup::Manager, feature_category: :backup_restore do
|
|||
subject.create # rubocop:disable Rails/SaveBang
|
||||
end
|
||||
|
||||
expect(Kernel).to have_received(:system).with(*pack_tar_cmdline)
|
||||
expect(File).to exist(backup_path.join(pack_tar_file))
|
||||
|
||||
expect(FileUtils).to have_received(:rm_rf).with(backup_path.join('backup_information.yml'))
|
||||
expect(FileUtils).to have_received(:rm_rf).with(backup_path.join('tmp'))
|
||||
end
|
||||
|
|
@ -243,15 +229,15 @@ RSpec.describe Backup::Manager, feature_category: :backup_restore do
|
|||
it 'uses the given value as tar file name' do
|
||||
subject.create # rubocop:disable Rails/SaveBang
|
||||
|
||||
expect(Kernel).to have_received(:system).with(*pack_tar_cmdline)
|
||||
expect(File).to exist(backup_path.join('custom_gitlab_backup.tar'))
|
||||
end
|
||||
|
||||
context 'tar fails' do
|
||||
before do
|
||||
expect(Kernel).to receive(:system).with(*pack_tar_cmdline).and_return(false)
|
||||
end
|
||||
|
||||
it 'logs a failure' do
|
||||
allow(Open3).to receive(:pipeline).and_return(
|
||||
[instance_double(Process::Status, success?: false, exitstatus: 1)]
|
||||
)
|
||||
|
||||
expect do
|
||||
subject.create # rubocop:disable Rails/SaveBang
|
||||
end.to raise_error(Backup::Error, 'Backup failed')
|
||||
|
|
@ -265,14 +251,13 @@ RSpec.describe Backup::Manager, feature_category: :backup_restore do
|
|||
context 'when SKIP env is set' do
|
||||
let(:expected_backup_contents) { %w[backup_information.yml lfs.tar.gz] }
|
||||
|
||||
before do
|
||||
stub_env('SKIP', 'pages')
|
||||
end
|
||||
|
||||
it 'executes tar' do
|
||||
subject.create # rubocop:disable Rails/SaveBang
|
||||
stub_env('SKIP', 'pages')
|
||||
|
||||
expect(Kernel).to have_received(:system).with(*pack_tar_cmdline)
|
||||
expect(lfs).to receive(:target).and_call_original
|
||||
expect(pages).not_to receive(:target)
|
||||
|
||||
subject.create # rubocop:disable Rails/SaveBang
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -281,16 +266,15 @@ RSpec.describe Backup::Manager, feature_category: :backup_restore do
|
|||
let(:pages) do
|
||||
Backup::Tasks::Pages.new(progress: progress, options: options)
|
||||
.tap do |task|
|
||||
allow(task).to receive_messages(target: target2, destination_optional: true)
|
||||
allow(task).to receive(:destination_optional).and_return(true)
|
||||
end
|
||||
end
|
||||
|
||||
it 'executes tar' do
|
||||
allow(pages).to receive_message_chain(:target, :dump)
|
||||
expect(File).to receive(:exist?).with(backup_path.join('pages.tar.gz')).and_return(false)
|
||||
|
||||
subject.create # rubocop:disable Rails/SaveBang
|
||||
|
||||
expect(Kernel).to have_received(:system).with(*pack_tar_cmdline)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -312,9 +296,12 @@ RSpec.describe Backup::Manager, feature_category: :backup_restore do
|
|||
|
||||
before do
|
||||
allow(Gitlab::BackupLogger).to receive(:info)
|
||||
allow(Dir).to receive(:chdir).and_yield
|
||||
allow(Dir).to receive(:glob).and_return(files)
|
||||
allow(FileUtils).to receive(:rm)
|
||||
|
||||
files.each do |bkp|
|
||||
FileUtils.touch(backup_path.join(bkp))
|
||||
end
|
||||
|
||||
allow(FileUtils).to receive(:rm).and_call_original
|
||||
allow(Time).to receive(:now).and_return(Time.zone.parse('2016-1-1'))
|
||||
end
|
||||
|
||||
|
|
@ -326,7 +313,9 @@ RSpec.describe Backup::Manager, feature_category: :backup_restore do
|
|||
end
|
||||
|
||||
it 'removes no files' do
|
||||
expect(FileUtils).not_to have_received(:rm)
|
||||
files.each do |bkp|
|
||||
expect(File).to exist(backup_path.join(bkp))
|
||||
end
|
||||
end
|
||||
|
||||
it 'prints a skipped message' do
|
||||
|
|
@ -350,7 +339,9 @@ RSpec.describe Backup::Manager, feature_category: :backup_restore do
|
|||
end
|
||||
|
||||
it 'removes no files' do
|
||||
expect(FileUtils).not_to have_received(:rm)
|
||||
files.each do |bkp|
|
||||
expect(File).to exist(backup_path.join(bkp))
|
||||
end
|
||||
end
|
||||
|
||||
it 'prints a done message' do
|
||||
|
|
@ -367,7 +358,9 @@ RSpec.describe Backup::Manager, feature_category: :backup_restore do
|
|||
end
|
||||
|
||||
it 'removes no files' do
|
||||
expect(FileUtils).not_to have_received(:rm)
|
||||
files.each do |bkp|
|
||||
expect(File).to exist(backup_path.join(bkp))
|
||||
end
|
||||
end
|
||||
|
||||
it 'prints a done message' do
|
||||
|
|
@ -643,11 +636,12 @@ RSpec.describe Backup::Manager, feature_category: :backup_restore do
|
|||
end
|
||||
|
||||
it 'creates a non-tarred backup' do
|
||||
expect(subject).not_to receive(:pack)
|
||||
|
||||
travel_to(backup_time) do
|
||||
subject.create # rubocop:disable Rails/SaveBang
|
||||
end
|
||||
|
||||
expect(Kernel).not_to have_received(:system).with(*pack_tar_cmdline)
|
||||
expect(subject.send(:backup_information).to_h).to include(
|
||||
backup_id: backup_id,
|
||||
backup_created_at: backup_time.localtime,
|
||||
|
|
@ -752,12 +746,14 @@ RSpec.describe Backup::Manager, feature_category: :backup_restore do
|
|||
end
|
||||
|
||||
it 'unpacks and packs the backup' do
|
||||
expect(subject).to receive(:unpack).and_call_original
|
||||
expect(subject).to receive(:pack).and_call_original
|
||||
|
||||
travel_to(backup_time) do
|
||||
subject.create # rubocop:disable Rails/SaveBang
|
||||
end
|
||||
|
||||
expect(Kernel).to have_received(:system).with(*unpack_tar_cmdline)
|
||||
expect(Kernel).to have_received(:system).with(*pack_tar_cmdline)
|
||||
expect(FileUtils).to have_received(:rm_rf).with(backup_path.join('backup_information.yml'))
|
||||
expect(FileUtils).to have_received(:rm_rf).with(backup_path.join('tmp'))
|
||||
end
|
||||
|
|
@ -777,11 +773,11 @@ RSpec.describe Backup::Manager, feature_category: :backup_restore do
|
|||
end
|
||||
|
||||
context 'tar fails' do
|
||||
before do
|
||||
expect(Kernel).to receive(:system).with(*pack_tar_cmdline).and_return(false)
|
||||
end
|
||||
|
||||
it 'logs a failure' do
|
||||
allow(Open3).to receive(:pipeline).and_return(
|
||||
[instance_double(Process::Status, success?: false, exitstatus: 1)]
|
||||
)
|
||||
|
||||
expect do
|
||||
subject.create # rubocop:disable Rails/SaveBang
|
||||
end.to raise_error(Backup::Error, 'Backup failed')
|
||||
|
|
@ -845,12 +841,14 @@ RSpec.describe Backup::Manager, feature_category: :backup_restore do
|
|||
end
|
||||
|
||||
it 'unpacks and packs the backup' do
|
||||
expect(subject).to receive(:unpack).and_call_original
|
||||
expect(subject).to receive(:pack).and_call_original
|
||||
|
||||
travel_to(backup_time) do
|
||||
subject.create # rubocop:disable Rails/SaveBang
|
||||
end
|
||||
|
||||
expect(Kernel).to have_received(:system).with(*unpack_tar_cmdline)
|
||||
expect(Kernel).to have_received(:system).with(*pack_tar_cmdline)
|
||||
expect(FileUtils).to have_received(:rm_rf).with(backup_path.join('backup_information.yml'))
|
||||
expect(FileUtils).to have_received(:rm_rf).with(backup_path.join('tmp'))
|
||||
end
|
||||
|
|
@ -873,7 +871,9 @@ RSpec.describe Backup::Manager, feature_category: :backup_restore do
|
|||
|
||||
context 'tar fails' do
|
||||
before do
|
||||
expect(Kernel).to receive(:system).with(*pack_tar_cmdline).and_return(false)
|
||||
allow(Open3).to receive(:pipeline).and_return(
|
||||
[instance_double(Process::Status, success?: false, exitstatus: 1)]
|
||||
)
|
||||
end
|
||||
|
||||
it 'logs a failure' do
|
||||
|
|
|
|||
|
|
@ -323,6 +323,18 @@ RSpec.describe Banzai::Filter::References::MilestoneReferenceFilter, feature_cat
|
|||
end
|
||||
end
|
||||
|
||||
shared_examples 'absolute references' do
|
||||
it 'supports absolute reference' do
|
||||
absolute_reference = "/#{reference}"
|
||||
|
||||
result = reference_filter("See #{absolute_reference}")
|
||||
|
||||
expect(result.css('a').first.attr('href')).to eq(urls.milestone_url(milestone))
|
||||
expect(result.css('a').first.attr('data-original')).to eq absolute_reference
|
||||
expect(result.content).to eq "See %#{milestone.title}"
|
||||
end
|
||||
end
|
||||
|
||||
shared_context 'project milestones' do
|
||||
let(:reference) { milestone.to_reference(format: :iid) }
|
||||
|
||||
|
|
@ -341,6 +353,10 @@ RSpec.describe Banzai::Filter::References::MilestoneReferenceFilter, feature_cat
|
|||
let(:resource) { milestone }
|
||||
let(:resource_text) { "#{resource.class.reference_prefix}#{resource.title}" }
|
||||
end
|
||||
|
||||
it_behaves_like 'absolute references' do
|
||||
let(:reference) { milestone.to_reference(format: :iid, full: true) }
|
||||
end
|
||||
end
|
||||
|
||||
shared_context 'group milestones' do
|
||||
|
|
@ -357,6 +373,10 @@ RSpec.describe Banzai::Filter::References::MilestoneReferenceFilter, feature_cat
|
|||
let(:resource_text) { "#{resource.class.reference_prefix}#{resource.title}" }
|
||||
end
|
||||
|
||||
it_behaves_like 'absolute references' do
|
||||
let(:reference) { milestone.to_reference(format: :name, full: true) }
|
||||
end
|
||||
|
||||
it 'does not support references by IID' do
|
||||
doc = reference_filter("See #{Milestone.reference_prefix}#{milestone.iid}")
|
||||
|
||||
|
|
@ -411,6 +431,10 @@ RSpec.describe Banzai::Filter::References::MilestoneReferenceFilter, feature_cat
|
|||
|
||||
expect(reference_filter(act, context).to_html).to eq exp
|
||||
end
|
||||
|
||||
it_behaves_like 'absolute references' do
|
||||
let(:reference) { "#{project.full_path}%#{milestone.iid}" }
|
||||
end
|
||||
end
|
||||
|
||||
context 'when group milestone' do
|
||||
|
|
@ -420,7 +444,7 @@ RSpec.describe Banzai::Filter::References::MilestoneReferenceFilter, feature_cat
|
|||
let(:sub_group) { create(:group, parent: group) }
|
||||
let(:sub_group_milestone) { create(:milestone, title: 'sub_group_milestone', group: sub_group) }
|
||||
|
||||
it 'links to a valid reference of subgroup and group milestones' do
|
||||
it 'links to valid references of subgroup and group milestones' do
|
||||
[group_milestone, sub_group_milestone].each do |milestone|
|
||||
reference = "%#{milestone.title}"
|
||||
|
||||
|
|
@ -429,6 +453,18 @@ RSpec.describe Banzai::Filter::References::MilestoneReferenceFilter, feature_cat
|
|||
expect(result.css('a').first.attr('href')).to eq(urls.milestone_url(milestone))
|
||||
end
|
||||
end
|
||||
|
||||
it 'links to valid absolute references of subgroup and group milestones' do
|
||||
[group_milestone, sub_group_milestone].each do |milestone|
|
||||
reference = "/#{milestone.group.full_path}%#{milestone.title}"
|
||||
|
||||
result = reference_filter("See #{reference}", { project: nil, group: sub_group })
|
||||
|
||||
expect(result.css('a').first.attr('href')).to eq(urls.milestone_url(milestone))
|
||||
expect(result.css('a').first.attr('data-original')).to eq reference
|
||||
expect(result.content).to eq "See %#{milestone.title}"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
it 'ignores internal references' do
|
||||
|
|
@ -450,6 +486,36 @@ RSpec.describe Banzai::Filter::References::MilestoneReferenceFilter, feature_cat
|
|||
expect(links[1].attr('href')).to eq(urls.milestone_url(group_milestone))
|
||||
end
|
||||
end
|
||||
|
||||
context 'when referencing both project and group milestones using absolute references' do
|
||||
let(:milestone) { create(:milestone, project: project) }
|
||||
let(:group_milestone) { create(:milestone, title: 'group_milestone', group: project.group) }
|
||||
|
||||
it 'links to valid references' do
|
||||
doc = reference_filter("See /#{milestone.to_reference(full: true)} and /#{group_milestone.to_reference(full: true)}", context)
|
||||
links = doc.css('a')
|
||||
|
||||
expect(links.length).to eq(2)
|
||||
expect(links[0].attr('href')).to eq(urls.milestone_url(milestone))
|
||||
expect(links[1].attr('href')).to eq(urls.milestone_url(group_milestone))
|
||||
end
|
||||
end
|
||||
|
||||
context 'when referencing both group and subgroup milestones using absolute references' do
|
||||
let(:subgroup) { create(:group, :public, parent: group) }
|
||||
let(:group_milestone) { create(:milestone, title: 'group_milestone', group: group) }
|
||||
let(:subgroup_milestone) { create(:milestone, title: 'group_milestone', group: subgroup) }
|
||||
let(:context) { { project: project, group: nil } }
|
||||
|
||||
it 'links to valid references' do
|
||||
doc = reference_filter("See /#{group_milestone.to_reference(full: true)} and /#{subgroup_milestone.to_reference(full: true)}", context)
|
||||
links = doc.css('a')
|
||||
|
||||
expect(links.length).to eq(2)
|
||||
expect(links[0].attr('href')).to eq(urls.milestone_url(group_milestone))
|
||||
expect(links[1].attr('href')).to eq(urls.milestone_url(subgroup_milestone))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when milestone is open' do
|
||||
|
|
|
|||
|
|
@ -3,11 +3,14 @@
|
|||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Banzai::Filter::References::ReferenceCache, feature_category: :team_planning do
|
||||
let_it_be(:project) { create(:project) }
|
||||
let_it_be(:group) { create(:group) }
|
||||
let_it_be(:subgroup) { create(:group, parent: group) }
|
||||
let_it_be(:project) { create(:project, group: group) }
|
||||
let_it_be(:project2) { create(:project) }
|
||||
let_it_be(:issue1) { create(:issue, project: project) }
|
||||
let_it_be(:issue2) { create(:issue, project: project) }
|
||||
let_it_be(:issue3) { create(:issue, project: project2) }
|
||||
let_it_be(:issue4) { create(:issue, project: project2) }
|
||||
let_it_be(:doc) { Nokogiri::HTML.fragment("#{issue1.to_reference} #{issue2.to_reference} #{issue3.to_reference(full: true)}") }
|
||||
let_it_be(:result) { {} }
|
||||
let_it_be(:filter_class) { Banzai::Filter::References::IssueReferenceFilter }
|
||||
|
|
@ -63,17 +66,49 @@ RSpec.describe Banzai::Filter::References::ReferenceCache, feature_category: :te
|
|||
|
||||
describe '#parent_per_reference' do
|
||||
it 'returns a Hash containing projects grouped per parent paths' do
|
||||
expect(cache.parent_per_reference).to match({ project.full_path => project, project2.full_path => project2 })
|
||||
expect(cache.parent_per_reference).to include({ project.full_path => project, project2.full_path => project2 })
|
||||
end
|
||||
end
|
||||
|
||||
describe '#records_per_parent' do
|
||||
it 'returns a Hash containing projects grouped per parent paths' do
|
||||
it 'returns a Hash containing records grouped per parent' do
|
||||
expect(cache.records_per_parent).to match({ project => { issue1.iid => issue1, issue2.iid => issue2 },
|
||||
project2 => { issue3.iid => issue3 } })
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the cache is loaded with absolute references' do
|
||||
it 'loads references grouped per parent path and absolute references' do
|
||||
milestone1 = create(:milestone, group: group)
|
||||
milestone2 = create(:milestone, group: subgroup)
|
||||
milestone3 = create(:milestone, project: project)
|
||||
|
||||
doc_milestone = Nokogiri::HTML.fragment("/#{milestone1.to_reference(full: true)} /#{milestone2.to_reference(full: true)} #{milestone3.to_reference(full: true)}")
|
||||
filter_milestone = Banzai::Filter::References::MilestoneReferenceFilter.new(doc_milestone, project: project)
|
||||
cache_milestone = described_class.new(filter_milestone, { project: project }, {})
|
||||
|
||||
cache_milestone.load_reference_cache(filter_milestone.nodes)
|
||||
|
||||
expect(cache_milestone.references_per_parent).to match({
|
||||
"/#{group.full_path}" => [{ milestone_iid: nil, milestone_name: milestone1.title, absolute_path: true }].to_set,
|
||||
"/#{subgroup.full_path}" => [{ milestone_iid: nil, milestone_name: milestone2.title, absolute_path: true }].to_set,
|
||||
project.full_path => [{ milestone_iid: nil, milestone_name: milestone3.title, absolute_path: false }].to_set
|
||||
})
|
||||
|
||||
expect(cache_milestone.parent_per_reference).to match({
|
||||
"/#{group.full_path}" => group,
|
||||
"/#{subgroup.full_path}" => subgroup,
|
||||
project.full_path => project
|
||||
})
|
||||
|
||||
expect(cache_milestone.records_per_parent).to match({
|
||||
group => { { milestone_iid: milestone1.iid, milestone_name: milestone1.title } => milestone1 },
|
||||
subgroup => { { milestone_iid: milestone2.iid, milestone_name: milestone2.title } => milestone2 },
|
||||
project => { { milestone_iid: milestone3.iid, milestone_name: milestone3.title } => milestone3 }
|
||||
})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#initialize_reference_cache' do
|
||||
|
|
@ -105,8 +140,8 @@ RSpec.describe Banzai::Filter::References::ReferenceCache, feature_category: :te
|
|||
end
|
||||
|
||||
describe '#find_for_paths' do
|
||||
def find_for_paths(paths)
|
||||
cache.send(:find_for_paths, paths)
|
||||
def find_for_paths(paths, absolute_path = false)
|
||||
cache.send(:find_for_paths, paths, absolute_path)
|
||||
end
|
||||
|
||||
context 'with RequestStore disabled' do
|
||||
|
|
@ -117,6 +152,14 @@ RSpec.describe Banzai::Filter::References::ReferenceCache, feature_category: :te
|
|||
it 'return an empty array for paths that do not exist' do
|
||||
expect(find_for_paths(['nonexistent/project'])).to eq([])
|
||||
end
|
||||
|
||||
it 'finds group and project by absolute path' do
|
||||
project_path = "/#{project.full_path}"
|
||||
group_path = "/#{subgroup.full_path}"
|
||||
nonexistent_path = '/nonexistent/project'
|
||||
|
||||
expect(find_for_paths([project_path, group_path, nonexistent_path], true)).to match_array([project, subgroup])
|
||||
end
|
||||
end
|
||||
|
||||
context 'with RequestStore enabled', :request_store do
|
||||
|
|
@ -166,9 +209,16 @@ RSpec.describe Banzai::Filter::References::ReferenceCache, feature_category: :te
|
|||
expect(cache.full_project_path('something', 'cool')).to eq 'something/cool'
|
||||
end
|
||||
|
||||
it 'returns uses default namespace and project ref when namespace nil' do
|
||||
it 'returns default namespace and project ref when namespace nil' do
|
||||
expect(cache.full_project_path(nil, 'cool')).to eq "#{project.namespace.full_path}/cool"
|
||||
end
|
||||
|
||||
it 'returns absolute paths when matched to an absolute path' do
|
||||
match = "/something/cool".match(Project.reference_pattern)
|
||||
|
||||
expect(cache.full_project_path('something', 'cool', match)).to eq '/something/cool'
|
||||
expect(cache.full_project_path(nil, 'cool', match)).to eq '/cool'
|
||||
end
|
||||
end
|
||||
|
||||
describe '#full_group_path' do
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ RSpec.describe Gitlab::Analytics::InternalEventsGenerator, :silence_stdout, feat
|
|||
let(:identifiers) { %w[project user namespace] }
|
||||
let(:event_definition) do
|
||||
{
|
||||
"category" => "InternalEventTracking",
|
||||
"internal_events" => true,
|
||||
"action" => event,
|
||||
"description" => description,
|
||||
"product_section" => section,
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ RSpec.describe Gitlab::Tracking::EventDefinition, feature_category: :service_pin
|
|||
it 'has no duplicated actions in InternalEventTracking events', :aggregate_failures do
|
||||
definitions_by_action = described_class
|
||||
.definitions
|
||||
.select { |d| d.attributes[:internal_events] || d.attributes[:category] == 'InternalEventTracking' }
|
||||
.select { |d| d.attributes[:internal_events] }
|
||||
.group_by { |d| d.attributes[:action] }
|
||||
|
||||
definitions_by_action.each do |action, definitions|
|
||||
|
|
@ -45,6 +45,17 @@ RSpec.describe Gitlab::Tracking::EventDefinition, feature_category: :service_pin
|
|||
end
|
||||
end
|
||||
|
||||
it 'only has internal events without category', :aggregate_failures do
|
||||
internal_events = described_class
|
||||
.definitions
|
||||
.select { |d| d.attributes[:internal_events] }
|
||||
|
||||
internal_events.each do |event|
|
||||
expect(event.attributes[:category]).to be_nil,
|
||||
"Event definition with internal_events: true should not have a category: #{event.path}"
|
||||
end
|
||||
end
|
||||
|
||||
it 'has event definitions for all events used in Internal Events metric definitions', :aggregate_failures do
|
||||
from_metric_definitions = Gitlab::Usage::MetricDefinition.definitions
|
||||
.values
|
||||
|
|
|
|||
|
|
@ -470,7 +470,7 @@ RSpec.describe Milestone, feature_category: :team_planning do
|
|||
end
|
||||
|
||||
it 'does supports cross-project references within a group' do
|
||||
expect(milestone.to_reference(another_project, format: :name)).to eq '%"milestone"'
|
||||
expect(milestone.to_reference(another_project, format: :name)).to eq "#{group.full_path}%\"milestone\""
|
||||
end
|
||||
|
||||
it 'raises an error when using iid format' do
|
||||
|
|
|
|||
|
|
@ -1491,6 +1491,26 @@ RSpec.describe Project, factory_default: :keep, feature_category: :groups_and_pr
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#reference_pattern' do
|
||||
it 'matches a normal reference' do
|
||||
reference = project.to_reference
|
||||
match = reference.match(described_class.reference_pattern)
|
||||
|
||||
expect(match[:namespace]).to eq project.namespace.full_path
|
||||
expect(match[:project]).to eq project.path
|
||||
expect(match[:absolute_path]).to eq nil
|
||||
end
|
||||
|
||||
it 'matches an absolute reference' do
|
||||
reference = "/#{project.to_reference}"
|
||||
match = reference.match(described_class.reference_pattern)
|
||||
|
||||
expect(match[:namespace]).to eq project.namespace.full_path
|
||||
expect(match[:project]).to eq project.path
|
||||
expect(match[:absolute_path]).to eq '/'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#to_reference_base' do
|
||||
|
|
|
|||
|
|
@ -216,6 +216,12 @@ RSpec.describe API::UsageData, feature_category: :service_ping do
|
|||
context 'with authentication' do
|
||||
let_it_be(:namespace) { create(:namespace) }
|
||||
let_it_be(:project) { create(:project) }
|
||||
let_it_be(:additional_properties) do
|
||||
{
|
||||
label: 'label3',
|
||||
property: 'admin'
|
||||
}
|
||||
end
|
||||
|
||||
before do
|
||||
stub_application_setting(usage_ping_enabled: true)
|
||||
|
|
@ -225,12 +231,43 @@ RSpec.describe API::UsageData, feature_category: :service_ping do
|
|||
context 'with correct params' do
|
||||
it 'returns status ok' do
|
||||
expect(Gitlab::InternalEvents).to receive(:track_event)
|
||||
.with(known_event, send_snowplow_event: false, user: user, namespace: namespace, project: project)
|
||||
.with(
|
||||
known_event,
|
||||
send_snowplow_event: false,
|
||||
user: user,
|
||||
namespace: namespace,
|
||||
project: project,
|
||||
additional_properties: additional_properties
|
||||
)
|
||||
|
||||
post api(endpoint, user), params: { event: known_event, namespace_id: namespace.id, project_id: project.id }
|
||||
params = {
|
||||
event: known_event,
|
||||
namespace_id: namespace.id,
|
||||
project_id: project.id,
|
||||
additional_properties: additional_properties
|
||||
}
|
||||
post api(endpoint, user), params: params
|
||||
|
||||
expect(response).to have_gitlab_http_status(:ok)
|
||||
end
|
||||
|
||||
context 'with no additional_properties' do
|
||||
it 'returns status ok' do
|
||||
expect(Gitlab::InternalEvents).to receive(:track_event)
|
||||
.with(
|
||||
known_event,
|
||||
send_snowplow_event: false,
|
||||
user: user,
|
||||
namespace: namespace,
|
||||
project: project,
|
||||
additional_properties: {}
|
||||
)
|
||||
|
||||
post api(endpoint, user), params: { event: known_event, namespace_id: namespace.id, project_id: project.id }
|
||||
|
||||
expect(response).to have_gitlab_http_status(:ok)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -133,13 +133,13 @@ RSpec.describe Cli, feature_category: :service_ping do
|
|||
context 'when creating a metric from multiple events' do
|
||||
let(:events) do
|
||||
[{
|
||||
action: '00_event1', category: 'InternalEventTracking',
|
||||
action: '00_event1', internal_events: true,
|
||||
product_section: 'dev', product_stage: 'plan', product_group: 'optimize'
|
||||
}, {
|
||||
action: '00_event2', category: 'InternalEventTracking',
|
||||
action: '00_event2', internal_events: true,
|
||||
product_section: 'dev', product_stage: 'create', product_group: 'ide'
|
||||
}, {
|
||||
action: '00_event3', category: 'InternalEventTracking',
|
||||
action: '00_event3', internal_events: true,
|
||||
product_section: 'dev', product_stage: 'create', product_group: 'source_code'
|
||||
}]
|
||||
end
|
||||
|
|
@ -213,8 +213,7 @@ RSpec.describe Cli, feature_category: :service_ping do
|
|||
context 'when product group for event no longer exists' do
|
||||
let(:event) do
|
||||
{
|
||||
action: '00_event1', category: 'InternalEventTracking',
|
||||
product_section: 'other', product_stage: 'other', product_group: 'other'
|
||||
action: '00_event1', product_section: 'other', product_stage: 'other', product_group: 'other'
|
||||
}
|
||||
end
|
||||
|
||||
|
|
@ -344,7 +343,7 @@ RSpec.describe Cli, feature_category: :service_ping do
|
|||
end
|
||||
|
||||
context 'when all metrics already exist' do
|
||||
let(:event) { { action: '00_event1', category: 'InternalEventTracking' } }
|
||||
let(:event) { { action: '00_event1' } }
|
||||
let(:metric) { { options: { 'events' => ['00_event1'] }, events: [{ 'name' => '00_event1' }] } }
|
||||
|
||||
let(:files) do
|
||||
|
|
|
|||
|
|
@ -228,7 +228,7 @@ module GitalySetup
|
|||
|
||||
Gitlab::SetupHelper::Gitaly.create_configuration(
|
||||
gitaly_dir,
|
||||
{ 'default' => storage_path, 'test_second_storage' => second_storage_path },
|
||||
{ 'default' => storage_path },
|
||||
force: true,
|
||||
options: {
|
||||
runtime_dir: runtime_dir,
|
||||
|
|
@ -237,7 +237,7 @@ module GitalySetup
|
|||
)
|
||||
Gitlab::SetupHelper::Gitaly.create_configuration(
|
||||
gitaly_dir,
|
||||
{ 'default' => storage_path, 'test_second_storage' => second_storage_path },
|
||||
{ 'test_second_storage' => second_storage_path },
|
||||
force: true,
|
||||
options: {
|
||||
runtime_dir: runtime_dir,
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ require (
|
|||
github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.3.0
|
||||
github.com/BurntSushi/toml v1.3.2
|
||||
github.com/alecthomas/chroma/v2 v2.12.0
|
||||
github.com/aws/aws-sdk-go v1.50.7
|
||||
github.com/aws/aws-sdk-go v1.50.27
|
||||
github.com/disintegration/imaging v1.6.2
|
||||
github.com/getsentry/raven-go v0.2.0
|
||||
github.com/golang-jwt/jwt/v5 v5.2.1
|
||||
|
|
@ -30,19 +30,19 @@ require (
|
|||
golang.org/x/net v0.21.0
|
||||
golang.org/x/oauth2 v0.16.0
|
||||
golang.org/x/tools v0.18.0
|
||||
google.golang.org/grpc v1.61.0
|
||||
google.golang.org/grpc v1.62.0
|
||||
google.golang.org/protobuf v1.32.0
|
||||
honnef.co/go/tools v0.4.7
|
||||
)
|
||||
|
||||
require (
|
||||
cloud.google.com/go v0.110.10 // indirect
|
||||
cloud.google.com/go v0.112.0 // indirect
|
||||
cloud.google.com/go/compute v1.23.3 // indirect
|
||||
cloud.google.com/go/compute/metadata v0.2.3 // indirect
|
||||
cloud.google.com/go/iam v1.1.5 // indirect
|
||||
cloud.google.com/go/monitoring v1.16.3 // indirect
|
||||
cloud.google.com/go/monitoring v1.17.0 // indirect
|
||||
cloud.google.com/go/profiler v0.1.0 // indirect
|
||||
cloud.google.com/go/storage v1.35.1 // indirect
|
||||
cloud.google.com/go/storage v1.36.0 // indirect
|
||||
cloud.google.com/go/trace v1.10.4 // indirect
|
||||
contrib.go.opencensus.io/exporter/stackdriver v0.13.14 // indirect
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.9.2 // indirect
|
||||
|
|
@ -63,6 +63,9 @@ require (
|
|||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
|
||||
github.com/dlclark/regexp2 v1.10.0 // indirect
|
||||
github.com/felixge/httpsnoop v1.0.4 // indirect
|
||||
github.com/go-logr/logr v1.3.0 // indirect
|
||||
github.com/go-logr/stdr v1.2.2 // indirect
|
||||
github.com/go-ole/go-ole v1.2.6 // indirect
|
||||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
||||
|
|
@ -107,6 +110,11 @@ require (
|
|||
github.com/uber/jaeger-lib v2.4.1+incompatible // indirect
|
||||
github.com/yusufpapurcu/wmi v1.2.2 // indirect
|
||||
go.opencensus.io v0.24.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.46.1 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1 // indirect
|
||||
go.opentelemetry.io/otel v1.21.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.21.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.21.0 // indirect
|
||||
go.uber.org/atomic v1.11.0 // indirect
|
||||
golang.org/x/crypto v0.19.0 // indirect
|
||||
golang.org/x/exp/typeparams v0.0.0-20221208152030-732eee02a75a // indirect
|
||||
|
|
@ -114,13 +122,13 @@ require (
|
|||
golang.org/x/sync v0.6.0 // indirect
|
||||
golang.org/x/sys v0.17.0 // indirect
|
||||
golang.org/x/text v0.14.0 // indirect
|
||||
golang.org/x/time v0.4.0 // indirect
|
||||
golang.org/x/time v0.5.0 // indirect
|
||||
golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect
|
||||
google.golang.org/api v0.151.0 // indirect
|
||||
google.golang.org/api v0.155.0 // indirect
|
||||
google.golang.org/appengine v1.6.8 // indirect
|
||||
google.golang.org/genproto v0.0.0-20231120223509-83a465c0220f // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20231120223509-83a465c0220f // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20231120223509-83a465c0220f // indirect
|
||||
google.golang.org/genproto v0.0.0-20240123012728-ef4313101c80 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240123012728-ef4313101c80 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240123012728-ef4313101c80 // indirect
|
||||
gopkg.in/DataDog/dd-trace-go.v1 v1.32.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
|
|
|
|||
|
|
@ -24,8 +24,8 @@ cloud.google.com/go v0.84.0/go.mod h1:RazrYuxIK6Kb7YrzzhPoLmCVzl7Sup4NrbKPg8KHSU
|
|||
cloud.google.com/go v0.87.0/go.mod h1:TpDYlFy7vuLzZMMZ+B6iRiELaY7z/gJPaqbMx6mlWcY=
|
||||
cloud.google.com/go v0.90.0/go.mod h1:kRX0mNRHe0e2rC6oNakvwQqzyDmg57xJ+SZU1eT2aDQ=
|
||||
cloud.google.com/go v0.92.2/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+YI=
|
||||
cloud.google.com/go v0.110.10 h1:LXy9GEO+timppncPIAZoOj3l58LIU9k+kn48AN7IO3Y=
|
||||
cloud.google.com/go v0.110.10/go.mod h1:v1OoFqYxiBkUrruItNM3eT4lLByNjxmJSV/xDKJNnic=
|
||||
cloud.google.com/go v0.112.0 h1:tpFCD7hpHFlQ8yPwT3x+QeXqc2T6+n6T+hmABHfDUSM=
|
||||
cloud.google.com/go v0.112.0/go.mod h1:3jEEVwZ/MHU4djK5t5RHuKOA/GbLddgTdVubX1qnPD4=
|
||||
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
|
||||
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
|
||||
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
|
||||
|
|
@ -40,8 +40,8 @@ cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7
|
|||
cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
|
||||
cloud.google.com/go/iam v1.1.5 h1:1jTsCu4bcsNsE4iiqNT5SHwrDRCfRmIaaaVFhRveTJI=
|
||||
cloud.google.com/go/iam v1.1.5/go.mod h1:rB6P/Ic3mykPbFio+vo7403drjlgvoWfYpJhMXEbzv8=
|
||||
cloud.google.com/go/monitoring v1.16.3 h1:mf2SN9qSoBtIgiMA4R/y4VADPWZA7VCNJA079qLaZQ8=
|
||||
cloud.google.com/go/monitoring v1.16.3/go.mod h1:KwSsX5+8PnXv5NJnICZzW2R8pWTis8ypC4zmdRD63Tw=
|
||||
cloud.google.com/go/monitoring v1.17.0 h1:blrdvF0MkPPivSO041ihul7rFMhXdVp8Uq7F59DKXTU=
|
||||
cloud.google.com/go/monitoring v1.17.0/go.mod h1:KwSsX5+8PnXv5NJnICZzW2R8pWTis8ypC4zmdRD63Tw=
|
||||
cloud.google.com/go/profiler v0.1.0 h1:MG/rxKC1MztRfEWMGYKFISxyZak5hNh29f0A/z2tvWk=
|
||||
cloud.google.com/go/profiler v0.1.0/go.mod h1:D7S7LV/zKbRWkOzYL1b5xytpqt8Ikd/v/yvf1/Tx2pQ=
|
||||
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
|
||||
|
|
@ -53,8 +53,8 @@ cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0Zeo
|
|||
cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
|
||||
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
|
||||
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
|
||||
cloud.google.com/go/storage v1.35.1 h1:B59ahL//eDfx2IIKFBeT5Atm9wnNmj3+8xG/W4WB//w=
|
||||
cloud.google.com/go/storage v1.35.1/go.mod h1:M6M/3V/D3KpzMTJyPOR/HU6n2Si5QdaXYEsng2xgOs8=
|
||||
cloud.google.com/go/storage v1.36.0 h1:P0mOkAcaJxhCTvAkMhxMfrTKiNcub4YmmPBtlhAyTr8=
|
||||
cloud.google.com/go/storage v1.36.0/go.mod h1:M6M/3V/D3KpzMTJyPOR/HU6n2Si5QdaXYEsng2xgOs8=
|
||||
cloud.google.com/go/trace v1.10.4 h1:2qOAuAzNezwW3QN+t41BtkDJOG42HywL73q8x/f6fnM=
|
||||
cloud.google.com/go/trace v1.10.4/go.mod h1:Nso99EDIK8Mj5/zmB+iGr9dosS/bzWCJ8wGmE6TXNWY=
|
||||
contrib.go.opencensus.io/exporter/stackdriver v0.13.14 h1:zBakwHardp9Jcb8sQHcHpXy/0+JIb1M8KjigCJzx7+4=
|
||||
|
|
@ -94,8 +94,8 @@ github.com/alecthomas/chroma/v2 v2.12.0/go.mod h1:4TQu7gdfuPjSh76j78ietmqh9LiurG
|
|||
github.com/alecthomas/repr v0.2.0 h1:HAzS41CIzNW5syS8Mf9UwXhNH1J9aix/BvDRf1Ml2Yk=
|
||||
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
|
||||
github.com/aws/aws-sdk-go v1.44.256/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI=
|
||||
github.com/aws/aws-sdk-go v1.50.7 h1:odKb+uneeGgF2jgAerKjFzpljiyZxleV4SHB7oBK+YA=
|
||||
github.com/aws/aws-sdk-go v1.50.7/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk=
|
||||
github.com/aws/aws-sdk-go v1.50.27 h1:96ifhrSuja+AzdP3W/T2337igqVQ2FcSIJYkk+0rCeA=
|
||||
github.com/aws/aws-sdk-go v1.50.27/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk=
|
||||
github.com/aws/aws-sdk-go-v2 v1.24.0 h1:890+mqQ+hTpNuw0gGP6/4akolQkSToDJgHfQE7AwGuk=
|
||||
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.5.4 h1:OCs21ST2LrepDfD3lwlQiOqIGp6JiEUqG84GzTDoyJs=
|
||||
github.com/aws/aws-sdk-go-v2/config v1.26.1 h1:z6DqMxclFGL3Zfo+4Q0rLnAZ6yVkzCRxhRMsiRQnD1o=
|
||||
|
|
@ -141,6 +141,7 @@ github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGX
|
|||
github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
||||
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
||||
github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||
github.com/cncf/xds/go v0.0.0-20231128003011-0fa0005c9caa h1:jQCWAUqqlij9Pgj2i/PB79y4KOPYVyFYdROxgaCwdTQ=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
|
||||
|
|
@ -160,6 +161,9 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.m
|
|||
github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
|
||||
github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/envoyproxy/protoc-gen-validate v1.0.4 h1:gVPz/FMfvh57HdSJQyvBtF00j8JU4zdyUgIUNhlgg0A=
|
||||
github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
|
||||
github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
|
||||
github.com/fsnotify/fsnotify v1.4.3-0.20170329110642-4da3e2cfbabc/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/garyburd/redigo v1.1.1-0.20170914051019-70e1b1943d4f/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY=
|
||||
|
|
@ -171,6 +175,11 @@ github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2
|
|||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY=
|
||||
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
|
||||
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
github.com/go-logr/logr v1.3.0 h1:2y3SDp0ZXuc6/cjLSZ+Q3ir+QB9T/iG5yYRXqsagWSY=
|
||||
github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
||||
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
||||
github.com/go-ole/go-ole v1.2.4/go.mod h1:XCwSNxSkXRo4vlyPy93sltvi/qJq0jqQhjqQNIwKuxM=
|
||||
github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY=
|
||||
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
|
||||
|
|
@ -456,6 +465,17 @@ go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk=
|
|||
go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E=
|
||||
go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
|
||||
go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.46.1 h1:SpGay3w+nEwMpfVnbqOLH5gY52/foP8RE8UzTZ1pdSE=
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.46.1/go.mod h1:4UoMYEZOC0yN/sPGH76KPkkU7zgiEWYWL9vwmbnTJPE=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1 h1:aFJWCqJMNjENlcleuuOkGAPH82y0yULBScfXcIEdS24=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1/go.mod h1:sEGXWArGqc3tVa+ekntsN65DmVbVeW+7lTKTjZF3/Fo=
|
||||
go.opentelemetry.io/otel v1.21.0 h1:hzLeKBZEL7Okw2mGzZ0cc4k/A7Fta0uoPgaJCr8fsFc=
|
||||
go.opentelemetry.io/otel v1.21.0/go.mod h1:QZzNPQPm1zLX4gZK4cMi+71eaorMSGT3A4znnUvNNEo=
|
||||
go.opentelemetry.io/otel/metric v1.21.0 h1:tlYWfeo+Bocx5kLEloTjbcDwBuELRrIFxwdQ36PlJu4=
|
||||
go.opentelemetry.io/otel/metric v1.21.0/go.mod h1:o1p3CA8nNHW8j5yuQLdc1eeqEaPfzug24uvsyIEJRWM=
|
||||
go.opentelemetry.io/otel/sdk v1.21.0 h1:FTt8qirL1EysG6sTQRZ5TokkU8d0ugCj8htOgThZXQ8=
|
||||
go.opentelemetry.io/otel/trace v1.21.0 h1:WD9i5gzvoUPuXIXH24ZNBudiarZDKuekPqi/E8fpfLc=
|
||||
go.opentelemetry.io/otel/trace v1.21.0/go.mod h1:LGbsEB0f9LGjN+OZaQQ26sohbOmiMR+BaslueVtS/qQ=
|
||||
go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
|
||||
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
||||
go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE=
|
||||
|
|
@ -689,8 +709,8 @@ golang.org/x/time v0.0.0-20170424234030-8be79e1e0910/go.mod h1:tRJNPiyCQ0inRvYxb
|
|||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.4.0 h1:Z81tqI5ddIoXDPvVQ7/7CC9TnLM7ubaFG2qXYd5BbYY=
|
||||
golang.org/x/time v0.4.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
|
||||
golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
|
||||
golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||
|
|
@ -785,8 +805,8 @@ google.golang.org/api v0.48.0/go.mod h1:71Pr1vy+TAZRPkPs/xlCf5SsU8WjuAWv1Pfjbtuk
|
|||
google.golang.org/api v0.50.0/go.mod h1:4bNT5pAuq5ji4SRZm+5QIkjny9JAyVD/3gaSihNefaw=
|
||||
google.golang.org/api v0.51.0/go.mod h1:t4HdrdoNgyN5cbEfm7Lum0lcLDLiise1F8qDKX00sOU=
|
||||
google.golang.org/api v0.54.0/go.mod h1:7C4bFFOvVDGXjfDTAsgGwDgAxRDeQ4X8NvUedIt6z3k=
|
||||
google.golang.org/api v0.151.0 h1:FhfXLO/NFdJIzQtCqjpysWwqKk8AzGWBUhMIx67cVDU=
|
||||
google.golang.org/api v0.151.0/go.mod h1:ccy+MJ6nrYFgE3WgRx/AMXOxOmU8Q4hSa+jjibzhxcg=
|
||||
google.golang.org/api v0.155.0 h1:vBmGhCYs0djJttDNynWo44zosHlPvHmA0XiN2zP2DtA=
|
||||
google.golang.org/api v0.155.0/go.mod h1:GI5qK5f40kCpHfPn6+YzGAByIKWv8ujFnmoWm7Igduk=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
|
|
@ -849,12 +869,12 @@ google.golang.org/genproto v0.0.0-20210716133855-ce7ef5c701ea/go.mod h1:AxrInvYm
|
|||
google.golang.org/genproto v0.0.0-20210728212813-7823e685a01f/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48=
|
||||
google.golang.org/genproto v0.0.0-20210805201207-89edb61ffb67/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48=
|
||||
google.golang.org/genproto v0.0.0-20210813162853-db860fec028c/go.mod h1:cFeNkxwySK631ADgubI+/XFU/xp8FD5KIVV4rj8UC5w=
|
||||
google.golang.org/genproto v0.0.0-20231120223509-83a465c0220f h1:Vn+VyHU5guc9KjB5KrjI2q0wCOWEOIh0OEsleqakHJg=
|
||||
google.golang.org/genproto v0.0.0-20231120223509-83a465c0220f/go.mod h1:nWSwAFPb+qfNJXsoeO3Io7zf4tMSfN8EA8RlDA04GhY=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20231120223509-83a465c0220f h1:2yNACc1O40tTnrsbk9Cv6oxiW8pxI/pXj0wRtdlYmgY=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20231120223509-83a465c0220f/go.mod h1:Uy9bTZJqmfrw2rIBxgGLnamc78euZULUBrLZ9XTITKI=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20231120223509-83a465c0220f h1:ultW7fxlIvee4HYrtnaRPon9HpEgFk5zYpmfMgtKB5I=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20231120223509-83a465c0220f/go.mod h1:L9KNLi232K1/xB6f7AlSX692koaRnKaWSR0stBki0Yc=
|
||||
google.golang.org/genproto v0.0.0-20240123012728-ef4313101c80 h1:KAeGQVN3M9nD0/bQXnr/ClcEMJ968gUXJQ9pwfSynuQ=
|
||||
google.golang.org/genproto v0.0.0-20240123012728-ef4313101c80/go.mod h1:cc8bqMqtv9gMOr0zHg2Vzff5ULhhL2IXP4sbcn32Dro=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240123012728-ef4313101c80 h1:Lj5rbfG876hIAYFjqiJnPHfhXbv+nzTWfm04Fg/XSVU=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240123012728-ef4313101c80/go.mod h1:4jWUdICTdgc3Ibxmr8nAJiiLHwQBY0UI0XZcEMaFKaA=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240123012728-ef4313101c80 h1:AjyfHzEPEFp/NpvfN5g+KDla3EMojjhRVZc1i7cj+oM=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240123012728-ef4313101c80/go.mod h1:PAREbraiVEVGVdTZsVWjSbbTtSyGbAgIIvni8a8CD5s=
|
||||
google.golang.org/grpc v1.2.1-0.20170921194603-d4b75ebd4f9f/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
|
||||
|
|
@ -881,8 +901,8 @@ google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQ
|
|||
google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
|
||||
google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE=
|
||||
google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE=
|
||||
google.golang.org/grpc v1.61.0 h1:TOvOcuXn30kRao+gfcvsebNEa5iZIiLkisYEkf7R7o0=
|
||||
google.golang.org/grpc v1.61.0/go.mod h1:VUbo7IFqmF1QtCAstipjG0GIoq49KvMe9+h1jFLBNJs=
|
||||
google.golang.org/grpc v1.62.0 h1:HQKZ/fa1bXkX1oFOvSjmZEUL8wLSaZTjCcLAlmZRtdk=
|
||||
google.golang.org/grpc v1.62.0/go.mod h1:IWTG0VlJLCh1SkC58F7np9ka9mx/WNkjl4PGJaiq+QE=
|
||||
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||
|
|
|
|||
Loading…
Reference in New Issue