mirror of
https://gitlab.com/gitlab-org/gitlab-foss.git
synced 2025-07-20 16:46:17 +00:00
Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
219
bin/secpick
219
bin/secpick
@ -2,219 +2,14 @@
|
||||
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'active_support/core_ext/object/to_query'
|
||||
require 'optparse'
|
||||
require 'open3'
|
||||
require 'rainbow/refinement'
|
||||
using Rainbow
|
||||
|
||||
module Secpick
|
||||
BRANCH_PREFIX = 'security'
|
||||
STABLE_SUFFIX = 'stable'
|
||||
NEW_SCRIPT = 'scripts/backport_fix_to_stable_branch'
|
||||
|
||||
DEFAULT_REMOTE = 'security'
|
||||
|
||||
SECURITY_MR_URL = 'https://gitlab.com/gitlab-org/security/gitlab/-/merge_requests/new'
|
||||
|
||||
class SecurityFix
|
||||
def initialize
|
||||
@options = self.class.options
|
||||
end
|
||||
|
||||
def dry_run?
|
||||
@options[:try] == true
|
||||
end
|
||||
|
||||
def source_branch
|
||||
branch = "#{@options[:branch]}-#{@options[:version]}"
|
||||
branch = "#{BRANCH_PREFIX}-#{branch}" unless branch.start_with?("#{BRANCH_PREFIX}-")
|
||||
branch
|
||||
end
|
||||
|
||||
def stable_branch
|
||||
"#{@options[:version]}-#{STABLE_SUFFIX}-ee"
|
||||
end
|
||||
|
||||
def git_pick_commands
|
||||
[
|
||||
fetch_stable_branch,
|
||||
create_backport_branch,
|
||||
cherry_pick_commit
|
||||
]
|
||||
end
|
||||
|
||||
def git_push_commands
|
||||
[
|
||||
push_to_remote,
|
||||
checkout_original_branch
|
||||
]
|
||||
end
|
||||
|
||||
def git_commands
|
||||
git_pick_commands + git_push_commands
|
||||
end
|
||||
|
||||
def gitlab_params
|
||||
{
|
||||
issuable_template: 'Security Release',
|
||||
merge_request: {
|
||||
source_branch: source_branch,
|
||||
target_branch: stable_branch
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
def new_mr_url
|
||||
SECURITY_MR_URL
|
||||
end
|
||||
|
||||
def create!
|
||||
if dry_run?
|
||||
puts "\nGit commands:".blue
|
||||
puts git_commands.join("\n")
|
||||
|
||||
if !@options[:merge_request]
|
||||
puts "\nMerge request URL:".blue
|
||||
puts new_mr_url
|
||||
end
|
||||
|
||||
puts "\nMerge request params:".blue
|
||||
pp gitlab_params
|
||||
else
|
||||
cmd = git_pick_commands.join(' && ')
|
||||
stdin, stdout, stderr, wait_thr = Open3.popen3(cmd)
|
||||
|
||||
puts stdout.read&.green
|
||||
puts stderr.read&.red
|
||||
|
||||
unless wait_thr.value.success?
|
||||
puts <<~MSG
|
||||
It looks like cherry pick failed!
|
||||
Open a new terminal and fix the conflicts.
|
||||
Once fixed run `git cherry-pick --continue`
|
||||
|
||||
After you are done, return here and continue. (Press n to cancel)
|
||||
|
||||
Ready to continue? (Y/n)
|
||||
MSG
|
||||
|
||||
unless ['', 'Y', 'y'].include?(gets.chomp)
|
||||
puts "\nRemaining git commands:".blue
|
||||
puts 'git cherry-pick --continue'
|
||||
puts git_push_commands.join("\n")
|
||||
exit 1
|
||||
end
|
||||
end
|
||||
|
||||
stdin.close
|
||||
stdout.close
|
||||
stderr.close
|
||||
|
||||
cmd = git_push_commands.join(' && ')
|
||||
stdin, stdout, stderr, wait_thr = Open3.popen3(cmd)
|
||||
|
||||
puts stdout.read&.green
|
||||
puts stderr.read&.red
|
||||
|
||||
if wait_thr.value.success? && !@options[:merge_request]
|
||||
puts "#{new_mr_url}?#{gitlab_params.to_query}".blue
|
||||
end
|
||||
|
||||
stdin.close
|
||||
stdout.close
|
||||
stderr.close
|
||||
end
|
||||
end
|
||||
|
||||
def self.options
|
||||
{ version: nil, branch: nil, sha: nil, merge_request: false }.tap do |options|
|
||||
parser = OptionParser.new do |opts|
|
||||
opts.banner = "Usage: #{$0} [options]"
|
||||
opts.on('-v', '--version 10.0', 'Version') do |version|
|
||||
options[:version] = version&.tr('.', '-')
|
||||
end
|
||||
|
||||
opts.on('-b', '--branch security-fix-branch', 'Original branch name (optional, defaults to current)') do |branch|
|
||||
options[:branch] = branch
|
||||
end
|
||||
|
||||
opts.on('-s', '--sha abcd', 'SHA or SHA range to cherry pick (optional, defaults to current)') do |sha|
|
||||
options[:sha] = sha
|
||||
end
|
||||
|
||||
opts.on('-r', '--remote dev', "Git remote name of security repo (optional, defaults to `#{DEFAULT_REMOTE}`)") do |remote|
|
||||
options[:remote] = remote
|
||||
end
|
||||
|
||||
opts.on('--mr', '--merge-request', 'Create relevant security Merge Request targeting the stable branch') do
|
||||
options[:merge_request] = true
|
||||
end
|
||||
|
||||
opts.on('-d', '--dry-run', 'Only show Git commands, without calling them') do
|
||||
options[:try] = true
|
||||
end
|
||||
|
||||
opts.on('-h', '--help', 'Displays Help') do
|
||||
puts opts
|
||||
|
||||
exit
|
||||
end
|
||||
end
|
||||
|
||||
parser.parse!
|
||||
|
||||
options[:sha] ||= `git rev-parse HEAD`.strip
|
||||
options[:branch] ||= `git rev-parse --abbrev-ref HEAD`.strip
|
||||
options[:remote] ||= DEFAULT_REMOTE
|
||||
|
||||
nil_options = options.select {|_, v| v.nil? }
|
||||
unless nil_options.empty?
|
||||
abort("Missing: #{nil_options.keys.join(', ')}. Use #{$0} --help to see the list of options available".red)
|
||||
end
|
||||
|
||||
abort("Wrong version format #{options[:version].bold}".red) unless options[:version] =~ /\A\d*\-\d*\Z/
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def checkout_original_branch
|
||||
"git checkout #{@options[:branch]}"
|
||||
end
|
||||
|
||||
def push_to_remote
|
||||
[
|
||||
"git push #{@options[:remote]} #{source_branch} --no-verify",
|
||||
*merge_request_push_options
|
||||
].join(' ')
|
||||
end
|
||||
|
||||
def merge_request_push_options
|
||||
return [] unless @options[:merge_request]
|
||||
|
||||
[
|
||||
"-o mr.create",
|
||||
"-o mr.target='#{stable_branch}'",
|
||||
"-o mr.description='Please apply Security Release template.\\n/milestone %#{milestone}'"
|
||||
]
|
||||
end
|
||||
|
||||
def cherry_pick_commit
|
||||
"git cherry-pick #{@options[:sha]}"
|
||||
end
|
||||
|
||||
def create_backport_branch
|
||||
"git checkout -B #{source_branch} #{@options[:remote]}/#{stable_branch} --no-track"
|
||||
end
|
||||
|
||||
def fetch_stable_branch
|
||||
"git fetch #{@options[:remote]} #{stable_branch}"
|
||||
end
|
||||
|
||||
def milestone
|
||||
@options[:version].gsub('-', '.')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Secpick::SecurityFix.new.create!
|
||||
puts "\n⚠️ This tool has moved! ⚠️\n".red
|
||||
puts "bin/secpick has updated and moved to ".white + NEW_SCRIPT.red.bold
|
||||
puts "\nThe new script can be used for #{'security fix backports'.bold}".white + " and #{'bug fix backports'.bold}.\n".white
|
||||
puts "Please run again with:".white
|
||||
puts "\n#{NEW_SCRIPT} #{ARGV.join(' ')}".blue
|
||||
exit 1
|
||||
|
@ -278,7 +278,7 @@
|
||||
"crypto": "^1.0.1",
|
||||
"custom-jquery-matchers": "^2.1.0",
|
||||
"dependency-cruiser": "^16.9.0",
|
||||
"eslint": "9.29.0",
|
||||
"eslint": "9.30.0",
|
||||
"eslint-formatter-gitlab": "^6.0.1",
|
||||
"eslint-import-resolver-jest": "3.0.2",
|
||||
"eslint-import-resolver-webpack": "0.13.10",
|
||||
|
371
scripts/backport_fix_to_stable_branch
Executable file
371
scripts/backport_fix_to_stable_branch
Executable file
@ -0,0 +1,371 @@
|
||||
#!/usr/bin/env ruby
|
||||
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'active_support/core_ext/object/to_query'
|
||||
require 'optparse'
|
||||
require 'open3'
|
||||
require 'rainbow/refinement'
|
||||
require 'tty-prompt'
|
||||
using Rainbow
|
||||
|
||||
class Backport
|
||||
SECURITY_REPO_URLS = {
|
||||
ssh: 'git@gitlab.com:gitlab-org/security/gitlab.git',
|
||||
http: 'https://gitlab.com/gitlab-org/security/gitlab.git'
|
||||
}.freeze
|
||||
|
||||
DEFAULT_OPTIONS = {
|
||||
base: {
|
||||
version: nil, branch: nil, sha: nil, merge_request: false, stable_branch_suffix: 'stable'
|
||||
},
|
||||
security: {
|
||||
branch_prefix: 'security',
|
||||
new_merge_request_url: 'https://gitlab.com/gitlab-org/security/gitlab/-/merge_requests/new',
|
||||
merge_request_template: 'Security Fix'
|
||||
},
|
||||
bugfix: {
|
||||
branch_prefix: 'backport',
|
||||
new_merge_request_url: 'https://gitlab.com/gitlab-org/gitlab/-/merge_requests/new',
|
||||
merge_request_template: 'Stable Branch'
|
||||
}
|
||||
}.freeze
|
||||
|
||||
BACKPORT_TYPE_CHOICES = [
|
||||
{ name: 'Security Fix', value: :security }.freeze,
|
||||
{ name: 'Bug Fix', value: :bugfix }.freeze
|
||||
].freeze
|
||||
|
||||
def initialize
|
||||
@prompt = TTY::Prompt.new(help_color: :cyan)
|
||||
@options = build_options
|
||||
end
|
||||
|
||||
attr_reader :prompt
|
||||
|
||||
def create!
|
||||
correct_repository_check!
|
||||
|
||||
return dry_run if dry_run?
|
||||
|
||||
pick_commits
|
||||
push_commits
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def correct_repository_check!
|
||||
if security_backport? && !pushing_to_security_remote?
|
||||
abort('⛔️ Can only push security backports to the security repository ⛔️'.red)
|
||||
elsif !security_backport? && pushing_to_security_remote?
|
||||
abort('⛔️ Bugfixes should be pushed to the canonical repository ⛔️'.red)
|
||||
end
|
||||
end
|
||||
|
||||
def pushing_to_security_remote?
|
||||
@options[:remote] == security_remote_name
|
||||
end
|
||||
|
||||
def build_options
|
||||
options = DEFAULT_OPTIONS[:base].dup
|
||||
parse_options(options)
|
||||
|
||||
options[:sha] ||= git_head_sha
|
||||
options[:branch] ||= git_current_branch
|
||||
options[:remote] ||= select_git_remote
|
||||
options[:version] ||= select_version
|
||||
|
||||
options.merge(DEFAULT_OPTIONS[confirmed_backport_type!])
|
||||
end
|
||||
|
||||
def confirmed_backport_type!
|
||||
backport_type = prompt.select('⚠️ What type of fix are you backporting? ⚠️'.red, BACKPORT_TYPE_CHOICES)
|
||||
|
||||
@security_backport = backport_type == :security
|
||||
|
||||
backport_type
|
||||
end
|
||||
|
||||
def security_backport?
|
||||
@security_backport
|
||||
end
|
||||
|
||||
def add_security_remote
|
||||
puts "⚠️ You do not have the security remote configured ⚠️".red
|
||||
|
||||
return attempt_to_add_security_remote if prompt.yes?('Would you like me to add the remote for you now?')
|
||||
|
||||
print_security_remote_config_instructions_and_exit
|
||||
end
|
||||
|
||||
def attempt_to_add_security_remote
|
||||
security_repo_url = prompt.select('Which remote format do you normally use?', git_remote_style_choices)
|
||||
stdin, stdout, stderr, wait_thr = Open3.popen3("git remote add security #{security_repo_url}")
|
||||
|
||||
if wait_thr.value.success? # rubocop:disable Cop/LineBreakAroundConditionalBlock -- https://gitlab.com/gitlab-org/ruby/gems/gitlab-styles/-/merge_requests/258
|
||||
@security_remote_name = 'security'
|
||||
puts '✅ Successfully created `security` remote'.white
|
||||
else
|
||||
puts "⛔️ Could not create `security` remote ⛔️".red
|
||||
puts ('-' * 80).red
|
||||
puts "\n#{stderr.read}".red
|
||||
puts ('-' * 80).red
|
||||
|
||||
print_security_remote_config_instructions_and_exit
|
||||
end
|
||||
ensure
|
||||
stdin.close
|
||||
stdout.close
|
||||
stderr.close
|
||||
end
|
||||
|
||||
def print_security_remote_config_instructions_and_exit
|
||||
puts "Please add the gitlab security remote to git with:".white
|
||||
puts "git remote add security #{SECURITY_REPO_URLS[:ssh]}".cyan
|
||||
puts "or".white
|
||||
puts "git remote add security #{SECURITY_REPO_URLS[:http]}".cyan
|
||||
puts "and then try again".white
|
||||
exit 1
|
||||
end
|
||||
|
||||
def parse_options(options)
|
||||
parser = OptionParser.new do |opts|
|
||||
opts.banner = <<~BANNER
|
||||
Usage: #{$PROGRAM_NAME} [options]
|
||||
|
||||
This tool requires confirmation for the backport type and will prompt
|
||||
for the remote and version unless specified.
|
||||
|
||||
BANNER
|
||||
|
||||
opts.on('-v', '--version 10.0', 'Version to target (opens prompt if not passed)') do |version|
|
||||
options[:version] = version&.tr('.', '-')
|
||||
end
|
||||
|
||||
opts.on('-r', '--remote dev', "Git remote name of repository (opens prompt if not passed)") do |remote|
|
||||
options[:remote] = remote
|
||||
end
|
||||
|
||||
opts.on('-b', '--branch branch-name', 'Original branch name (optional, defaults to current branch)') do |branch|
|
||||
options[:branch] = branch
|
||||
end
|
||||
|
||||
opts.on('-s', '--sha abcd', 'SHA or SHA range to cherry pick (optional, defaults to HEAD SHA)') do |sha|
|
||||
options[:sha] = sha
|
||||
end
|
||||
|
||||
opts.on('--mr', '--merge-request', 'Create a Merge Request targeting the stable branch') do
|
||||
options[:merge_request] = true
|
||||
end
|
||||
|
||||
opts.on('-d', '--dry-run', 'Display the Git commands this script will run without calling them') do
|
||||
options[:try] = true
|
||||
end
|
||||
|
||||
opts.on('-h', '--help', 'Displays Help') do
|
||||
puts opts
|
||||
|
||||
exit
|
||||
end
|
||||
end
|
||||
|
||||
parser.parse!
|
||||
end
|
||||
|
||||
def git_head_sha
|
||||
`git rev-parse HEAD`.strip
|
||||
end
|
||||
|
||||
def git_current_branch
|
||||
`git rev-parse --abbrev-ref HEAD`.strip
|
||||
end
|
||||
|
||||
def select_git_remote
|
||||
prompt.select("Which remote do you want to push to?", remote_choices)
|
||||
end
|
||||
|
||||
def git_remotes
|
||||
@git_remotes ||= `git remote -v`.strip.split("\n").each_with_object({}) do |line, output|
|
||||
name, url, _type = line.split(/\s+/)
|
||||
output[name] = url
|
||||
end
|
||||
end
|
||||
|
||||
def security_remote_name
|
||||
return @security_remote_name if defined?(@security_remote_name)
|
||||
|
||||
@security_remote_name = git_remotes.find { |_k, url| SECURITY_REPO_URLS.value?(url) }&.first
|
||||
add_security_remote if @security_remote_name.nil?
|
||||
@security_remote_name
|
||||
end
|
||||
|
||||
# Sorts git remotes so the security remote is first in the list
|
||||
def remote_choices
|
||||
[security_remote_name] + (git_remotes.keys - [security_remote_name])
|
||||
end
|
||||
|
||||
def git_remote_style_choices
|
||||
SECURITY_REPO_URLS.map { |style, url| { name: "#{style}: #{url}", value: url } }
|
||||
end
|
||||
|
||||
def select_version
|
||||
prompt.select('Which version are you targeting?', version_choices)
|
||||
end
|
||||
|
||||
def current_version
|
||||
version_filepath = File.join(File.dirname($PROGRAM_NAME), '../VERSION')
|
||||
full_version = File.read(version_filepath)
|
||||
major, minor, _rest = full_version.split('.')
|
||||
[major.to_i, minor.to_i]
|
||||
end
|
||||
|
||||
def version_choices
|
||||
major, minor = current_version
|
||||
|
||||
Array.new(3) do
|
||||
minor -= 1
|
||||
|
||||
if minor < 0
|
||||
major -= 1
|
||||
minor = 11
|
||||
end
|
||||
|
||||
{ name: "#{major}.#{minor}", value: "#{major}-#{minor}" }
|
||||
end
|
||||
end
|
||||
|
||||
def dry_run?
|
||||
@options[:try] == true
|
||||
end
|
||||
|
||||
def dry_run
|
||||
puts "\nGit commands:".blue
|
||||
puts git_commands.join("\n")
|
||||
puts "\nMerge request URL:".blue
|
||||
puts new_merge_request_url
|
||||
end
|
||||
|
||||
def pick_commits
|
||||
cmd = git_pick_commands.join(' && ')
|
||||
stdin, stdout, stderr, wait_thr = Open3.popen3(cmd)
|
||||
|
||||
puts stdout.read.green
|
||||
puts stderr.read.red
|
||||
|
||||
unless wait_thr.value.success? # rubocop:disable Cop/LineBreakAroundConditionalBlock -- https://gitlab.com/gitlab-org/ruby/gems/gitlab-styles/-/merge_requests/258
|
||||
puts <<~MSG
|
||||
It looks like cherry pick failed!
|
||||
Open a new terminal and fix the conflicts.
|
||||
Once fixed run `git cherry-pick --continue`
|
||||
|
||||
After you are done, return here and continue. (Press n to cancel)
|
||||
|
||||
Ready to continue? (Y/n)
|
||||
MSG
|
||||
|
||||
unless ['', 'Y', 'y'].include?(gets.chomp)
|
||||
puts "\nRemaining git commands:".blue
|
||||
puts 'git cherry-pick --continue'
|
||||
puts git_push_commands.join("\n")
|
||||
exit 1
|
||||
end
|
||||
end
|
||||
ensure
|
||||
stdin.close
|
||||
stdout.close
|
||||
stderr.close
|
||||
end
|
||||
|
||||
def push_commits
|
||||
cmd = git_push_commands.join(' && ')
|
||||
stdin, stdout, stderr, wait_thr = Open3.popen3(cmd)
|
||||
|
||||
puts stdout.read.green
|
||||
puts stderr.read.red
|
||||
|
||||
puts new_merge_request_url.blue if wait_thr.value.success? && !@options[:merge_request]
|
||||
ensure
|
||||
stdin.close
|
||||
stdout.close
|
||||
stderr.close
|
||||
end
|
||||
|
||||
def git_pick_commands
|
||||
[
|
||||
fetch_stable_branch,
|
||||
create_backport_branch,
|
||||
cherry_pick_commit
|
||||
]
|
||||
end
|
||||
|
||||
def git_push_commands
|
||||
[
|
||||
push_to_remote,
|
||||
checkout_original_branch
|
||||
]
|
||||
end
|
||||
|
||||
def git_commands
|
||||
git_pick_commands + git_push_commands
|
||||
end
|
||||
|
||||
def fetch_stable_branch
|
||||
"git fetch #{@options[:remote]} #{stable_branch}"
|
||||
end
|
||||
|
||||
def create_backport_branch
|
||||
"git checkout -B #{source_branch} #{@options[:remote]}/#{stable_branch} --no-track"
|
||||
end
|
||||
|
||||
def cherry_pick_commit
|
||||
"git cherry-pick #{@options[:sha]}"
|
||||
end
|
||||
|
||||
def push_to_remote
|
||||
[
|
||||
"git push #{@options[:remote]} #{source_branch} --no-verify",
|
||||
*merge_request_push_options
|
||||
].join(' ')
|
||||
end
|
||||
|
||||
def checkout_original_branch
|
||||
"git checkout #{@options[:branch]}"
|
||||
end
|
||||
|
||||
def gitlab_params
|
||||
{
|
||||
issuable_template: @options[:merge_request_template],
|
||||
merge_request: {
|
||||
source_branch: source_branch,
|
||||
target_branch: stable_branch
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
def merge_request_push_options
|
||||
return [] unless @options[:merge_request]
|
||||
|
||||
[
|
||||
"-o mr.create",
|
||||
"-o mr.target='#{stable_branch}'",
|
||||
"-o mr.description='Please apply `#{@options[:merge_request_template]}` template.'",
|
||||
"-o mr.milestone='#{@options[:version].tr('-', '.')}'"
|
||||
]
|
||||
end
|
||||
|
||||
def source_branch
|
||||
branch = "#{@options[:branch]}-#{@options[:version]}"
|
||||
branch = "#{@options[:branch_prefix]}-#{branch}" unless branch.start_with?("#{@options[:branch_prefix]}-")
|
||||
branch
|
||||
end
|
||||
|
||||
def stable_branch
|
||||
"#{@options[:version]}-#{@options[:stable_branch_suffix]}-ee"
|
||||
end
|
||||
|
||||
def new_merge_request_url
|
||||
"#{@options[:new_merge_request_url]}?#{gitlab_params.to_query}"
|
||||
end
|
||||
end
|
||||
|
||||
Backport.new.create!
|
38
yarn.lock
38
yarn.lock
@ -1272,19 +1272,19 @@
|
||||
resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.12.1.tgz#cfc6cffe39df390a3841cde2abccf92eaa7ae0e0"
|
||||
integrity sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==
|
||||
|
||||
"@eslint/config-array@^0.20.1":
|
||||
version "0.20.1"
|
||||
resolved "https://registry.yarnpkg.com/@eslint/config-array/-/config-array-0.20.1.tgz#454f89be82b0e5b1ae872c154c7e2f3dd42c3979"
|
||||
integrity sha512-OL0RJzC/CBzli0DrrR31qzj6d6i6Mm3HByuhflhl4LOBiWxN+3i6/t/ZQQNii4tjksXi8r2CRW1wMpWA2ULUEw==
|
||||
"@eslint/config-array@^0.21.0":
|
||||
version "0.21.0"
|
||||
resolved "https://registry.yarnpkg.com/@eslint/config-array/-/config-array-0.21.0.tgz#abdbcbd16b124c638081766392a4d6b509f72636"
|
||||
integrity sha512-ENIdc4iLu0d93HeYirvKmrzshzofPw6VkZRKQGe9Nv46ZnWUzcF1xV01dcvEg/1wXUR61OmmlSfyeyO7EvjLxQ==
|
||||
dependencies:
|
||||
"@eslint/object-schema" "^2.1.6"
|
||||
debug "^4.3.1"
|
||||
minimatch "^3.1.2"
|
||||
|
||||
"@eslint/config-helpers@^0.2.1":
|
||||
version "0.2.1"
|
||||
resolved "https://registry.yarnpkg.com/@eslint/config-helpers/-/config-helpers-0.2.1.tgz#26042c028d1beee5ce2235a7929b91c52651646d"
|
||||
integrity sha512-RI17tsD2frtDu/3dmI7QRrD4bedNKPM08ziRYaC5AhkGrzIAJelm9kJU1TznK+apx6V+cqRz8tfpEeG3oIyjxw==
|
||||
"@eslint/config-helpers@^0.3.0":
|
||||
version "0.3.0"
|
||||
resolved "https://registry.yarnpkg.com/@eslint/config-helpers/-/config-helpers-0.3.0.tgz#3e09a90dfb87e0005c7694791e58e97077271286"
|
||||
integrity sha512-ViuymvFmcJi04qdZeDc2whTHryouGcDlaxPqarTD0ZE10ISpxGUVZGZDx4w01upyIynL3iu6IXH2bS1NhclQMw==
|
||||
|
||||
"@eslint/core@^0.14.0":
|
||||
version "0.14.0"
|
||||
@ -1315,10 +1315,10 @@
|
||||
minimatch "^3.1.2"
|
||||
strip-json-comments "^3.1.1"
|
||||
|
||||
"@eslint/js@9.29.0", "@eslint/js@^9.15.0":
|
||||
version "9.29.0"
|
||||
resolved "https://registry.yarnpkg.com/@eslint/js/-/js-9.29.0.tgz#dc6fd117c19825f8430867a662531da36320fe56"
|
||||
integrity sha512-3PIF4cBw/y+1u2EazflInpV+lYsSG0aByVIQzAgb1m1MhHFSbqTyNqtBKHgWf/9Ykud+DhILS9EGkmekVhbKoQ==
|
||||
"@eslint/js@9.30.0", "@eslint/js@^9.15.0":
|
||||
version "9.30.0"
|
||||
resolved "https://registry.yarnpkg.com/@eslint/js/-/js-9.30.0.tgz#c396fa450d5505dd9b7b8846b33f0491aebd9a2d"
|
||||
integrity sha512-Wzw3wQwPvc9sHM+NjakWTcPx11mbZyiYHuwWa/QfZ7cIRX7WK54PSk7bdyXDaoaopUcMatv1zaQvOAAO8hCdww==
|
||||
|
||||
"@eslint/object-schema@^2.1.6":
|
||||
version "2.1.6"
|
||||
@ -7511,18 +7511,18 @@ eslint-visitor-keys@^4.2.1:
|
||||
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz#4cfea60fe7dd0ad8e816e1ed026c1d5251b512c1"
|
||||
integrity sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==
|
||||
|
||||
eslint@9.29.0:
|
||||
version "9.29.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint/-/eslint-9.29.0.tgz#65e3db3b7e5a5b04a8af541741a0f3648d0a81a6"
|
||||
integrity sha512-GsGizj2Y1rCWDu6XoEekL3RLilp0voSePurjZIkxL3wlm5o5EC9VpgaP7lrCvjnkuLvzFBQWB3vWB3K5KQTveQ==
|
||||
eslint@9.30.0:
|
||||
version "9.30.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint/-/eslint-9.30.0.tgz#fb0c655f5e28fc1b2f4050c28efa1876d78034fc"
|
||||
integrity sha512-iN/SiPxmQu6EVkf+m1qpBxzUhE12YqFLOSySuOyVLJLEF9nzTf+h/1AJYc1JWzCnktggeNrjvQGLngDzXirU6g==
|
||||
dependencies:
|
||||
"@eslint-community/eslint-utils" "^4.2.0"
|
||||
"@eslint-community/regexpp" "^4.12.1"
|
||||
"@eslint/config-array" "^0.20.1"
|
||||
"@eslint/config-helpers" "^0.2.1"
|
||||
"@eslint/config-array" "^0.21.0"
|
||||
"@eslint/config-helpers" "^0.3.0"
|
||||
"@eslint/core" "^0.14.0"
|
||||
"@eslint/eslintrc" "^3.3.1"
|
||||
"@eslint/js" "9.29.0"
|
||||
"@eslint/js" "9.30.0"
|
||||
"@eslint/plugin-kit" "^0.3.1"
|
||||
"@humanfs/node" "^0.16.6"
|
||||
"@humanwhocodes/module-importer" "^1.0.1"
|
||||
|
Reference in New Issue
Block a user