diff --git a/.github/actionlint.yaml b/.github/actionlint.yaml index 9ddf78eba35105..97ba215778c25f 100644 --- a/.github/actionlint.yaml +++ b/.github/actionlint.yaml @@ -1,9 +1,6 @@ self-hosted-runner: # Labels of self-hosted runner in array of strings. - labels: - # TODO: technically not a self-hosted runner but avoids errors until a new - # version of actionlint is released. - - macos-14 + labels: [] # Configuration variables in array of strings defined in your repository or # organization. `null` means disabling configuration variables check. # Empty array means no configuration variable is allowed. diff --git a/.github/maintainers.json b/.github/maintainers.json index bdbf49624bbfae..94d81e5e7b743f 100644 --- a/.github/maintainers.json +++ b/.github/maintainers.json @@ -1 +1 @@ -["Moisan","timsutton","MikeMcQuaid","singingwolfboy","issyl0","dtrodrigues","dduugg","bayandin","Bo98","reitermarkus","SMillerDev","chenrui333","samford","fxcoudert","EricFromCanada","iMichka","alebcay","miccal","razvanazamfirei","branchvincent","gdams","cho-m","ZhongRuoyu","carlocab","Rylan12","nandahkrishna","krehel","bevanjkay","apainintheneck","p-linnane"] \ No newline at end of file +["Moisan","timsutton","MikeMcQuaid","singingwolfboy","issyl0","dtrodrigues","dduugg","bayandin","Bo98","reitermarkus","SMillerDev","chenrui333","samford","fxcoudert","EricFromCanada","iMichka","alebcay","miccal","razvanazamfirei","branchvincent","cho-m","ZhongRuoyu","carlocab","Rylan12","nandahkrishna","krehel","bevanjkay","apainintheneck","p-linnane"] \ No newline at end of file diff --git a/.github/workflows/sponsors-maintainers-man-completions.yml b/.github/workflows/sponsors-maintainers-man-completions.yml index e0af1f9d051197..bb84d5f7a2ea7c 100644 --- a/.github/workflows/sponsors-maintainers-man-completions.yml +++ b/.github/workflows/sponsors-maintainers-man-completions.yml @@ -3,7 +3,7 @@ name: Update sponsors, maintainers, manpage and completions on: push: branches: - - "**" + - master paths: - .github/workflows/sponsors-maintainers-man-completions.yml - README.md diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index cf4b4a360be9a9..1d8ec39031b6fb 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -108,7 +108,6 @@ jobs: - name: Set up all Homebrew taps run: | brew tap homebrew/aliases - brew tap homebrew/autoupdate brew tap homebrew/bundle brew tap homebrew/cask-fonts brew tap homebrew/cask-versions @@ -127,7 +126,6 @@ jobs: homebrew/test-bot brew style homebrew/aliases \ - homebrew/autoupdate\ homebrew/command-not-found \ homebrew/formula-analytics \ homebrew/portable-ruby diff --git a/.gitignore b/.gitignore index c4cc9d81b94291..8eb0cb3d451a54 100644 --- a/.gitignore +++ b/.gitignore @@ -5,7 +5,7 @@ .DS_Store # Unignore the contents of `Library` as that's where our code lives. -!/Library/ +!/Library # Ignore files within `Library` (again). /Library/Homebrew/.npmignore @@ -82,16 +82,15 @@ **/vendor/bundle/ruby/*/gems/erubi-*/ **/vendor/bundle/ruby/*/gems/hana-*/ **/vendor/bundle/ruby/*/gems/highline-*/ -**/vendor/bundle/ruby/*/gems/hpricot-*/ **/vendor/bundle/ruby/*/gems/jaro_winkler-*/ **/vendor/bundle/ruby/*/gems/json-*/ **/vendor/bundle/ruby/*/gems/json_schemer-*/ +**/vendor/bundle/ruby/*/gems/kramdown-*/ **/vendor/bundle/ruby/*/gems/language_server-protocol-*/ **/vendor/bundle/ruby/*/gems/method_source-*/ **/vendor/bundle/ruby/*/gems/mini_portile2-*/ **/vendor/bundle/ruby/*/gems/minitest-*/ **/vendor/bundle/ruby/*/gems/msgpack-*/ -**/vendor/bundle/ruby/*/gems/mustache-*/ **/vendor/bundle/ruby/*/gems/netrc-*/ **/vendor/bundle/ruby/*/gems/ntlm-http-*/ **/vendor/bundle/ruby/*/gems/parallel-*/ @@ -106,10 +105,8 @@ **/vendor/bundle/ruby/*/gems/racc-*/ **/vendor/bundle/ruby/*/gems/rainbow-*/ **/vendor/bundle/ruby/*/gems/rbi-*/ -**/vendor/bundle/ruby/*/gems/rdiscount-*/ **/vendor/bundle/ruby/*/gems/regexp_parser-*/ **/vendor/bundle/ruby/*/gems/rexml-*/ -**/vendor/bundle/ruby/*/gems/ronn-*/ **/vendor/bundle/ruby/*/gems/rspec-*/ **/vendor/bundle/ruby/*/gems/rspec-core-*/ **/vendor/bundle/ruby/*/gems/rspec-expectations-*/ diff --git a/Library/.rubocop.yml b/Library/.rubocop.yml index eb3ee74832ac73..3b98089c10f7f4 100644 --- a/Library/.rubocop.yml +++ b/Library/.rubocop.yml @@ -366,9 +366,6 @@ Style/HashAsLastArrayItem: - "/**/Formula/**/*.rb" - "**/Formula/**/*.rb" -Style/HashSyntax: - EnforcedShorthandSyntax: either - Style/InverseMethods: InverseMethods: :blank?: :present? diff --git a/Library/Homebrew/Gemfile b/Library/Homebrew/Gemfile index 01d1fb91c4a5bf..fb1e87df969956 100644 --- a/Library/Homebrew/Gemfile +++ b/Library/Homebrew/Gemfile @@ -28,7 +28,7 @@ group :livecheck, optional: true do gem "ruby-progressbar", require: false end group :man, optional: true do - gem "ronn", require: false + gem "kramdown", require: false end group :pr_upload, optional: true do gem "json_schemer", require: false diff --git a/Library/Homebrew/Gemfile.lock b/Library/Homebrew/Gemfile.lock index 9ff4c6df6bb5ff..776e8726c7f4ae 100644 --- a/Library/Homebrew/Gemfile.lock +++ b/Library/Homebrew/Gemfile.lock @@ -18,20 +18,20 @@ GEM erubi (1.12.0) hana (1.3.7) highline (2.0.3) - hpricot (0.8.6) json (2.7.1) json_schemer (2.1.1) hana (~> 1.3) regexp_parser (~> 2.0) simpleidn (~> 0.2) + kramdown (2.4.0) + rexml language_server-protocol (3.17.0.3) method_source (1.0.0) - minitest (5.22.2) + minitest (5.22.3) msgpack (1.7.2) - mustache (1.1.1) netrc (0.11.0) parallel (1.24.0) - parallel_tests (4.5.1) + parallel_tests (4.5.2) parallel parlour (8.1.0) commander (~> 4.5) @@ -55,13 +55,8 @@ GEM rbi (0.1.9) prism (>= 0.18.0, < 0.25) sorbet-runtime (>= 0.5.9204) - rdiscount (2.2.7.3) regexp_parser (2.9.0) rexml (3.2.6) - ronn (0.7.3) - hpricot (>= 0.8.2) - mustache (>= 0.7.0) - rdiscount (>= 1.5.8) rspec (3.13.0) rspec-core (~> 3.13.0) rspec-expectations (~> 3.13.0) @@ -86,7 +81,7 @@ GEM rspec-support (3.13.1) rspec_junit_formatter (0.6.0) rspec-core (>= 2, < 4, != 2.12.0) - rubocop (1.61.0) + rubocop (1.62.1) json (~> 2.3) language_server-protocol (>= 3.17.0) parallel (~> 1.10) @@ -94,10 +89,10 @@ GEM rainbow (>= 2.2.2, < 4.0) regexp_parser (>= 1.8, < 3.0) rexml (>= 3.2.5, < 4.0) - rubocop-ast (>= 1.30.0, < 2.0) + rubocop-ast (>= 1.31.1, < 2.0) ruby-progressbar (~> 1.7) unicode-display_width (>= 2.4.0, < 3.0) - rubocop-ast (1.31.1) + rubocop-ast (1.31.2) parser (>= 3.3.0.4) rubocop-capybara (2.20.0) rubocop (~> 1.41) @@ -108,11 +103,11 @@ GEM rubocop-performance (1.20.2) rubocop (>= 1.48.1, < 2.0) rubocop-ast (>= 1.30.0, < 2.0) - rubocop-rspec (2.26.1) + rubocop-rspec (2.27.1) rubocop (~> 1.40) rubocop-capybara (~> 2.17) rubocop-factory_bot (~> 2.22) - rubocop-sorbet (0.7.7) + rubocop-sorbet (0.7.8) rubocop (>= 0.90.0) ruby-macho (4.0.1) ruby-prof (1.7.0) @@ -128,15 +123,15 @@ GEM simplecov_json_formatter (0.1.4) simpleidn (0.2.1) unf (~> 0.1.4) - sorbet (0.5.11276) - sorbet-static (= 0.5.11276) - sorbet-runtime (0.5.11276) - sorbet-static (0.5.11276-aarch64-linux) - sorbet-static (0.5.11276-universal-darwin) - sorbet-static (0.5.11276-x86_64-linux) - sorbet-static-and-runtime (0.5.11276) - sorbet (= 0.5.11276) - sorbet-runtime (= 0.5.11276) + sorbet (0.5.11294) + sorbet-static (= 0.5.11294) + sorbet-runtime (0.5.11294) + sorbet-static (0.5.11294-aarch64-linux) + sorbet-static (0.5.11294-universal-darwin) + sorbet-static (0.5.11294-x86_64-linux) + sorbet-static-and-runtime (0.5.11294) + sorbet (= 0.5.11294) + sorbet-runtime (= 0.5.11294) spoom (1.2.4) erubi (>= 1.10.0) sorbet-static-and-runtime (>= 0.5.10187) @@ -177,6 +172,7 @@ DEPENDENCIES bootsnap byebug json_schemer + kramdown method_source minitest parallel_tests @@ -185,7 +181,6 @@ DEPENDENCIES plist pry rexml - ronn rspec rspec-github rspec-its diff --git a/Library/Homebrew/PATH.rb b/Library/Homebrew/PATH.rb index 5730b2a11f6bdc..16759a1b562e9f 100644 --- a/Library/Homebrew/PATH.rb +++ b/Library/Homebrew/PATH.rb @@ -77,7 +77,7 @@ def empty? sig { returns(T.nilable(T.self_type)) } def existing - existing_path = select(&File.method(:directory?)) + existing_path = select { File.directory?(_1) } # return nil instead of empty PATH, to unset environment variables existing_path unless existing_path.empty? end diff --git a/Library/Homebrew/api.rb b/Library/Homebrew/api.rb index 1f194c59564a39..2599bb40f3d5c6 100644 --- a/Library/Homebrew/api.rb +++ b/Library/Homebrew/api.rb @@ -95,7 +95,7 @@ def self.fetch_json_api_file(endpoint, target: HOMEBREW_CACHE_API/endpoint, end mtime = insecure_download ? Time.new(1970, 1, 1) : Time.now - FileUtils.touch(target, mtime: mtime) unless skip_download + FileUtils.touch(target, mtime:) unless skip_download JSON.parse(target.read, freeze: true) rescue JSON::ParserError target.unlink diff --git a/Library/Homebrew/api/cask.rb b/Library/Homebrew/api/cask.rb index 8e06edc840b573..d70f6da2e17d9c 100644 --- a/Library/Homebrew/api/cask.rb +++ b/Library/Homebrew/api/cask.rb @@ -83,7 +83,7 @@ def self.all_renames def self.write_names(regenerate: false) download_and_cache_data! unless cache.key?("casks") - Homebrew::API.write_names_file(all_casks.keys, "cask", regenerate: regenerate) + Homebrew::API.write_names_file(all_casks.keys, "cask", regenerate:) end end end diff --git a/Library/Homebrew/api/formula.rb b/Library/Homebrew/api/formula.rb index d27e963eff5b4c..5cda1457537fd0 100644 --- a/Library/Homebrew/api/formula.rb +++ b/Library/Homebrew/api/formula.rb @@ -119,7 +119,7 @@ def self.tap_git_head def self.write_names_and_aliases(regenerate: false) download_and_cache_data! unless cache.key?("formulae") - return unless Homebrew::API.write_names_file(all_formulae.keys, "formula", regenerate: regenerate) + return unless Homebrew::API.write_names_file(all_formulae.keys, "formula", regenerate:) (HOMEBREW_CACHE_API/"formula_aliases.txt").open("w") do |file| all_aliases.each do |alias_name, real_name| diff --git a/Library/Homebrew/brew.rb b/Library/Homebrew/brew.rb index 78b51cb55ce844..c50bf61ab53c91 100644 --- a/Library/Homebrew/brew.rb +++ b/Library/Homebrew/brew.rb @@ -78,7 +78,7 @@ # - no arguments are passed if empty_argv || help_flag require "help" - Homebrew::Help.help cmd, remaining_args: args.remaining, empty_argv: empty_argv + Homebrew::Help.help cmd, remaining_args: args.remaining, empty_argv: # `Homebrew::Help.help` never returns, except for unknown commands. end @@ -133,14 +133,14 @@ Homebrew::Help.help cmd, remaining_args: args.remaining, usage_error: e.message rescue SystemExit => e onoe "Kernel.exit" if args.debug? && !e.success? - $stderr.puts Utils::Backtrace.clean(e) if args.debug? + $stderr.puts Utils::Backtrace.clean(e) if args&.debug? || ARGV.include?("--debug") raise rescue Interrupt $stderr.puts # seemingly a newline is typical exit 130 rescue BuildError => e Utils::Analytics.report_build_error(e) - e.dump(verbose: args.verbose?) + e.dump(verbose: args&.verbose?) if e.formula.head? || e.formula.deprecated? || e.formula.disabled? reason = if e.formula.head? @@ -167,7 +167,7 @@ raise if e.message.empty? onoe e - $stderr.puts Utils::Backtrace.clean(e) if args.debug? + $stderr.puts Utils::Backtrace.clean(e) if args&.debug? || ARGV.include?("--debug") exit 1 rescue MethodDeprecatedError => e @@ -176,7 +176,7 @@ $stderr.puts "If reporting this issue please do so at (not Homebrew/brew or Homebrew/homebrew-core):" $stderr.puts " #{Formatter.url(e.issues_url)}" end - $stderr.puts Utils::Backtrace.clean(e) if args.debug? + $stderr.puts Utils::Backtrace.clean(e) if args&.debug? || ARGV.include?("--debug") exit 1 rescue Exception => e # rubocop:disable Lint/RescueException onoe e diff --git a/Library/Homebrew/brew.sh b/Library/Homebrew/brew.sh index 9fb8818f5fb4f2..ff60dca83f34d2 100644 --- a/Library/Homebrew/brew.sh +++ b/Library/Homebrew/brew.sh @@ -262,22 +262,6 @@ check-array-membership() { fi } -# Let user know we're still updating Homebrew if brew update --auto-update -# exceeds 3 seconds. -auto-update-timer() { - sleep 3 - # Outputting a command but don't want to run it, hence single quotes. - # shellcheck disable=SC2016 - echo 'Running `brew update --auto-update`...' >&2 - if [[ -z "${HOMEBREW_NO_ENV_HINTS}" && -z "${HOMEBREW_AUTO_UPDATE_SECS}" ]] - then - # shellcheck disable=SC2016 - echo 'Adjust how often this is run with HOMEBREW_AUTO_UPDATE_SECS or disable with' >&2 - # shellcheck disable=SC2016 - echo 'HOMEBREW_NO_AUTO_UPDATE. Hide these hints with HOMEBREW_NO_ENV_HINTS (see `man brew`).' >&2 - fi -} - # These variables are set from various Homebrew scripts. # shellcheck disable=SC2154 auto-update() { @@ -339,20 +323,8 @@ auto-update() { return fi - if [[ -z "${HOMEBREW_VERBOSE}" ]] - then - auto-update-timer & - timer_pid=$! - fi - brew update --auto-update - if [[ -n "${timer_pid}" ]] - then - kill "${timer_pid}" 2>/dev/null - wait "${timer_pid}" 2>/dev/null - fi - unset HOMEBREW_AUTO_UPDATING # Restore user path as it'll be refiltered by HOMEBREW_BREW_FILE (bin/brew) @@ -866,7 +838,8 @@ if check-array-membership "${HOMEBREW_COMMAND}" "${AUTO_UPDATE_CORE_TAP_COMMANDS then export HOMEBREW_AUTO_UPDATE_COMMAND="1" export HOMEBREW_AUTO_UPDATE_CORE_TAP="1" -else +elif [[ -z "${HOMEBREW_AUTO_UPDATING}" ]] +then unset HOMEBREW_AUTO_UPDATE_CORE_TAP fi @@ -880,8 +853,9 @@ if check-array-membership "${HOMEBREW_COMMAND}" "${AUTO_UPDATE_CASK_TAP_COMMANDS then export HOMEBREW_AUTO_UPDATE_COMMAND="1" export HOMEBREW_AUTO_UPDATE_CASK_TAP="1" -else - unset HOMEBREW_AUTO_UPDATE_CORE_TAP +elif [[ -z "${HOMEBREW_AUTO_UPDATING}" ]] +then + unset HOMEBREW_AUTO_UPDATE_CASK_TAP fi # Disable Ruby options we don't need. diff --git a/Library/Homebrew/build.rb b/Library/Homebrew/build.rb index bc2c8a52b1ff00..663b2f04b535a7 100644 --- a/Library/Homebrew/build.rb +++ b/Library/Homebrew/build.rb @@ -80,7 +80,7 @@ def install ENV.deps = formula_deps ENV.run_time_deps = run_time_deps ENV.setup_build_environment( - formula: formula, + formula:, cc: args.cc, build_bottle: args.build_bottle?, bottle_arch: args.bottle_arch, @@ -93,7 +93,7 @@ def install end else ENV.setup_build_environment( - formula: formula, + formula:, cc: args.cc, build_bottle: args.build_bottle?, bottle_arch: args.bottle_arch, @@ -139,12 +139,14 @@ def install with_env( # For head builds, HOMEBREW_FORMULA_PREFIX should include the commit, # which is not known until after the formula has been staged. - HOMEBREW_FORMULA_PREFIX: formula.prefix, + HOMEBREW_FORMULA_PREFIX: formula.prefix, + # https://reproducible-builds.org/docs/build-path/ + HOMEBREW_FORMULA_BUILDPATH: formula.buildpath, # https://reproducible-builds.org/docs/source-date-epoch/ - SOURCE_DATE_EPOCH: formula.source_modified_time.to_i.to_s, + SOURCE_DATE_EPOCH: formula.source_modified_time.to_i.to_s, # Avoid make getting confused about timestamps. # https://github.com/Homebrew/homebrew-core/pull/87470 - TZ: "UTC0", + TZ: "UTC0", ) do formula.patch @@ -225,7 +227,7 @@ def fixopt(formula) formula = args.named.to_formulae.first options = Options.create(args.flags_only) - build = Build.new(formula, options, args: args) + build = Build.new(formula, options, args:) build.install rescue Exception => e # rubocop:disable Lint/RescueException error_hash = JSON.parse e.to_json diff --git a/Library/Homebrew/cask/artifact/abstract_uninstall.rb b/Library/Homebrew/cask/artifact/abstract_uninstall.rb index 66a6f2dabc454a..2caff1b700b938 100644 --- a/Library/Homebrew/cask/artifact/abstract_uninstall.rb +++ b/Library/Homebrew/cask/artifact/abstract_uninstall.rb @@ -113,7 +113,7 @@ def uninstall_launchctl(*services, command: nil, **_) plist_status = command.run( "/bin/launchctl", args: ["list", service], - sudo: sudo, + sudo:, sudo_as_root: sudo, print_stderr: false, ).stdout @@ -121,7 +121,7 @@ def uninstall_launchctl(*services, command: nil, **_) command.run!( "/bin/launchctl", args: ["remove", service], - sudo: sudo, + sudo:, sudo_as_root: sudo, ) sleep 1 @@ -133,7 +133,7 @@ def uninstall_launchctl(*services, command: nil, **_) paths.each { |elt| elt.prepend(Dir.home).freeze } unless sudo paths = paths.map { |elt| Pathname(elt) }.select(&:exist?) paths.each do |path| - command.run!("/bin/rm", args: ["-f", "--", path], sudo: sudo, sudo_as_root: sudo) + command.run!("/bin/rm", args: ["-f", "--", path], sudo:, sudo_as_root: sudo) end # undocumented and untested: pass a path to uninstall :launchctl next unless Pathname(service).exist? @@ -141,13 +141,13 @@ def uninstall_launchctl(*services, command: nil, **_) command.run!( "/bin/launchctl", args: ["unload", "-w", "--", service], - sudo: sudo, + sudo:, sudo_as_root: sudo, ) command.run!( "/bin/rm", args: ["-f", "--", service], - sudo: sudo, + sudo:, sudo_as_root: sudo, ) sleep 1 @@ -511,13 +511,13 @@ def recursive_rmdir(*directories, command: nil, **_) # Directory counts as empty if it only contains a `.DS_Store`. if children.include?(ds_store = resolved_path/".DS_Store") - Utils.gain_permissions_remove(ds_store, command: command) + Utils.gain_permissions_remove(ds_store, command:) children.delete(ds_store) end - next false unless recursive_rmdir(*children, command: command) + next false unless recursive_rmdir(*children, command:) - Utils.gain_permissions_rmdir(resolved_path, command: command) + Utils.gain_permissions_rmdir(resolved_path, command:) true end diff --git a/Library/Homebrew/cask/artifact/artifact.rb b/Library/Homebrew/cask/artifact/artifact.rb index c1d2f306b090d3..9472fec95e7a3b 100644 --- a/Library/Homebrew/cask/artifact/artifact.rb +++ b/Library/Homebrew/cask/artifact/artifact.rb @@ -31,11 +31,6 @@ def self.from_args(cask, *args) def resolve_target(target) super(target, base_dir: nil) end - - sig { params(cask: Cask, source: T.any(String, Pathname), target: T.any(String, Pathname)).void } - def initialize(cask, source, target:) - super(cask, source, target: target) - end end end end diff --git a/Library/Homebrew/cask/artifact/binary.rb b/Library/Homebrew/cask/artifact/binary.rb index a8c7d55450a626..16bbfe84248324 100644 --- a/Library/Homebrew/cask/artifact/binary.rb +++ b/Library/Homebrew/cask/artifact/binary.rb @@ -10,7 +10,7 @@ module Artifact # @api private class Binary < Symlinked def link(command: nil, **options) - super(command: command, **options) + super(command:, **options) return if source.executable? if source.writable? diff --git a/Library/Homebrew/cask/artifact/installer.rb b/Library/Homebrew/cask/artifact/installer.rb index 810a48b9f784d8..040045c80302b1 100644 --- a/Library/Homebrew/cask/artifact/installer.rb +++ b/Library/Homebrew/cask/artifact/installer.rb @@ -94,7 +94,7 @@ def summarize end def to_h - { path: path }.tap do |h| + { path: }.tap do |h| h[:args] = args unless is_a?(ManualInstaller) end end diff --git a/Library/Homebrew/cask/artifact/moved.rb b/Library/Homebrew/cask/artifact/moved.rb index a9e3470d7cdf19..3709c84615feae 100644 --- a/Library/Homebrew/cask/artifact/moved.rb +++ b/Library/Homebrew/cask/artifact/moved.rb @@ -46,18 +46,40 @@ def move(adopt: false, force: false, verbose: false, predecessor: nil, reinstall if target.parent.writable? && !force target.rmdir else - Utils.gain_permissions_remove(target, command: command) + Utils.gain_permissions_remove(target, command:) end end else if adopt ohai "Adopting existing #{self.class.english_name} at '#{target}'" - same = command.run( - "/usr/bin/diff", - args: ["--recursive", "--brief", source, target], - verbose: verbose, - print_stdout: verbose, - ).success? + + source_plist = Pathname("#{source}/Contents/Info.plist") + target_plist = Pathname("#{target}/Contents/Info.plist") + same = if source_plist.size? && + (source_bundle_version = Homebrew::BundleVersion.from_info_plist(source_plist)) && + target_plist.size? && + (target_bundle_version = Homebrew::BundleVersion.from_info_plist(target_plist)) + if source_bundle_version.short_version == target_bundle_version.short_version + if source_bundle_version.version == target_bundle_version.version + true + else + onoe "The bundle version of #{source} is #{source_bundle_version.version} but " \ + "is #{target_bundle_version.version} for #{target}!" + false + end + else + onoe "The bundle short version of #{source} is #{source_bundle_version.short_version} but " \ + "is #{target_bundle_version.short_version} for #{target}!" + false + end + else + command.run( + "/usr/bin/diff", + args: ["--recursive", "--brief", source, target], + verbose:, + print_stdout: verbose, + ).success? + end unless same raise CaskError, @@ -73,25 +95,25 @@ def move(adopt: false, force: false, verbose: false, predecessor: nil, reinstall message = "It seems there is already #{self.class.english_article} " \ "#{self.class.english_name} at '#{target}'" - raise CaskError, "#{message}." unless force + raise CaskError, "#{message}." if !force && !adopt opoo "#{message}; overwriting." - delete(target, force: force, command: command, **options) + delete(target, force:, command:, **options) end end ohai "Moving #{self.class.english_name} '#{source.basename}' to '#{target}'" - Utils.gain_permissions_mkpath(target.dirname, command: command) unless target.dirname.exist? + Utils.gain_permissions_mkpath(target.dirname, command:) unless target.dirname.exist? - if target.directory? && Quarantine.app_management_permissions_granted?(app: target, command: command) + if target.directory? && Quarantine.app_management_permissions_granted?(app: target, command:) if target.writable? source.children.each { |child| FileUtils.move(child, target/child.basename) } else command.run!("/bin/cp", args: ["-pR", *source.children, target], sudo: true) end - Quarantine.copy_xattrs(source, target, command: command) + Quarantine.copy_xattrs(source, target, command:) source.rmtree elsif target.dirname.writable? FileUtils.move(source, target) @@ -109,7 +131,7 @@ def move(adopt: false, force: false, verbose: false, predecessor: nil, reinstall def post_move(command) FileUtils.ln_sf target, source - add_altname_metadata(target, source.basename, command: command) + add_altname_metadata(target, source.basename, command:) end def matching_artifact?(cask) @@ -120,16 +142,16 @@ def matching_artifact?(cask) end end - def move_back(skip: false, force: false, command: nil, **options) + def move_back(skip: false, force: false, adopt: false, command: nil, **options) FileUtils.rm source if source.symlink? && source.dirname.join(source.readlink) == target if Utils.path_occupied?(source) message = "It seems there is already #{self.class.english_article} " \ "#{self.class.english_name} at '#{source}'" - raise CaskError, "#{message}." unless force + raise CaskError, "#{message}." if !force && !adopt opoo "#{message}; overwriting." - delete(source, force: force, command: command, **options) + delete(source, force:, command:, **options) end unless target.exist? @@ -144,7 +166,7 @@ def move_back(skip: false, force: false, command: nil, **options) # We need to preserve extended attributes between copies. command.run!("/bin/cp", args: ["-pR", target, source], sudo: !source.parent.writable?) - delete(target, force: force, command: command, **options) + delete(target, force:, command:, **options) end def delete(target, force: false, successor: nil, command: nil, **_) @@ -154,7 +176,7 @@ def delete(target, force: false, successor: nil, command: nil, **_) return unless Utils.path_occupied?(target) if target.directory? && matching_artifact?(successor) && Quarantine.app_management_permissions_granted?( - app: target, command: command, + app: target, command:, ) # If an app folder is deleted, macOS considers the app uninstalled and removes some data. # Remove only the contents to handle this case. @@ -162,13 +184,13 @@ def delete(target, force: false, successor: nil, command: nil, **_) if target.writable? && !force child.rmtree else - Utils.gain_permissions_remove(child, command: command) + Utils.gain_permissions_remove(child, command:) end end elsif target.parent.writable? && !force target.rmtree else - Utils.gain_permissions_remove(target, command: command) + Utils.gain_permissions_remove(target, command:) end end end diff --git a/Library/Homebrew/cask/artifact/pkg.rb b/Library/Homebrew/cask/artifact/pkg.rb index 5bf94b6ee65256..0df431932fe1ef 100644 --- a/Library/Homebrew/cask/artifact/pkg.rb +++ b/Library/Homebrew/cask/artifact/pkg.rb @@ -66,9 +66,9 @@ def run_installer(command: nil, verbose: false, **_options) "/usr/sbin/installer", sudo: true, sudo_as_root: true, - args: args, + args:, print_stdout: true, - env: env, + env:, ) end end diff --git a/Library/Homebrew/cask/artifact/symlinked.rb b/Library/Homebrew/cask/artifact/symlinked.rb index 0d65a40e3a8908..1f5199d8876229 100644 --- a/Library/Homebrew/cask/artifact/symlinked.rb +++ b/Library/Homebrew/cask/artifact/symlinked.rb @@ -43,7 +43,7 @@ def summarize_installed private - def link(force: false, command: nil, **_options) + def link(force: false, adopt: false, command: nil, **_options) unless source.exist? raise CaskError, "It seems the #{self.class.link_type_english_name.downcase} " \ @@ -54,33 +54,33 @@ def link(force: false, command: nil, **_options) message = "It seems there is already #{self.class.english_article} " \ "#{self.class.english_name} at '#{target}'" - if force && target.symlink? && + if (force || adopt) && target.symlink? && (target.realpath == source.realpath || target.realpath.to_s.start_with?("#{cask.caskroom_path}/")) opoo "#{message}; overwriting." - Utils.gain_permissions_remove(target, command: command) + Utils.gain_permissions_remove(target, command:) else raise CaskError, "#{message}." end end ohai "Linking #{self.class.english_name} '#{source.basename}' to '#{target}'" - create_filesystem_link(command: command) + create_filesystem_link(command:) end def unlink(command: nil, **) return unless target.symlink? ohai "Unlinking #{self.class.english_name} '#{target}'" - Utils.gain_permissions_remove(target, command: command) + Utils.gain_permissions_remove(target, command:) end def create_filesystem_link(command: nil) - Utils.gain_permissions_mkpath(target.dirname, command: command) + Utils.gain_permissions_mkpath(target.dirname, command:) command.run! "/bin/ln", args: ["-h", "-f", "-s", "--", source, target], sudo: !target.dirname.writable? - add_altname_metadata(source, target.basename, command: command) + add_altname_metadata(source, target.basename, command:) end end end diff --git a/Library/Homebrew/cask/audit.rb b/Library/Homebrew/cask/audit.rb index d154e91107b145..f2805902ef0f6a 100644 --- a/Library/Homebrew/cask/audit.rb +++ b/Library/Homebrew/cask/audit.rb @@ -41,7 +41,7 @@ def initialize( download = online || signing if download.nil? @cask = cask - @download = Download.new(cask, quarantine: quarantine) if download + @download = Download.new(cask, quarantine:) if download @online = online @strict = strict @signing = signing @@ -95,7 +95,7 @@ def add_error(message, location: nil, strict_only: false) # Only raise non-critical audits if the user specified `--strict`. return if strict_only && !@strict - errors << ({ message: message, location: location, corrected: false }) + errors << ({ message:, location:, corrected: false }) end def result @@ -407,17 +407,20 @@ def audit_token_valid add_error "cask token contains non-ascii characters" unless cask.token.ascii_only? add_error "cask token + should be replaced by -plus-" if cask.token.include? "+" add_error "cask token whitespace should be replaced by hyphens" if cask.token.include? " " - add_error "cask token @ should be replaced by -at-" if cask.token.include? "@" add_error "cask token underscores should be replaced by hyphens" if cask.token.include? "_" add_error "cask token should not contain double hyphens" if cask.token.include? "--" - if cask.token.match?(/[^a-z0-9-]/) - add_error "cask token should only contain lowercase alphanumeric characters and hyphens" + if cask.token.match?(/[^@a-z0-9-]/) + add_error "cask token should only contain lowercase alphanumeric characters, hyphens and @" end - return if !cask.token.start_with?("-") && !cask.token.end_with?("-") + if cask.token.start_with?("-", "@") || cask.token.end_with?("-", "@") + add_error "cask token should not have leading or trailing hyphens and/or @" + end - add_error "cask token should not have leading or trailing hyphens" + add_error "cask token @ unrelated to versioning should be replaced by -at-" if cask.token.count("@") > 1 + add_error "cask token should not contain a hyphen followed by @" if cask.token.include? "-@" + add_error "cask token should not contain @ followed by a hyphen" if cask.token.include? "@-" end sig { void } @@ -663,7 +666,7 @@ def audit_github_prerelease_version tag = SharedAudits.github_tag_from_url(cask.url) tag ||= cask.version - error = SharedAudits.github_release(user, repo, tag, cask: cask) + error = SharedAudits.github_release(user, repo, tag, cask:) add_error error, location: cask.url.location if error end @@ -678,7 +681,7 @@ def audit_gitlab_prerelease_version tag = SharedAudits.gitlab_tag_from_url(cask.url) tag ||= cask.version - error = SharedAudits.gitlab_release(user, repo, tag, cask: cask) + error = SharedAudits.gitlab_release(user, repo, tag, cask:) add_error error, location: cask.url.location if error end @@ -783,7 +786,7 @@ def audit_homepage_https_availability validate_url_for_https_availability( homepage, SharedAudits::URL_TYPE_HOMEPAGE, - user_agents: user_agents, + user_agents:, check_content: true, strict: strict? ) @@ -843,7 +846,7 @@ def validate_url_for_https_availability(url_to_check, url_type, location: nil, * add_error problem, location: location unless exception elsif exception add_error "#{url_to_check} is in the secure connection audit skiplist but does not need to be skipped", - location: location + location: end end diff --git a/Library/Homebrew/cask/auditor.rb b/Library/Homebrew/cask/auditor.rb index ae7457ec63b966..1485429020c7e4 100644 --- a/Library/Homebrew/cask/auditor.rb +++ b/Library/Homebrew/cask/auditor.rb @@ -86,7 +86,7 @@ def output_summary?(audit = nil) def audit_languages(languages) original_config = cask.config - localized_config = original_config.merge(Config.new(explicit: { languages: languages })) + localized_config = original_config.merge(Config.new(explicit: { languages: })) cask.config = localized_config audit_cask_instance(cask) diff --git a/Library/Homebrew/cask/cask.rb b/Library/Homebrew/cask/cask.rb index fc76d85389b867..8c0870c4ecee15 100644 --- a/Library/Homebrew/cask/cask.rb +++ b/Library/Homebrew/cask/cask.rb @@ -2,6 +2,7 @@ # frozen_string_literal: true require "attrable" +require "bundle_version" require "cask/cask_loader" require "cask/config" require "cask/dsl" @@ -86,7 +87,7 @@ def initialize(token, sourcefile_path: nil, source: nil, tap: nil, loaded_from_a sig { returns(T::Array[String]) } def old_tokens @old_tokens ||= if (tap = self.tap) - Tap.reverse_tap_migrations_renames.fetch("#{tap}/#{token}", []) + + Tap.tap_migration_oldnames(tap, token) + tap.cask_reverse_renames.fetch(token, []) else [] @@ -115,7 +116,7 @@ def refresh def timestamped_versions(caskroom_path: self.caskroom_path) relative_paths = Pathname.glob(metadata_timestamped_path( version: "*", timestamp: "*", - caskroom_path: caskroom_path + caskroom_path: )) .map { |p| p.relative_path_from(p.parent.parent) } # Sorbet is unaware that Pathname is sortable: https://github.com/sorbet/sorbet/issues/6844 @@ -176,8 +177,20 @@ def installed_caskfile sig { returns(T.nilable(String)) } def installed_version + return unless (installed_caskfile = self.installed_caskfile) + # /.metadata///Casks/.{rb,json} -> - installed_caskfile&.dirname&.dirname&.dirname&.basename&.to_s + installed_caskfile.dirname.dirname.dirname.basename.to_s + end + + sig { returns(T.nilable(String)) } + def bundle_short_version + bundle_version&.short_version + end + + sig { returns(T.nilable(String)) } + def bundle_long_version + bundle_version&.version end def config_path @@ -214,8 +227,8 @@ def caskroom_path end def outdated?(greedy: false, greedy_latest: false, greedy_auto_updates: false) - !outdated_version(greedy: greedy, greedy_latest: greedy_latest, - greedy_auto_updates: greedy_auto_updates).nil? + !outdated_version(greedy:, greedy_latest:, + greedy_auto_updates:).nil? end def outdated_version(greedy: false, greedy_latest: false, greedy_auto_updates: false) @@ -239,8 +252,8 @@ def outdated_version(greedy: false, greedy_latest: false, greedy_auto_updates: f def outdated_info(greedy, verbose, json, greedy_latest, greedy_auto_updates) return token if !verbose && !json - installed_version = outdated_version(greedy: greedy, greedy_latest: greedy_latest, - greedy_auto_updates: greedy_auto_updates).to_s + installed_version = outdated_version(greedy:, greedy_latest:, + greedy_auto_updates:).to_s if json { @@ -264,7 +277,7 @@ def ruby_source_path def ruby_source_checksum @ruby_source_checksum ||= { - "sha256" => Digest::SHA256.file(sourcefile_path).hexdigest, + sha256: Digest::SHA256.file(sourcefile_path).hexdigest, }.freeze end @@ -283,7 +296,11 @@ def populate_from_api!(json_cask) @tap_git_head = json_cask.fetch(:tap_git_head, "HEAD") @ruby_source_path = json_cask[:ruby_source_path] - @ruby_source_checksum = json_cask[:ruby_source_checksum].freeze + + # TODO: Clean this up when we deprecate the current JSON API and move to the internal JSON v3. + ruby_source_sha256 = json_cask.dig(:ruby_source_checksum, :sha256) + ruby_source_sha256 ||= json_cask[:ruby_source_sha256] + @ruby_source_checksum = { "sha256" => ruby_source_sha256 } end def to_s @@ -304,14 +321,6 @@ def eql?(other) alias == eql? def to_h - url_specs = url&.specs.dup - case url_specs&.dig(:user_agent) - when :default - url_specs.delete(:user_agent) - when Symbol - url_specs[:user_agent] = ":#{url_specs[:user_agent]}" - end - { "token" => token, "full_token" => full_name, @@ -326,6 +335,8 @@ def to_h "version" => version, "installed" => installed_version, "installed_time" => install_time&.to_i, + "bundle_version" => bundle_long_version, + "bundle_short_version" => bundle_short_version, "outdated" => outdated?, "sha256" => sha256, "artifacts" => artifacts_list, @@ -347,27 +358,76 @@ def to_h } end - def to_hash_with_variations - if loaded_from_api? && !Homebrew::EnvConfig.no_install_from_api? - return api_to_local_hash(Homebrew::API::Cask.all_casks[token].dup) + # @private + def to_internal_api_hash + api_hash = { + "token" => token, + "name" => name, + "desc" => desc, + "homepage" => homepage, + "url" => url, + "version" => version, + "sha256" => sha256, + "artifacts" => artifacts_list(compact: true), + "ruby_source_path" => ruby_source_path, + "ruby_source_sha256" => ruby_source_checksum.fetch(:sha256), + } + + if deprecation_date + api_hash["deprecation_date"] = deprecation_date + api_hash["deprecation_reason"] = deprecation_reason end - hash = to_h - variations = {} + if disable_date + api_hash["disable_date"] = disable_date + api_hash["disable_reason"] = disable_reason + end + + if (url_specs_hash = url_specs).present? + api_hash["url_specs"] = url_specs_hash + end - hash_keys_to_skip = %w[outdated installed versions] + api_hash["caskfile_only"] = true if caskfile_only? + api_hash["conflicts_with"] = conflicts_with if conflicts_with.present? + api_hash["depends_on"] = depends_on if depends_on.present? + api_hash["container"] = container.pairs if container + api_hash["caveats"] = caveats if caveats.present? + api_hash["auto_updates"] = auto_updates if auto_updates + api_hash["languages"] = languages if languages.present? + + api_hash + end + + HASH_KEYS_TO_SKIP = %w[outdated installed versions].freeze + private_constant :HASH_KEYS_TO_SKIP + + # @private + def to_hash_with_variations(hash_method: :to_h) + case hash_method + when :to_h + if loaded_from_api? && !Homebrew::EnvConfig.no_install_from_api? + return api_to_local_hash(Homebrew::API::Cask.all_casks[token].dup) + end + when :to_internal_api_hash + raise ArgumentError, "API Hash must be generated from Ruby source files" if loaded_from_api? + else + raise ArgumentError, "Unknown hash method #{hash_method.inspect}" + end + + hash = public_send(hash_method) + variations = {} if @dsl.on_system_blocks_exist? begin MacOSVersion::SYMBOLS.keys.product(OnSystem::ARCH_OPTIONS).each do |os, arch| - bottle_tag = ::Utils::Bottles::Tag.new(system: os, arch: arch) + bottle_tag = ::Utils::Bottles::Tag.new(system: os, arch:) next unless bottle_tag.valid_combination? - Homebrew::SimulateSystem.with os: os, arch: arch do + Homebrew::SimulateSystem.with(os:, arch:) do refresh - to_h.each do |key, value| - next if hash_keys_to_skip.include? key + public_send(hash_method).each do |key, value| + next if HASH_KEYS_TO_SKIP.include? key next if value.to_s == hash[key].to_s variations[bottle_tag.to_sym] ||= {} @@ -380,12 +440,20 @@ def to_hash_with_variations end end - hash["variations"] = variations + hash["variations"] = variations if hash_method != :to_internal_api_hash || variations.present? hash end private + sig { returns(T.nilable(Homebrew::BundleVersion)) } + def bundle_version + @bundle_version ||= if (bundle = artifacts.find { |a| a.is_a?(Artifact::App) }&.target) && + (plist = Pathname("#{bundle}/Contents/Info.plist")) && plist.exist? + Homebrew::BundleVersion.from_info_plist(plist) + end + end + def api_to_local_hash(hash) hash["token"] = token hash["installed"] = installed_version @@ -393,16 +461,28 @@ def api_to_local_hash(hash) hash end - def artifacts_list - artifacts.map do |artifact| + def artifacts_list(compact: false) + artifacts.filter_map do |artifact| case artifact when Artifact::AbstractFlightBlock # Only indicate whether this block is used as we don't load it from the API - { artifact.summarize => nil } + # We can skip this entirely once we move to internal JSON v3. + { artifact.summarize => nil } unless compact else { artifact.class.dsl_key => artifact.to_args } end end end + + def url_specs + url&.specs.dup.tap do |url_specs| + case url_specs&.dig(:user_agent) + when :default + url_specs.delete(:user_agent) + when Symbol + url_specs[:user_agent] = ":#{url_specs[:user_agent]}" + end + end + end end end diff --git a/Library/Homebrew/cask/cask_loader.rb b/Library/Homebrew/cask/cask_loader.rb index d9e8fd452adb3c..5f6aeaba377bb9 100644 --- a/Library/Homebrew/cask/cask_loader.rb +++ b/Library/Homebrew/cask/cask_loader.rb @@ -44,7 +44,7 @@ class AbstractContentLoader ).returns(Cask) } def cask(header_token, **options, &block) - Cask.new(header_token, source: content, tap: tap, **options, config: @config, &block) + Cask.new(header_token, source: content, tap:, **options, config: @config, &block) end end @@ -127,9 +127,7 @@ def load(config:) @content = path.read(encoding: "UTF-8") @config = config - if path.extname == ".json" - return FromAPILoader.new(token, from_json: JSON.parse(@content)).load(config: config) - end + return FromAPILoader.new(token, from_json: JSON.parse(@content)).load(config:) if path.extname == ".json" begin instance_eval(content, path).tap do |cask| @@ -207,7 +205,7 @@ class FromTapLoader < FromPathLoader def self.try_new(ref, warn: false) ref = ref.to_s - return unless (token_tap_type = CaskLoader.tap_cask_token_type(ref, warn: warn)) + return unless (token_tap_type = CaskLoader.tap_cask_token_type(ref, warn:)) token, tap, = token_tap_type new("#{tap}/#{token}") @@ -215,8 +213,7 @@ def self.try_new(ref, warn: false) sig { params(tapped_token: String).void } def initialize(tapped_token) - user, repo, token = tapped_token.split("/", 3) - tap = Tap.fetch(user, repo) + tap, token = Tap.with_cask_token(tapped_token) cask = CaskLoader.find_cask_in_tap(token, tap) super cask end @@ -279,7 +276,7 @@ def self.try_new(ref, warn: false) ref = "#{CoreCaskTap.instance}/#{token}" - token, tap, = CaskLoader.tap_cask_token_type(ref, warn: warn) + token, tap, = CaskLoader.tap_cask_token_type(ref, warn:) new("#{tap}/#{token}") end @@ -296,7 +293,7 @@ def load(config:) cask_options = { loaded_from_api: true, source: JSON.pretty_generate(json_cask), - config: config, + config:, loader: self, } @@ -439,23 +436,6 @@ def from_h_gsubs(value, appdir) end end - # Loader which tries loading casks from the default tap. - class FromDefaultNameLoader < FromTapLoader - sig { - params(ref: T.any(String, Pathname, Cask, URI::Generic), warn: T::Boolean) - .returns(T.nilable(T.attached_class)) - } - def self.try_new(ref, warn: false) - return unless ref.is_a?(String) - return unless (token = ref[HOMEBREW_DEFAULT_TAP_CASK_REGEX, :token]) - return unless (tap = CoreCaskTap.instance).installed? - - return unless (loader = super("#{tap}/#{token}", warn: warn)) - - loader if loader.path.exist? - end - end - # Loader which tries loading casks from tap paths, failing # if the same token exists in multiple taps. class FromNameLoader < FromTapLoader @@ -465,12 +445,19 @@ class FromNameLoader < FromTapLoader } def self.try_new(ref, warn: false) return unless ref.is_a?(String) - return if ref.include?("/") + return unless ref.match?(/\A#{HOMEBREW_TAP_CASK_TOKEN_REGEX}\Z/o) token = ref - loaders = Tap.filter_map { |tap| super("#{tap}/#{token}", warn: warn) } - .select { _1.path.exist? } + # If it exists in the default tap, never treat it as ambiguous with another tap. + if (core_cask_tap = CoreCaskTap.instance).installed? && + (loader= super("#{core_cask_tap}/#{token}", warn:))&.path&.exist? + return loader + end + + loaders = Tap.select { |tap| tap.installed? && !tap.core_cask_tap? } + .filter_map { |tap| super("#{tap}/#{token}", warn:) } + .select { |tap| tap.path.exist? } case loaders.count when 1 @@ -526,7 +513,7 @@ def self.path(ref) end def self.load(ref, config: nil, warn: true) - self.for(ref, warn: warn).load(config: config) + self.for(ref, warn:).load(config:) end sig { params(tapped_token: String, warn: T::Boolean).returns(T.nilable([String, Tap, T.nilable(Symbol)])) } @@ -543,9 +530,7 @@ def self.tap_cask_token_type(tapped_token, warn:) new_token = tap.core_cask_tap? ? token : "#{tap}/#{token}" type = :rename elsif (new_tap_name = tap.tap_migrations[token].presence) - new_tap_user, new_tap_repo, new_token = new_tap_name.split("/", 3) - new_token ||= token - new_tap = Tap.fetch(new_tap_user, new_tap_repo) + new_tap, new_token = Tap.with_cask_token(new_tap_name) || [Tap.fetch(new_tap_name), token] new_tap.ensure_installed! new_tapped_token = "#{new_tap}/#{new_token}" @@ -573,13 +558,12 @@ def self.for(ref, need_path: false, warn: true) FromURILoader, FromAPILoader, FromTapLoader, - FromDefaultNameLoader, FromNameLoader, FromPathLoader, FromInstalledPathLoader, NullLoader, ].each do |loader_class| - if (loader = loader_class.try_new(ref, warn: warn)) + if (loader = loader_class.try_new(ref, warn:)) $stderr.puts "#{$PROGRAM_NAME} (#{loader.class}): loading #{ref}" if debug? return loader end diff --git a/Library/Homebrew/cask/caskroom.rb b/Library/Homebrew/cask/caskroom.rb index 75605f0d996f79..d83c53804a9816 100644 --- a/Library/Homebrew/cask/caskroom.rb +++ b/Library/Homebrew/cask/caskroom.rb @@ -44,18 +44,18 @@ def self.ensure_caskroom_exists "We'll set permissions properly so we won't need sudo in the future." end - SystemCommand.run("/bin/mkdir", args: ["-p", path], sudo: sudo) - SystemCommand.run("/bin/chmod", args: ["g+rwx", path], sudo: sudo) - SystemCommand.run("/usr/sbin/chown", args: [User.current, path], sudo: sudo) - SystemCommand.run("/usr/bin/chgrp", args: ["admin", path], sudo: sudo) + SystemCommand.run("/bin/mkdir", args: ["-p", path], sudo:) + SystemCommand.run("/bin/chmod", args: ["g+rwx", path], sudo:) + SystemCommand.run("/usr/sbin/chown", args: [User.current, path], sudo:) + SystemCommand.run("/usr/bin/chgrp", args: ["admin", path], sudo:) end sig { params(config: T.nilable(Config)).returns(T::Array[Cask]) } def self.casks(config: nil) tokens.sort.filter_map do |token| - CaskLoader.load(token, config: config, warn: false) + CaskLoader.load(token, config:, warn: false) rescue TapCaskAmbiguityError => e - T.must(e.loaders.first).load(config: config) + T.must(e.loaders.first).load(config:) rescue # Don't blow up because of a single unavailable cask. nil diff --git a/Library/Homebrew/cask/config.rb b/Library/Homebrew/cask/config.rb index ac11934b7a756c..37854d8ec59ecf 100644 --- a/Library/Homebrew/cask/config.rb +++ b/Library/Homebrew/cask/config.rb @@ -66,7 +66,7 @@ def self.from_json(json, ignore_invalid_keys: false) default: config.fetch("default", {}), env: config.fetch("env", {}), explicit: config.fetch("explicit", {}), - ignore_invalid_keys: ignore_invalid_keys, + ignore_invalid_keys:, ) end @@ -199,9 +199,9 @@ def explicit_s sig { params(options: T.untyped).returns(String) } def to_json(*options) { - default: default, - env: env, - explicit: explicit, + default:, + env:, + explicit:, }.to_json(*options) end end diff --git a/Library/Homebrew/cask/download.rb b/Library/Homebrew/cask/download.rb index 76c412103814e6..047def35b189aa 100644 --- a/Library/Homebrew/cask/download.rb +++ b/Library/Homebrew/cask/download.rb @@ -52,7 +52,7 @@ def fetch(quiet: nil, verify_download_integrity: true, timeout: nil) downloader.quiet! if quiet begin - super(verify_download_integrity: false, timeout: timeout) + super(verify_download_integrity: false, timeout:) rescue DownloadError => e error = CaskError.new("Download failed on Cask '#{cask}' with message: #{e.cause}") error.set_backtrace e.backtrace @@ -68,7 +68,7 @@ def fetch(quiet: nil, verify_download_integrity: true, timeout: nil) def time_file_size(timeout: nil) raise ArgumentError, "not supported for this download strategy" unless downloader.is_a?(CurlDownloadStrategy) - T.cast(downloader, CurlDownloadStrategy).resolved_time_file_size(timeout: timeout) + T.cast(downloader, CurlDownloadStrategy).resolved_time_file_size(timeout:) end def basename diff --git a/Library/Homebrew/cask/dsl.rb b/Library/Homebrew/cask/dsl.rb index 75d7e4b1dc7c6e..e70b07f0205dad 100644 --- a/Library/Homebrew/cask/dsl.rb +++ b/Library/Homebrew/cask/dsl.rb @@ -209,9 +209,9 @@ def url(*args, **options, &block) set_unique_stanza(:url, args.empty? && options.empty? && !block) do if block - URL.new(*args, **options, caller_location: caller_location, dsl: self, &block) + URL.new(*args, **options, caller_location:, dsl: self, &block) else - URL.new(*args, **options, caller_location: caller_location) + URL.new(*args, **options, caller_location:) end end end @@ -249,7 +249,7 @@ def sha256(arg = nil, arm: nil, intel: nil) set_unique_stanza(:sha256, should_return) do @on_system_blocks_exist = true if arm.present? || intel.present? - val = arg || on_arch_conditional(arm: arm, intel: intel) + val = arg || on_arch_conditional(arm:, intel:) case val when :no_check val @@ -268,7 +268,7 @@ def arch(arm: nil, intel: nil) set_unique_stanza(:arch, should_return) do @on_system_blocks_exist = true - on_arch_conditional(arm: arm, intel: intel) + on_arch_conditional(arm:, intel:) end end diff --git a/Library/Homebrew/cask/dsl/version.rb b/Library/Homebrew/cask/dsl/version.rb index e6488c9c5c944d..3b1887c0cda1b1 100644 --- a/Library/Homebrew/cask/dsl/version.rb +++ b/Library/Homebrew/cask/dsl/version.rb @@ -135,7 +135,7 @@ def minor_patch # @api public sig { returns(T::Array[Version]) } # Only top-level T.self_type is supported https://sorbet.org/docs/self-type def csv - split(",").map(&self.class.method(:new)) + split(",").map { self.class.new(_1) } end # @api public diff --git a/Library/Homebrew/cask/installer.rb b/Library/Homebrew/cask/installer.rb index 8786d187b0c32c..dc6b454d27ce22 100644 --- a/Library/Homebrew/cask/installer.rb +++ b/Library/Homebrew/cask/installer.rb @@ -68,7 +68,7 @@ def fetch(quiet: nil, timeout: nil) verify_has_sha if require_sha? && !force? check_requirements - download(quiet: quiet, timeout: timeout) + download(quiet:, timeout:) satisfy_cask_and_formula_dependencies end @@ -109,10 +109,10 @@ def install @cask.config = @cask.default_config.merge(old_config) - install_artifacts(predecessor: predecessor) + install_artifacts(predecessor:) if (tap = @cask.tap) && tap.should_report_analytics? - ::Utils::Analytics.report_event(:cask_install, package_name: @cask.token, tap_name: tap.name, + ::Utils::Analytics.report_package_event(:cask_install, package_name: @cask.token, tap_name: tap.name, on_request: true) end @@ -130,11 +130,16 @@ def check_deprecate_disable deprecate_disable_type = DeprecateDisable.type(@cask) return if deprecate_disable_type.nil? + message = DeprecateDisable.message(@cask) + message_full = "#{@cask.token} has been #{message}" + case deprecate_disable_type when :deprecated - opoo "#{@cask.token} has been #{DeprecateDisable.message(@cask)}" + puts "::warning::#{message_full}" if ENV["GITHUB_ACTIONS"] + opoo message_full when :disabled - raise CaskCannotBeInstalledError.new(@cask, DeprecateDisable.message(@cask)) + puts "::error::#{message_full}" if ENV["GITHUB_ACTIONS"] + raise CaskCannotBeInstalledError.new(@cask, message) end end @@ -178,8 +183,8 @@ def downloader sig { params(quiet: T.nilable(T::Boolean), timeout: T.nilable(T.any(Integer, Float))).returns(Pathname) } def download(quiet: nil, timeout: nil) # Store cask download path in cask to prevent multiple downloads in a row when checking if it's outdated - @cask.download ||= downloader.fetch(quiet: quiet, verify_download_integrity: @verify_download_integrity, - timeout: timeout) + @cask.download ||= downloader.fetch(quiet:, verify_download_integrity: @verify_download_integrity, + timeout:) end def verify_has_sha @@ -209,21 +214,21 @@ def extract_primary_container(to: @cask.staged_path) if (nested_container = @cask.container&.nested) Dir.mktmpdir("cask-installer", HOMEBREW_TEMP) do |tmpdir| tmpdir = Pathname(tmpdir) - primary_container.extract(to: tmpdir, basename: basename, verbose: verbose?) + primary_container.extract(to: tmpdir, basename:, verbose: verbose?) FileUtils.chmod_R "+rw", tmpdir/nested_container, force: true, verbose: verbose? UnpackStrategy.detect(tmpdir/nested_container, merge_xattrs: true) - .extract_nestedly(to: to, verbose: verbose?) + .extract_nestedly(to:, verbose: verbose?) end else - primary_container.extract_nestedly(to: to, basename: basename, verbose: verbose?) + primary_container.extract_nestedly(to:, basename:, verbose: verbose?) end return unless quarantine? return unless Quarantine.available? - Quarantine.propagate(from: primary_container.path, to: to) + Quarantine.propagate(from: primary_container.path, to:) end sig { params(predecessor: T.nilable(Cask)).void } @@ -241,7 +246,7 @@ def install_artifacts(predecessor: nil) next if artifact.is_a?(Artifact::Binary) && !binaries? artifact.install_phase( - command: @command, verbose: verbose?, adopt: adopt?, force: force?, predecessor: predecessor, + command: @command, verbose: verbose?, adopt: adopt?, force: force?, predecessor:, ) already_installed_artifacts.unshift(artifact) end @@ -401,7 +406,7 @@ def save_download_sha def uninstall(successor: nil) load_installed_caskfile! oh1 "Uninstalling Cask #{Formatter.identifier(@cask)}" - uninstall_artifacts(clear: true, successor: successor) + uninstall_artifacts(clear: true, successor:) if !reinstall? && !upgrade? remove_download_sha remove_config_file @@ -422,7 +427,7 @@ def remove_download_sha sig { params(successor: T.nilable(Cask)).void } def start_upgrade(successor:) - uninstall_artifacts(successor: successor) + uninstall_artifacts(successor:) backup end @@ -445,7 +450,7 @@ def restore_backup def revert_upgrade(predecessor:) opoo "Reverting upgrade for Cask #{@cask}" restore_backup - install_artifacts(predecessor: predecessor) + install_artifacts(predecessor:) end def finalize_upgrade @@ -471,7 +476,7 @@ def uninstall_artifacts(clear: false, successor: nil) verbose: verbose?, skip: clear, force: force?, - successor: successor, + successor:, upgrade: upgrade?, reinstall: reinstall?, ) @@ -485,7 +490,7 @@ def uninstall_artifacts(clear: false, successor: nil) verbose: verbose?, skip: clear, force: force?, - successor: successor, + successor:, ) end end diff --git a/Library/Homebrew/cask/metadata.rb b/Library/Homebrew/cask/metadata.rb index 4282dd686596a1..c7c664808499c1 100644 --- a/Library/Homebrew/cask/metadata.rb +++ b/Library/Homebrew/cask/metadata.rb @@ -18,7 +18,7 @@ def metadata_versioned_path(version: self.version, caskroom_path: self.caskroom_ raise CaskError, "Cannot create metadata path with empty version." if cask_version.empty? - metadata_main_container_path(caskroom_path: caskroom_path).join(cask_version) + metadata_main_container_path(caskroom_path:).join(cask_version) end def metadata_timestamped_path(version: self.version, timestamp: :latest, create: false, @@ -26,10 +26,10 @@ def metadata_timestamped_path(version: self.version, timestamp: :latest, create: raise CaskError, "Cannot create metadata path when timestamp is :latest." if create && timestamp == :latest path = if timestamp == :latest - Pathname.glob(metadata_versioned_path(version: version, caskroom_path: caskroom_path).join("*")).max + Pathname.glob(metadata_versioned_path(version:, caskroom_path:).join("*")).max else timestamp = new_timestamp if timestamp == :now - metadata_versioned_path(version: version, caskroom_path: caskroom_path).join(timestamp) + metadata_versioned_path(version:, caskroom_path:).join(timestamp) end if create && !path.directory? @@ -45,8 +45,8 @@ def metadata_subdir(leaf, version: self.version, timestamp: :latest, create: fal raise CaskError, "Cannot create metadata subdir when timestamp is :latest." if create && timestamp == :latest raise CaskError, "Cannot create metadata subdir for empty leaf." if !leaf.respond_to?(:empty?) || leaf.empty? - parent = metadata_timestamped_path(version: version, timestamp: timestamp, create: create, - caskroom_path: caskroom_path) + parent = metadata_timestamped_path(version:, timestamp:, create:, + caskroom_path:) return if parent.nil? diff --git a/Library/Homebrew/cask/migrator.rb b/Library/Homebrew/cask/migrator.rb index 1c3d9f4f20fbb4..ae97769f6d1fa6 100644 --- a/Library/Homebrew/cask/migrator.rb +++ b/Library/Homebrew/cask/migrator.rb @@ -27,7 +27,7 @@ def self.migrate_if_needed(new_cask, dry_run: false) return if new_cask.token == old_cask.token migrator = new(old_cask, new_cask) - migrator.migrate(dry_run: dry_run) + migrator.migrate(dry_run:) end sig { params(dry_run: T::Boolean).void } diff --git a/Library/Homebrew/cask/pkg.rb b/Library/Homebrew/cask/pkg.rb index a71e0eb17b3709..49dcade6b01c55 100644 --- a/Library/Homebrew/cask/pkg.rb +++ b/Library/Homebrew/cask/pkg.rb @@ -90,7 +90,7 @@ def pkgutil_bom_all .stdout .split("\n") .map { |path| root.join(path) } - .reject(&MacOS.public_method(:undeletable?)) + .reject { MacOS.undeletable?(_1) } end sig { returns(Pathname) } diff --git a/Library/Homebrew/cask/quarantine.rb b/Library/Homebrew/cask/quarantine.rb index a93525bd74c09d..2d5fd2589201ff 100644 --- a/Library/Homebrew/cask/quarantine.rb +++ b/Library/Homebrew/cask/quarantine.rb @@ -18,7 +18,17 @@ module Quarantine COPY_XATTRS_SCRIPT = (HOMEBREW_LIBRARY_PATH/"cask/utils/copy-xattrs.swift").freeze def self.swift - @swift ||= DevelopmentTools.locate("swift") + @swift ||= begin + # /usr/bin/swift (which runs via xcrun) adds `/usr/local/include` to the top of the include path, + # which allows really broken local setups to break our Swift usage here. Using the underlying + # Swift executable directly however (returned by `xcrun -find`) avoids this CPATH mess. + xcrun_swift = ::Utils.popen_read("/usr/bin/xcrun", "-find", "swift", err: :close).chomp + if $CHILD_STATUS.success? && File.executable?(xcrun_swift) + xcrun_swift + else + DevelopmentTools.locate("swift") + end + end end private_class_method :swift diff --git a/Library/Homebrew/cask/reinstall.rb b/Library/Homebrew/cask/reinstall.rb index d756aa3c56843c..1a4cf728d8e9b3 100644 --- a/Library/Homebrew/cask/reinstall.rb +++ b/Library/Homebrew/cask/reinstall.rb @@ -21,14 +21,14 @@ def self.reinstall_casks( casks.each do |cask| Installer.new(cask, - binaries: binaries, - verbose: verbose, - force: force, - skip_cask_deps: skip_cask_deps, - require_sha: require_sha, + binaries:, + verbose:, + force:, + skip_cask_deps:, + require_sha:, reinstall: true, - quarantine: quarantine, - zap: zap).install + quarantine:, + zap:).install end end end diff --git a/Library/Homebrew/cask/uninstall.rb b/Library/Homebrew/cask/uninstall.rb index fb38219e2c0298..be1da477a66ccd 100644 --- a/Library/Homebrew/cask/uninstall.rb +++ b/Library/Homebrew/cask/uninstall.rb @@ -12,7 +12,7 @@ def self.uninstall_casks(*casks, binaries: nil, force: false, verbose: false) raise CaskNotInstalledError, cask if !cask.installed? && !force - Installer.new(cask, binaries: binaries, force: force, verbose: verbose).uninstall + Installer.new(cask, binaries:, force:, verbose:).uninstall end end end diff --git a/Library/Homebrew/cask/upgrade.rb b/Library/Homebrew/cask/upgrade.rb index 54e76880c6cac6..558109b6dfec9c 100644 --- a/Library/Homebrew/cask/upgrade.rb +++ b/Library/Homebrew/cask/upgrade.rb @@ -44,8 +44,8 @@ def self.upgrade_casks( outdated_casks = if casks.empty? Caskroom.casks(config: Config.from_args(args)).select do |cask| - cask.outdated?(greedy: greedy, greedy_latest: greedy_latest, - greedy_auto_updates: greedy_auto_updates) + cask.outdated?(greedy:, greedy_latest:, + greedy_auto_updates:) end else casks.select do |cask| @@ -113,8 +113,8 @@ def self.upgrade_casks( upgradable_casks.each do |(old_cask, new_cask)| upgrade_cask( old_cask, new_cask, - binaries: binaries, force: force, skip_cask_deps: skip_cask_deps, verbose: verbose, - quarantine: quarantine, require_sha: require_sha + binaries:, force:, skip_cask_deps:, verbose:, + quarantine:, require_sha: ) rescue => e new_exception = e.exception("#{new_cask.full_name}: #{e}") @@ -153,9 +153,9 @@ def self.upgrade_cask( old_config = old_cask.config old_options = { - binaries: binaries, - verbose: verbose, - force: force, + binaries:, + verbose:, + force:, upgrade: true, }.compact @@ -165,13 +165,13 @@ def self.upgrade_cask( new_cask.config = new_cask.default_config.merge(old_config) new_options = { - binaries: binaries, - verbose: verbose, - force: force, - skip_cask_deps: skip_cask_deps, - require_sha: require_sha, + binaries:, + verbose:, + force:, + skip_cask_deps:, + require_sha:, upgrade: true, - quarantine: quarantine, + quarantine:, }.compact new_cask_installer = diff --git a/Library/Homebrew/cask/url.rb b/Library/Homebrew/cask/url.rb index f2e88920c95850..792ee814a2adac 100644 --- a/Library/Homebrew/cask/url.rb +++ b/Library/Homebrew/cask/url.rb @@ -191,26 +191,26 @@ def initialize( super( if block LazyObject.new do - uri2, options = *BlockDSL.new(uri, dsl: dsl, &block).call + uri2, options = *BlockDSL.new(uri, dsl:, &block).call options ||= {} DSL.new(uri2, **options) end else DSL.new( T.must(uri), - verified: verified, - using: using, - tag: tag, - branch: branch, - revisions: revisions, - revision: revision, - trust_cert: trust_cert, - cookies: cookies, - referer: referer, - header: header, - user_agent: user_agent, - data: data, - only_path: only_path, + verified:, + using:, + tag:, + branch:, + revisions:, + revision:, + trust_cert:, + cookies:, + referer:, + header:, + user_agent:, + data:, + only_path:, ) end ) diff --git a/Library/Homebrew/cleaner.rb b/Library/Homebrew/cleaner.rb index 66b5c8f4dff980..5f9217aeb3a6f9 100644 --- a/Library/Homebrew/cleaner.rb +++ b/Library/Homebrew/cleaner.rb @@ -15,11 +15,13 @@ class Cleaner include Context # Create a cleaner for the given formula. + sig { params(formula: Formula).void } def initialize(formula) @formula = formula end # Clean the keg of the formula. + sig { void } def clean ObserverPathnameExtension.reset_counts! @@ -48,8 +50,7 @@ def clean # [1]: https://github.com/Homebrew/brew/pull/11597 # [2]: https://github.com/Homebrew/homebrew-core/issues/100190 # [3]: https://github.com/Homebrew/brew/pull/13215 - Dir.glob(@formula.info/"**/dir").each do |file| - info_dir_file = Pathname(file) + @formula.info.glob("**/dir").each do |info_dir_file| next unless info_dir_file.file? next if info_dir_file == @formula.info/@formula.name/"dir" next if @formula.skip_clean?(info_dir_file) @@ -58,12 +59,14 @@ def clean end rewrite_shebangs + clean_python_metadata prune end private + sig { params(path: Pathname).void } def observe_file_removal(path) path.extend(ObserverPathnameExtension).unlink if path.exist? end @@ -71,6 +74,7 @@ def observe_file_removal(path) # Removes any empty directories in the formula's prefix subtree # Keeps any empty directories protected by skip_clean # Removes any unresolved symlinks + sig { void } def prune dirs = [] symlinks = [] @@ -99,6 +103,7 @@ def prune end end + sig { params(path: Pathname).returns(T::Boolean) } def executable_path?(path) path.text_executable? || path.executable? end @@ -118,6 +123,7 @@ def executable_path?(path) # # lib may have a large directory tree (see Erlang for instance), and # clean_dir applies cleaning rules to the entire tree + sig { params(directory: Pathname).void } def clean_dir(directory) directory.find do |path| path.extend(ObserverPathnameExtension) @@ -146,6 +152,7 @@ def clean_dir(directory) end end + sig { void } def rewrite_shebangs require "language/perl" require "utils/shebang" @@ -163,6 +170,30 @@ def rewrite_shebangs end end end + + # Remove non-reproducible pip direct_url.json which records the /tmp build directory. + # Remove RECORD files to prevent changes to the installed Python package. + # Modify INSTALLER to provide information that files are managed by brew. + # + # @see https://packaging.python.org/en/latest/specifications/recording-installed-packages/ + sig { void } + def clean_python_metadata + basepath = @formula.prefix.realpath + basepath.find do |path| + Find.prune if @formula.skip_clean?(path) + + next if path.directory? || path.symlink? + next if path.parent.extname != ".dist-info" + + case path.basename.to_s + when "direct_url.json", "RECORD" + observe_file_removal path + when "INSTALLER" + odebug "Modifying #{path} contents from #{path.read.chomp} to brew" + path.atomic_write("brew\n") + end + end + end end require "extend/os/cleaner" diff --git a/Library/Homebrew/cleanup.rb b/Library/Homebrew/cleanup.rb index 66937919c49b58..8d0c9e9f4426dd 100644 --- a/Library/Homebrew/cleanup.rb +++ b/Library/Homebrew/cleanup.rb @@ -269,7 +269,7 @@ def clean!(quiet: false, periodic: false) .sort_by(&:name) .reject { |f| Cleanup.skip_clean_formula?(f) } .each do |formula| - cleanup_formula(formula, quiet: quiet, ds_store: false, cache_db: false) + cleanup_formula(formula, quiet:, ds_store: false, cache_db: false) end Cleanup.autoremove(dry_run: dry_run?) if Homebrew::EnvConfig.autoremove? @@ -326,16 +326,16 @@ def unremovable_kegs end def cleanup_formula(formula, quiet: false, ds_store: true, cache_db: true) - formula.eligible_kegs_for_cleanup(quiet: quiet) + formula.eligible_kegs_for_cleanup(quiet:) .each(&method(:cleanup_keg)) - cleanup_cache(Pathname.glob(cache/"#{formula.name}--*").map { |path| { path: path, type: nil } }) + cleanup_cache(Pathname.glob(cache/"#{formula.name}--*").map { |path| { path:, type: nil } }) rm_ds_store([formula.rack]) if ds_store cleanup_cache_db(formula.rack) if cache_db cleanup_lockfiles(FormulaLock.new(formula.name).path) end def cleanup_cask(cask, ds_store: true) - cleanup_cache(Pathname.glob(cache/"Cask/#{cask.token}--*").map { |path| { path: path, type: :cask } }) + cleanup_cache(Pathname.glob(cache/"Cask/#{cask.token}--*").map { |path| { path:, type: :cask } }) rm_ds_store([cask.caskroom_path]) if ds_store cleanup_lockfiles(CaskLock.new(cask.token).path) end @@ -363,10 +363,10 @@ def cache_files api_source_files = (cache/"api-source").glob("*/*/*/*/*") # org/repo/git_head/type/file.rb gh_actions_artifacts = (cache/"gh-actions-artifact").directory? ? (cache/"gh-actions-artifact").children : [] - files.map { |path| { path: path, type: nil } } + - cask_files.map { |path| { path: path, type: :cask } } + - api_source_files.map { |path| { path: path, type: :api_source } } + - gh_actions_artifacts.map { |path| { path: path, type: :gh_actions_artifact } } + files.map { |path| { path:, type: nil } } + + cask_files.map { |path| { path:, type: :cask } } + + api_source_files.map { |path| { path:, type: :api_source } } + + gh_actions_artifacts.map { |path| { path:, type: :gh_actions_artifact } } end def cleanup_empty_api_source_directories(directory = cache/"api-source") @@ -600,6 +600,7 @@ def prune_prefix_symlinks_and_directories ObserverPathnameExtension.reset_counts! dirs = [] + children_count = {} Keg::MUST_EXIST_SUBDIRECTORIES.each do |dir| next unless dir.directory? @@ -612,21 +613,24 @@ def prune_prefix_symlinks_and_directories if dry_run? puts "Would remove (broken link): #{path}" + children_count[path.dirname] -= 1 if children_count.key?(path.dirname) else path.unlink end end elsif path.directory? && Keg::MUST_EXIST_SUBDIRECTORIES.exclude?(path) dirs << path + children_count[path] = path.children.length if dry_run? end end end dirs.reverse_each do |d| - if dry_run? && d.children.empty? - puts "Would remove (empty directory): #{d}" - else + if !dry_run? d.rmdir_if_possible + elsif children_count[d].zero? + puts "Would remove (empty directory): #{d}" + children_count[d.dirname] -= 1 if children_count.key?(d.dirname) end end diff --git a/Library/Homebrew/cli/args.rb b/Library/Homebrew/cli/args.rb index 00f47b9abe5324..0926546cdbbf68 100644 --- a/Library/Homebrew/cli/args.rb +++ b/Library/Homebrew/cli/args.rb @@ -40,8 +40,8 @@ def freeze_named_args!(named_args, cask_options:, without_api:) self[:named] = NamedArgs.new( *named_args.freeze, parent: self, - cask_options: cask_options, - without_api: without_api, + cask_options:, + without_api:, **options, ) end @@ -131,7 +131,7 @@ def os_arch_combinations oses.product(arches).select do |os, arch| if skip_invalid_combinations - bottle_tag = Utils::Bottles::Tag.new(system: os, arch: arch) + bottle_tag = Utils::Bottles::Tag.new(system: os, arch:) bottle_tag.valid_combination? else true diff --git a/Library/Homebrew/cli/args.rbi b/Library/Homebrew/cli/args.rbi deleted file mode 100644 index e51b8fe18f174e..00000000000000 --- a/Library/Homebrew/cli/args.rbi +++ /dev/null @@ -1,355 +0,0 @@ -# typed: strict - -module Homebrew - module CLI - class Args < OpenStruct - sig { returns(T::Boolean) } - def remove_bottle_block?; end - - sig { returns(T::Boolean) } - def strict?; end - - sig { returns(T::Boolean) } - def HEAD?; end - - sig { returns(T::Boolean) } - def include_test?; end - - sig { returns(T::Boolean) } - def build_bottle?; end - - sig { returns(T::Boolean) } - def build_universal?; end - - sig { returns(T::Boolean) } - def build_from_source?; end - - sig { returns(T::Boolean) } - def force_bottle?; end - - sig { returns(T::Boolean) } - def newer_only?; end - - sig { returns(T::Boolean) } - def resources?; end - - sig { returns(T::Boolean) } - def full_name?; end - - sig { returns(T::Boolean) } - def json?; end - - sig { returns(T::Boolean) } - def debug?; end - - sig { returns(T::Boolean) } - def quiet?; end - - sig { returns(T::Boolean) } - def verbose?; end - - sig { returns(T::Boolean) } - def fetch_HEAD?; end - - sig { returns(T::Boolean) } - def cask?; end - - sig { returns(T::Boolean) } - def dry_run?; end - - sig { returns(T::Boolean) } - def skip_cask_deps?; end - - sig { returns(T::Boolean) } - def greedy?; end - - sig { returns(T::Boolean) } - def force?; end - - sig { returns(T::Boolean) } - def ignore_pinned?; end - - sig { returns(T::Boolean) } - def display_times?; end - - sig { returns(T::Boolean) } - def formula?; end - - sig { returns(T::Boolean) } - def zap?; end - - sig { returns(T::Boolean) } - def ignore_dependencies?; end - - sig { returns(T::Boolean) } - def aliases?; end - - sig { returns(T::Boolean) } - def fix?; end - - sig { returns(T::Boolean) } - def keep_tmp?; end - - sig { returns(T::Boolean) } - def debug_symbols?; end - - sig { returns(T::Boolean) } - def overwrite?; end - - sig { returns(T::Boolean) } - def silent?; end - - sig { returns(T::Boolean) } - def repair?; end - - sig { returns(T::Boolean) } - def prune_prefix?; end - - sig { returns(T::Boolean) } - def upload?; end - - sig { returns(T::Boolean) } - def linux?; end - - sig { returns(T::Boolean) } - def linux_self_hosted?; end - - sig { returns(T::Boolean) } - def linux_wheezy?; end - - sig { returns(T::Boolean) } - def total?; end - - sig { returns(T::Boolean) } - def dependents?; end - - sig { returns(T::Boolean) } - def installed?; end - - sig { returns(T::Boolean) } - def installed_on_request?; end - - sig { returns(T::Boolean) } - def installed_as_dependency?; end - - sig { returns(T::Boolean) } - def all?; end - - sig { returns(T::Boolean) } - def eval_all?; end - - sig { returns(T::Boolean) } - def full?; end - - sig { returns(T::Boolean) } - def list_pinned?; end - - sig { returns(T::Boolean) } - def display_cop_names?; end - - sig { returns(T::Boolean) } - def syntax?; end - - sig { returns(T::Boolean) } - def no_simulate?; end - - sig { returns(T::Boolean) } - def ignore_non_pypi_packages?; end - - sig { returns(T::Boolean) } - def test?; end - - sig { returns(T::Boolean) } - def reverse?; end - - sig { returns(T::Boolean) } - def print_only?; end - - sig { returns(T::Boolean) } - def markdown?; end - - sig { returns(T::Boolean) } - def reset_cache?; end - - sig { returns(T::Boolean) } - def major?; end - - sig { returns(T::Boolean) } - def minor?; end - - sig { returns(T.nilable(String)) } - def bottle_tag; end - - sig { returns(T.nilable(String)) } - def tag; end - - sig { returns(T.nilable(String)) } - def tap; end - - sig { returns(T.nilable(T::Array[String])) } - def macos; end - - sig { returns(T.nilable(T::Array[String])) } - def hide; end - - sig { returns(T.nilable(String)) } - def version; end - - sig { returns(T.nilable(String)) } - def name; end - - sig { returns(T::Boolean) } - def no_publish?; end - - sig { returns(T::Boolean) } - def shallow?; end - - sig { returns(T::Boolean) } - def fail_if_not_changed?; end - - sig { returns(T.nilable(String)) } - def limit; end - - sig { returns(T.nilable(String)) } - def start_with; end - - sig { returns(T.nilable(String)) } - def message; end - - sig { returns(T.nilable(String)) } - def timeout; end - - sig { returns(T.nilable(String)) } - def issue; end - - sig { returns(T.nilable(String)) } - def workflow; end - - sig { returns(T.nilable(String)) } - def package_name; end - - sig { returns(T.nilable(String)) } - def prune; end - - sig { returns(T.nilable(T::Array[String])) } - def only_cops; end - - sig { returns(T.nilable(T::Array[String])) } - def except_cops; end - - sig { returns(T.nilable(T::Array[String])) } - def only; end - - sig { returns(T.nilable(String)) } - def os; end - - sig { returns(T.nilable(T::Array[String])) } - def except; end - - sig { returns(T.nilable(T::Array[String])) } - def mirror; end - - sig { returns(T.nilable(T::Array[String])) } - def without_labels; end - - sig { returns(T.nilable(T::Array[String])) } - def workflows; end - - sig { returns(T.nilable(T::Array[String])) } - def ignore_missing_artifacts; end - - sig { returns(T.nilable(T::Array[String])) } - def language; end - - sig { returns(T.nilable(T::Array[String])) } - def extra_packages; end - - sig { returns(T.nilable(T::Array[String])) } - def exclude_packages; end - - sig { returns(T.nilable(T::Array[String])) } - def update; end - - sig { returns(T::Boolean) } - def s?; end - - sig { returns(T.nilable(String)) } - def arch; end - - sig { returns(T.nilable(String)) } - def appdir; end - - sig { returns(T.nilable(String)) } - def keyboard_layoutdir; end - - sig { returns(T.nilable(String)) } - def fontdir; end - - sig { returns(T.nilable(String)) } - def colorpickerdir; end - - sig { returns(T.nilable(String)) } - def prefpanedir; end - - sig { returns(T.nilable(String)) } - def qlplugindir; end - - sig { returns(T.nilable(String)) } - def dictionarydir; end - - sig { returns(T.nilable(String)) } - def servicedir; end - - sig { returns(T.nilable(String)) } - def input_methoddir; end - - sig { returns(T.nilable(String)) } - def mdimporterdir; end - - sig { returns(T.nilable(String)) } - def internet_plugindir; end - - sig { returns(T.nilable(String)) } - def audio_unit_plugindir; end - - sig { returns(T.nilable(String)) } - def vst_plugindir; end - - sig { returns(T.nilable(String)) } - def vst3_plugindir; end - - sig { returns(T.nilable(String)) } - def screen_saverdir; end - - sig { returns(T::Array[String]) } - def repositories; end - - sig { returns(T.nilable(String)) } - def from; end - - sig { returns(T.nilable(String)) } - def to; end - - sig { returns(T.nilable(T::Array[String])) } - def groups; end - - sig { returns(T::Boolean) } - def write_only?; end - - sig { returns(T::Boolean) } - def custom_remote?; end - - sig { returns(T::Boolean) } - def print_path?; end - - sig { returns(T.nilable(T::Boolean)) } - def force_auto_update?; end - - sig { returns(T::Boolean) } - def csv?; end - - sig { returns(T.nilable(String)) } - def user; end - end - end -end diff --git a/Library/Homebrew/cli/named_args.rb b/Library/Homebrew/cli/named_args.rb index 9b470f4f2e870d..1b30ef7d6b9f25 100644 --- a/Library/Homebrew/cli/named_args.rb +++ b/Library/Homebrew/cli/named_args.rb @@ -79,8 +79,8 @@ def to_formulae_and_casks( ) @to_formulae_and_casks ||= {} @to_formulae_and_casks[only] ||= downcased_unique_named.flat_map do |name| - options = { warn: warn }.compact - load_formula_or_cask(name, only: only, method: method, **options) + options = { warn: }.compact + load_formula_or_cask(name, only:, method:, **options) rescue FormulaUnreadableError, FormulaClassUnavailableError, TapFormulaUnreadableError, TapFormulaClassUnavailableError, Cask::CaskUnreadableError @@ -100,7 +100,7 @@ def to_formulae_and_casks( def to_formulae_to_casks(only: parent&.only_formula_or_cask, method: nil) @to_formulae_to_casks ||= {} - @to_formulae_to_casks[[method, only]] = to_formulae_and_casks(only: only, method: method) + @to_formulae_to_casks[[method, only]] = to_formulae_and_casks(only:, method:) .partition { |o| o.is_a?(Formula) || o.is_a?(Keg) } .map(&:freeze).freeze end @@ -108,7 +108,7 @@ def to_formulae_to_casks(only: parent&.only_formula_or_cask, method: nil) def to_formulae_and_casks_and_unavailable(only: parent&.only_formula_or_cask, method: nil) @to_formulae_casks_unknowns ||= {} @to_formulae_casks_unknowns[method] = downcased_unique_named.map do |name| - load_formula_or_cask(name, only: only, method: method) + load_formula_or_cask(name, only:, method:) rescue FormulaOrCaskUnavailableError => e e end.uniq.freeze @@ -122,7 +122,7 @@ def load_formula_or_cask(name, only: nil, method: nil, warn: nil) begin formula = case method when nil, :factory - options = { warn: warn, force_bottle: @force_bottle, flags: @flags }.compact + options = { warn:, force_bottle: @force_bottle, flags: @flags }.compact Formulary.factory(name, *@override_spec, **options) when :resolve resolve_formula(name) @@ -155,8 +155,8 @@ def load_formula_or_cask(name, only: nil, method: nil, warn: nil) begin config = Cask::Config.from_args(@parent) if @cask_options - options = { warn: warn }.compact - cask = Cask::CaskLoader.load(name, config: config, **options) + options = { warn: }.compact + cask = Cask::CaskLoader.load(name, config:, **options) if unreadable_error.present? onoe <<~EOS @@ -177,8 +177,8 @@ def load_formula_or_cask(name, only: nil, method: nil, warn: nil) # If we're trying to get a keg-like Cask, do our best to handle it # not being readable and return something that can be used. if want_keg_like_cask - cask_version = Cask::Cask.new(name, config: config).installed_version - cask = Cask::Cask.new(name, config: config) do + cask_version = Cask::Cask.new(name, config:).installed_version + cask = Cask::Cask.new(name, config:) do version cask_version if cask_version end return cask @@ -214,12 +214,12 @@ def resolve_formula(name) sig { params(uniq: T::Boolean).returns(T::Array[Formula]) } def to_resolved_formulae(uniq: true) - @to_resolved_formulae ||= to_formulae_and_casks(only: :formula, method: :resolve, uniq: uniq) + @to_resolved_formulae ||= to_formulae_and_casks(only: :formula, method: :resolve, uniq:) .freeze end def to_resolved_formulae_to_casks(only: parent&.only_formula_or_cask) - to_formulae_to_casks(only: only, method: :resolve) + to_formulae_to_casks(only:, method: :resolve) end LOCAL_PATH_REGEX = %r{^/|[.]|/$} @@ -314,7 +314,7 @@ def to_kegs_to_casks(only: parent&.only_formula_or_cask, ignore_unavailable: nil method = all_kegs ? :kegs : :default_kegs @to_kegs_to_casks ||= {} @to_kegs_to_casks[method] ||= - to_formulae_and_casks(only: only, ignore_unavailable: ignore_unavailable, method: method) + to_formulae_and_casks(only:, ignore_unavailable:, method:) .partition { |o| o.is_a?(Keg) } .map(&:freeze).freeze end @@ -417,8 +417,10 @@ def resolve_default_keg(name) def warn_if_cask_conflicts(ref, loaded_type) message = "Treating #{ref} as a #{loaded_type}." begin - cask = Cask::CaskLoader.load ref - message += " For the cask, use #{cask.tap.name}/#{cask.token}" if cask.tap.present? + cask = Cask::CaskLoader.load(ref, warn: false) + message += " For the cask, " + message += "use #{cask.tap.name}/#{cask.token} or " if cask.tap + message += "specify the `--cask` flag." rescue Cask::CaskUnreadableError => e # Need to rescue before `CaskUnavailableError` (superclass of this) # The cask was found, but there's a problem with its implementation diff --git a/Library/Homebrew/cli/parser.rb b/Library/Homebrew/cli/parser.rb index ca51b661110125..b9dcb1a84f7a6b 100644 --- a/Library/Homebrew/cli/parser.rb +++ b/Library/Homebrew/cli/parser.rb @@ -159,8 +159,8 @@ def switch(*names, description: nil, replacement: nil, env: nil, depends_on: nil global_switch = names.first.is_a?(Symbol) return if global_switch - description = option_description(description, *names, hidden: hidden) - process_option(*names, description, type: :switch, hidden: hidden) unless disable + description = option_description(description, *names, hidden:) + process_option(*names, description, type: :switch, hidden:) unless disable if replacement || disable description += " (#{disable ? "disabled" : "deprecated"}#{"; replaced by #{replacement}" if replacement})" @@ -171,11 +171,11 @@ def switch(*names, description: nil, replacement: nil, env: nil, depends_on: nil odeprecated "the `#{names.first}` switch", replacement, disable: disable if !replacement.nil? || disable value = true if names.none? { |name| name.start_with?("--[no-]") } - set_switch(*names, value: value, from: :args) + set_switch(*names, value:, from: :args) end names.each do |name| - set_constraints(name, depends_on: depends_on) + set_constraints(name, depends_on:) end env_value = value_for_env(env) @@ -211,8 +211,8 @@ def usage_banner_text def comma_array(name, description: nil, hidden: false) name = name.chomp "=" - description = option_description(description, name, hidden: hidden) - process_option(name, description, type: :comma_array, hidden: hidden) + description = option_description(description, name, hidden:) + process_option(name, description, type: :comma_array, hidden:) @parser.on(name, OptionParser::REQUIRED_ARGUMENT, Array, *wrap_option_desc(description)) do |list| @args[option_to_name(name)] = list end @@ -225,9 +225,9 @@ def flag(*names, description: nil, replacement: nil, depends_on: nil, hidden: fa [OptionParser::OPTIONAL_ARGUMENT, :optional_flag] end names.map! { |name| name.chomp "=" } - description = option_description(description, *names, hidden: hidden) + description = option_description(description, *names, hidden:) if replacement.nil? - process_option(*names, description, type: flag_type, hidden: hidden) + process_option(*names, description, type: flag_type, hidden:) else description += " (disabled#{"; replaced by #{replacement}" if replacement.present?})" end @@ -240,7 +240,7 @@ def flag(*names, description: nil, replacement: nil, depends_on: nil, hidden: fa end names.each do |name| - set_constraints(name, depends_on: depends_on) + set_constraints(name, depends_on:) end end @@ -329,9 +329,9 @@ def parse(argv = ARGV.freeze, ignore_invalid_options: false) name = o.flag description = "`#{f.name}`: #{o.description}" if name.end_with? "=" - flag name, description: description + flag(name, description:) else - switch name, description: description + switch name, description: end conflicts "--cask", name @@ -339,7 +339,7 @@ def parse(argv = ARGV.freeze, ignore_invalid_options: false) end end - remaining, non_options = parse_remaining(argv, ignore_invalid_options: ignore_invalid_options) + remaining, non_options = parse_remaining(argv, ignore_invalid_options:) named_args = if ignore_invalid_options [] @@ -601,11 +601,11 @@ def check_named_args(args) exception = if @min_named_args && @max_named_args && @min_named_args == @max_named_args && args.size != @max_named_args - NumberOfNamedArgumentsError.new(@min_named_args, types: types) + NumberOfNamedArgumentsError.new(@min_named_args, types:) elsif @min_named_args && args.size < @min_named_args - MinNamedArgumentsError.new(@min_named_args, types: types) + MinNamedArgumentsError.new(@min_named_args, types:) elsif @max_named_args && args.size > @max_named_args - MaxNamedArgumentsError.new(@max_named_args, types: types) + MaxNamedArgumentsError.new(@max_named_args, types:) end raise exception if exception @@ -679,7 +679,7 @@ def initialize(arg1, arg2, missing: false) class OptionConflictError < UsageError def initialize(args) - args_list = args.map(&Formatter.public_method(:option)) + args_list = args.map { Formatter.option(_1) } .join(" and ") super "Options #{args_list} are mutually exclusive." end diff --git a/Library/Homebrew/cmd/--cache.rb b/Library/Homebrew/cmd/--cache.rb index bfe862b635ec49..9939ed050bd5f5 100644 --- a/Library/Homebrew/cmd/--cache.rb +++ b/Library/Homebrew/cmd/--cache.rb @@ -63,9 +63,9 @@ def self.__cache ref = formula.loaded_from_api? ? formula.full_name : formula.path os_arch_combinations.each do |os, arch| - SimulateSystem.with os: os, arch: arch do + SimulateSystem.with(os:, arch:) do formula = Formulary.factory(ref) - print_formula_cache(formula, os: os, arch: arch, args: args) + print_formula_cache(formula, os:, arch:, args:) end end else @@ -75,7 +75,7 @@ def self.__cache os_arch_combinations.each do |os, arch| next if os == :linux - SimulateSystem.with os: os, arch: arch do + SimulateSystem.with(os:, arch:) do cask = Cask::CaskLoader.load(ref) print_cask_cache(cask) end @@ -97,7 +97,7 @@ def self.print_formula_cache(formula, os:, arch:, args:) bottle_tag = if (bottle_tag = args.bottle_tag&.to_sym) Utils::Bottles::Tag.from_symbol(bottle_tag) else - Utils::Bottles::Tag.new(system: os, arch: arch) + Utils::Bottles::Tag.new(system: os, arch:) end bottle = formula.bottle_for_tag(bottle_tag) diff --git a/Library/Homebrew/cmd/cleanup.rb b/Library/Homebrew/cmd/cleanup.rb index 225696d51d2e37..470e08c7e3cf98 100644 --- a/Library/Homebrew/cmd/cleanup.rb +++ b/Library/Homebrew/cmd/cleanup.rb @@ -48,7 +48,7 @@ def cleanup end end - cleanup = Cleanup.new(*args.named, dry_run: args.dry_run?, scrub: args.s?, days: days) + cleanup = Cleanup.new(*args.named, dry_run: args.dry_run?, scrub: args.s?, days:) if args.prune_prefix? cleanup.prune_prefix_symlinks_and_directories return diff --git a/Library/Homebrew/cmd/deps.rb b/Library/Homebrew/cmd/deps.rb index f0e4bcdd067a5a..2a664ebaa0894d 100644 --- a/Library/Homebrew/cmd/deps.rb +++ b/Library/Homebrew/cmd/deps.rb @@ -119,7 +119,7 @@ def self.deps end if args.graph? - dot_code = dot_code(dependents, recursive: recursive, args: args) + dot_code = dot_code(dependents, recursive:, args:) if args.dot? puts dot_code else @@ -128,15 +128,15 @@ def self.deps return end - puts_deps_tree dependents, recursive: recursive, args: args + puts_deps_tree(dependents, recursive:, args:) return elsif all - puts_deps sorted_dependents( - Formula.all(eval_all: args.eval_all?) + Cask::Cask.all(eval_all: args.eval_all?), - ), recursive: recursive, args: args + puts_deps(sorted_dependents( + Formula.all(eval_all: args.eval_all?) + Cask::Cask.all(eval_all: args.eval_all?), + ), recursive:, args:) return elsif !args.no_named? && args.for_each? - puts_deps sorted_dependents(args.named.to_formulae_and_casks), recursive: recursive, args: args + puts_deps(sorted_dependents(args.named.to_formulae_and_casks), recursive:, args:) return end @@ -151,16 +151,16 @@ def self.deps else sorted_dependents(Formula.installed + Cask::Caskroom.casks) end - puts_deps sorted_dependents_formulae_and_casks, recursive: recursive, args: args + puts_deps(sorted_dependents_formulae_and_casks, recursive:, args:) return end dependents = dependents(args.named.to_formulae_and_casks) check_head_spec(dependents) if args.HEAD? - all_deps = deps_for_dependents(dependents, recursive: recursive, args: args, &(args.union? ? :| : :&)) - condense_requirements(all_deps, args: args) - all_deps.map! { |d| dep_display_name(d, args: args) } + all_deps = deps_for_dependents(dependents, recursive:, args:, &(args.union? ? :| : :&)) + condense_requirements(all_deps, args:) + all_deps.map! { |d| dep_display_name(d, args:) } all_deps.uniq! all_deps.sort! unless args.topological? puts all_deps @@ -218,7 +218,7 @@ def self.deps_for_dependent(dependency, args:, recursive: false) end def self.deps_for_dependents(dependents, args:, recursive: false, &block) - dependents.map { |d| deps_for_dependent(d, recursive: recursive, args: args) }.reduce(&block) + dependents.map { |d| deps_for_dependent(d, recursive:, args:) }.reduce(&block) end def self.check_head_spec(dependents) @@ -230,10 +230,10 @@ def self.check_head_spec(dependents) def self.puts_deps(dependents, args:, recursive: false) check_head_spec(dependents) if args.HEAD? dependents.each do |dependent| - deps = deps_for_dependent(dependent, recursive: recursive, args: args) - condense_requirements(deps, args: args) + deps = deps_for_dependent(dependent, recursive:, args:) + condense_requirements(deps, args:) deps.sort_by!(&:name) - deps.map! { |d| dep_display_name(d, args: args) } + deps.map! { |d| dep_display_name(d, args:) } puts "#{dependent.full_name}: #{deps.join(" ")}" end end @@ -241,7 +241,7 @@ def self.puts_deps(dependents, args:, recursive: false) def self.dot_code(dependents, recursive:, args:) dep_graph = {} dependents.each do |d| - graph_deps(d, dep_graph: dep_graph, recursive: recursive, args: args) + graph_deps(d, dep_graph:, recursive:, args:) end dot_code = dep_graph.map do |d, deps| @@ -264,7 +264,7 @@ def self.dot_code(dependents, recursive:, args:) def self.graph_deps(formula, dep_graph:, recursive:, args:) return if dep_graph.key?(formula) - dependables = dependables(formula, args: args) + dependables = dependables(formula, args:) dep_graph[formula] = dependables return unless recursive @@ -272,9 +272,9 @@ def self.graph_deps(formula, dep_graph:, recursive:, args:) next unless dep.is_a? Dependency graph_deps(Formulary.factory(dep.name), - dep_graph: dep_graph, + dep_graph:, recursive: true, - args: args) + args:) end end @@ -282,7 +282,7 @@ def self.puts_deps_tree(dependents, args:, recursive: false) check_head_spec(dependents) if args.HEAD? dependents.each do |d| puts d.full_name - recursive_deps_tree(d, dep_stack: [], prefix: "", recursive: recursive, args: args) + recursive_deps_tree(d, dep_stack: [], prefix: "", recursive:, args:) puts end end @@ -297,7 +297,7 @@ def self.dependables(formula, args:) end def self.recursive_deps_tree(formula, dep_stack:, prefix:, recursive:, args:) - dependables = dependables(formula, args: args) + dependables = dependables(formula, args:) max = dependables.length - 1 dep_stack.push formula.name dependables.each_with_index do |dep, i| @@ -307,7 +307,7 @@ def self.recursive_deps_tree(formula, dep_stack:, prefix:, recursive:, args:) "├──" end - display_s = "#{tree_lines} #{dep_display_name(dep, args: args)}" + display_s = "#{tree_lines} #{dep_display_name(dep, args:)}" # Detect circular dependencies and consider them a failure if present. is_circular = dep_stack.include?(dep.name) @@ -329,10 +329,10 @@ def self.recursive_deps_tree(formula, dep_stack:, prefix:, recursive:, args:) next unless dep.is_a? Dependency recursive_deps_tree(Formulary.factory(dep.name), - dep_stack: dep_stack, + dep_stack:, prefix: prefix + prefix_addition, recursive: true, - args: args) + args:) end dep_stack.pop diff --git a/Library/Homebrew/cmd/desc.rb b/Library/Homebrew/cmd/desc.rb index 681d8b86dfd569..aa43dc61df5bbb 100644 --- a/Library/Homebrew/cmd/desc.rb +++ b/Library/Homebrew/cmd/desc.rb @@ -68,7 +68,7 @@ def desc else query = args.named.join(" ") string_or_regex = Search.query_regexp(query) - Search.search_descriptions(string_or_regex, args, search_type: search_type) + Search.search_descriptions(string_or_regex, args, search_type:) end end end diff --git a/Library/Homebrew/cmd/developer.rb b/Library/Homebrew/cmd/developer.rb old mode 100755 new mode 100644 diff --git a/Library/Homebrew/cmd/fetch.rb b/Library/Homebrew/cmd/fetch.rb index b8efff19cd7a11..028cc3bc4928ac 100644 --- a/Library/Homebrew/cmd/fetch.rb +++ b/Library/Homebrew/cmd/fetch.rb @@ -98,7 +98,7 @@ def self.fetch ref = formula.loaded_from_api? ? formula.full_name : formula.path os_arch_combinations.each do |os, arch| - SimulateSystem.with os: os, arch: arch do + SimulateSystem.with(os:, arch:) do formula = Formulary.factory(ref, args.HEAD? ? :head : :stable) formula.print_tap_action verb: "Fetching" @@ -118,7 +118,7 @@ def self.fetch bottle_tag = if (bottle_tag = args.bottle_tag&.to_sym) Utils::Bottles::Tag.from_symbol(bottle_tag) else - Utils::Bottles::Tag.new(system: os, arch: arch) + Utils::Bottles::Tag.new(system: os, arch:) end bottle = formula.bottle_for_tag(bottle_tag) @@ -131,10 +131,10 @@ def self.fetch begin bottle.fetch_tab rescue DownloadError - retry if retry_fetch?(bottle, args: args) + retry if retry_fetch?(bottle, args:) raise end - fetch_formula(bottle, args: args) + fetch_formula(bottle, args:) rescue Interrupt raise rescue => e @@ -150,14 +150,14 @@ def self.fetch next if fetched_bottle - fetch_formula(formula, args: args) + fetch_formula(formula, args:) formula.resources.each do |r| - fetch_resource(r, args: args) - r.patches.each { |p| fetch_patch(p, args: args) if p.external? } + fetch_resource(r, args:) + r.patches.each { |p| fetch_patch(p, args:) if p.external? } end - formula.patchlist.each { |p| fetch_patch(p, args: args) if p.external? } + formula.patchlist.each { |p| fetch_patch(p, args:) if p.external? } end end else @@ -167,7 +167,7 @@ def self.fetch os_arch_combinations.each do |os, arch| next if os == :linux - SimulateSystem.with os: os, arch: arch do + SimulateSystem.with(os:, arch:) do cask = Cask::CaskLoader.load(ref) if cask.url.nil? || cask.sha256.nil? @@ -178,8 +178,8 @@ def self.fetch quarantine = args.quarantine? quarantine = true if quarantine.nil? - download = Cask::Download.new(cask, quarantine: quarantine) - fetch_cask(download, args: args) + download = Cask::Download.new(cask, quarantine:) + fetch_cask(download, args:) end end end @@ -188,28 +188,28 @@ def self.fetch def self.fetch_resource(resource, args:) puts "Resource: #{resource.name}" - fetch_fetchable resource, args: args + fetch_fetchable resource, args: rescue ChecksumMismatchError => e - retry if retry_fetch?(resource, args: args) + retry if retry_fetch?(resource, args:) opoo "Resource #{resource.name} reports different sha256: #{e.expected}" end def self.fetch_formula(formula, args:) - fetch_fetchable formula, args: args + fetch_fetchable(formula, args:) rescue ChecksumMismatchError => e - retry if retry_fetch?(formula, args: args) + retry if retry_fetch?(formula, args:) opoo "Formula reports different sha256: #{e.expected}" end def self.fetch_cask(cask_download, args:) - fetch_fetchable cask_download, args: args + fetch_fetchable(cask_download, args:) rescue ChecksumMismatchError => e - retry if retry_fetch?(cask_download, args: args) + retry if retry_fetch?(cask_download, args:) opoo "Cask reports different sha256: #{e.expected}" end def self.fetch_patch(patch, args:) - fetch_fetchable patch, args: args + fetch_fetchable(patch, args:) rescue ChecksumMismatchError => e opoo "Patch reports different sha256: #{e.expected}" Homebrew.failed = true @@ -242,7 +242,7 @@ def self.fetch_fetchable(formula, args:) begin download = formula.fetch(verify_download_integrity: false) rescue DownloadError - retry if retry_fetch?(formula, args: args) + retry if retry_fetch?(formula, args:) raise end diff --git a/Library/Homebrew/cmd/gist-logs.rb b/Library/Homebrew/cmd/gist-logs.rb index 829cec0c4b410d..f18e99d67be41b 100644 --- a/Library/Homebrew/cmd/gist-logs.rb +++ b/Library/Homebrew/cmd/gist-logs.rb @@ -125,6 +125,6 @@ def gist_logs Install.perform_preinstall_checks(all_fatal: true) Install.perform_build_from_source_checks(all_fatal: true) - gistify_logs(args.named.to_resolved_formulae.first, args: args) + gistify_logs(args.named.to_resolved_formulae.first, args:) end end diff --git a/Library/Homebrew/cmd/info.rb b/Library/Homebrew/cmd/info.rb index d52fe812b7f726..477cf6709f3a68 100644 --- a/Library/Homebrew/cmd/info.rb +++ b/Library/Homebrew/cmd/info.rb @@ -96,11 +96,11 @@ def info end end - print_analytics(args: args) + print_analytics(args:) elsif args.json all = args.eval_all? - print_json(all, args: args) + print_json(all, args:) elsif args.github? raise FormulaOrCaskUnspecifiedError if args.no_named? @@ -108,7 +108,7 @@ def info elsif args.no_named? print_statistics else - print_info(args: args) + print_info(args:) end end @@ -123,7 +123,7 @@ def print_statistics sig { params(args: CLI::Args).void } def print_analytics(args:) if args.no_named? - Utils::Analytics.output(args: args) + Utils::Analytics.output(args:) return end @@ -132,11 +132,11 @@ def print_analytics(args:) case obj when Formula - Utils::Analytics.formula_output(obj, args: args) + Utils::Analytics.formula_output(obj, args:) when Cask::Cask - Utils::Analytics.cask_output(obj, args: args) + Utils::Analytics.cask_output(obj, args:) when FormulaOrCaskUnavailableError - Utils::Analytics.output(filter: obj.name, args: args) + Utils::Analytics.output(filter: obj.name, args:) else raise end @@ -150,9 +150,9 @@ def print_info(args:) case obj when Formula - info_formula(obj, args: args) + info_formula(obj, args:) when Cask::Cask - info_cask(obj, args: args) + info_cask(obj, args:) when FormulaUnreadableError, FormulaClassUnavailableError, TapFormulaUnreadableError, TapFormulaClassUnavailableError, Cask::CaskUnreadableError @@ -341,7 +341,7 @@ def info_formula(formula, args:) caveats = Caveats.new(formula) ohai "Caveats", caveats.to_s unless caveats.empty? - Utils::Analytics.formula_output(formula, args: args) + Utils::Analytics.formula_output(formula, args:) end def decorate_dependencies(dependencies) diff --git a/Library/Homebrew/cmd/install.rb b/Library/Homebrew/cmd/install.rb index ca9293f15f85e1..921bcd9c511c25 100644 --- a/Library/Homebrew/cmd/install.rb +++ b/Library/Homebrew/cmd/install.rb @@ -258,7 +258,7 @@ def self.install require_sha: args.require_sha?, skip_cask_deps: args.skip_cask_deps?, verbose: args.verbose?, - args: args, + args:, ) end end diff --git a/Library/Homebrew/cmd/list.rb b/Library/Homebrew/cmd/list.rb index 4267c7a11c9ef1..1b69e2596e6f97 100644 --- a/Library/Homebrew/cmd/list.rb +++ b/Library/Homebrew/cmd/list.rb @@ -86,10 +86,10 @@ def self.list puts full_cask_names if full_cask_names.present? end elsif args.pinned? - filtered_list(args: args) + filtered_list(args:) elsif args.versions? - filtered_list(args: args) unless args.cask? - list_casks(args: args) if args.cask? || (!args.formula? && !args.multiple? && args.no_named?) + filtered_list(args:) unless args.cask? + list_casks(args:) if args.cask? || (!args.formula? && !args.multiple? && args.no_named?) elsif args.no_named? ENV["CLICOLOR"] = nil @@ -117,7 +117,7 @@ def self.list system_command! "find", args: casks.map(&:caskroom_path) + find_args, print_stdout: true if casks.present? else kegs.each { |keg| PrettyListing.new keg } if kegs.present? - list_casks(args: args) if casks.present? + list_casks(args:) if casks.present? end end end diff --git a/Library/Homebrew/cmd/log.rb b/Library/Homebrew/cmd/log.rb index 35a6033de64796..06223b4b4759a1 100644 --- a/Library/Homebrew/cmd/log.rb +++ b/Library/Homebrew/cmd/log.rb @@ -41,11 +41,11 @@ def self.log ENV["PATH"] = PATH.new(ORIGINAL_PATHS).to_s if args.no_named? - git_log HOMEBREW_REPOSITORY, args: args + git_log(HOMEBREW_REPOSITORY, args:) else path = args.named.to_paths.first tap = Tap.from_path(path) - git_log path.dirname, path, tap, args: args + git_log path.dirname, path, tap, args: end end diff --git a/Library/Homebrew/cmd/nodenv-sync.rb b/Library/Homebrew/cmd/nodenv-sync.rb old mode 100755 new mode 100644 diff --git a/Library/Homebrew/cmd/options.rb b/Library/Homebrew/cmd/options.rb index e95b5c8feb58c3..6d93d75833f088 100644 --- a/Library/Homebrew/cmd/options.rb +++ b/Library/Homebrew/cmd/options.rb @@ -35,9 +35,9 @@ def options all = args.eval_all? if all - puts_options Formula.all(eval_all: args.eval_all?).sort, args: args + puts_options(Formula.all(eval_all: args.eval_all?).sort, args:) elsif args.installed? - puts_options Formula.installed.sort, args: args + puts_options(Formula.installed.sort, args:) elsif args.command.present? cmd_options = Commands.command_options(args.command) odie "Unknown command: #{args.command}" if cmd_options.nil? @@ -51,7 +51,7 @@ def options elsif args.no_named? raise FormulaUnspecifiedError else - puts_options args.named.to_formulae, args: args + puts_options args.named.to_formulae, args: end end diff --git a/Library/Homebrew/cmd/outdated.rb b/Library/Homebrew/cmd/outdated.rb index 6df2c6e2d25530..f881b3ea61bd48 100644 --- a/Library/Homebrew/cmd/outdated.rb +++ b/Library/Homebrew/cmd/outdated.rb @@ -55,16 +55,16 @@ def self.outdated odie "`brew outdated --json=v1` is no longer supported. Use brew outdated --json=v2 instead." when :v2, :default formulae, casks = if args.formula? - [outdated_formulae(args: args), []] + [outdated_formulae(args:), []] elsif args.cask? - [[], outdated_casks(args: args)] + [[], outdated_casks(args:)] else - outdated_formulae_casks args: args + outdated_formulae_casks(args:) end json = { - "formulae" => json_info(formulae, args: args), - "casks" => json_info(casks, args: args), + "formulae" => json_info(formulae, args:), + "casks" => json_info(casks, args:), } puts JSON.pretty_generate(json) @@ -72,14 +72,14 @@ def self.outdated else outdated = if args.formula? - outdated_formulae args: args + outdated_formulae(args:) elsif args.cask? - outdated_casks args: args + outdated_casks(args:) else - outdated_formulae_casks(args: args).flatten + outdated_formulae_casks(args:).flatten end - print_outdated(outdated, args: args) + print_outdated(outdated, args:) end Homebrew.failed = args.named.present? && outdated.present? @@ -137,7 +137,7 @@ def self.json_info(formulae_or_casks, args:) { name: f.full_name, installed_versions: outdated_versions.map(&:to_s), - current_version: current_version, + current_version:, pinned: f.pinned?, pinned_version: f.pinned_version } else @@ -166,14 +166,14 @@ def self.json_version(version) end def self.outdated_formulae(args:) - select_outdated((args.named.to_resolved_formulae.presence || Formula.installed), args: args).sort + select_outdated((args.named.to_resolved_formulae.presence || Formula.installed), args:).sort end def self.outdated_casks(args:) if args.named.present? - select_outdated(args.named.to_casks, args: args) + select_outdated(args.named.to_casks, args:) else - select_outdated(Cask::Caskroom.casks, args: args) + select_outdated(Cask::Caskroom.casks, args:) end end @@ -185,7 +185,7 @@ def self.outdated_formulae_casks(args:) casks = Cask::Caskroom.casks end - [select_outdated(formulae, args: args).sort, select_outdated(casks, args: args)] + [select_outdated(formulae, args:).sort, select_outdated(casks, args:)] end def self.select_outdated(formulae_or_casks, args:) diff --git a/Library/Homebrew/cmd/postgresql-upgrade-database.rb b/Library/Homebrew/cmd/postgresql-upgrade-database.rb old mode 100755 new mode 100644 diff --git a/Library/Homebrew/cmd/rbenv-sync.rb b/Library/Homebrew/cmd/rbenv-sync.rb old mode 100755 new mode 100644 diff --git a/Library/Homebrew/cmd/readall.rb b/Library/Homebrew/cmd/readall.rb index e20db93e364a03..530c41e3ee4013 100644 --- a/Library/Homebrew/cmd/readall.rb +++ b/Library/Homebrew/cmd/readall.rb @@ -57,7 +57,7 @@ def readall raise UsageError, "`brew readall` needs a tap or `--eval-all` passed or `HOMEBREW_EVAL_ALL` set!" end - Tap.select(&:installed?) + Tap.installed else args.named.to_installed_taps end diff --git a/Library/Homebrew/cmd/tap.rb b/Library/Homebrew/cmd/tap.rb index f3f751ead323bf..86005e7cb5fabb 100644 --- a/Library/Homebrew/cmd/tap.rb +++ b/Library/Homebrew/cmd/tap.rb @@ -34,8 +34,7 @@ def tap_args replacement: false, disable: true switch "--[no-]force-auto-update", - description: "Auto-update tap even if it is not hosted on GitHub. By default, only taps " \ - "hosted on GitHub are auto-updated (for performance reasons)." + hidden: true switch "--custom-remote", description: "Install or change a tap with a custom remote. Useful for mirrors." switch "--repair", @@ -55,21 +54,20 @@ def tap args = tap_args.parse if args.repair? - Tap.select(&:installed?).each do |tap| + Tap.installed.each do |tap| tap.link_completions_and_manpages tap.fix_remote_configuration end elsif args.no_named? - puts Tap.select(&:installed?) + puts Tap.installed.sort_by(&:name) else tap = Tap.fetch(args.named.first) begin - tap.install clone_target: args.named.second, - force_auto_update: args.force_auto_update?, - custom_remote: args.custom_remote?, - quiet: args.quiet?, - verify: args.eval_all? || Homebrew::EnvConfig.eval_all?, - force: args.force? + tap.install clone_target: args.named.second, + custom_remote: args.custom_remote?, + quiet: args.quiet?, + verify: args.eval_all? || Homebrew::EnvConfig.eval_all?, + force: args.force? rescue TapRemoteMismatchError, TapNoCustomRemoteError => e odie e rescue TapAlreadyTappedError diff --git a/Library/Homebrew/cmd/uninstall.rb b/Library/Homebrew/cmd/uninstall.rb index 65642fb159c00a..4c62dc8095a0b8 100644 --- a/Library/Homebrew/cmd/uninstall.rb +++ b/Library/Homebrew/cmd/uninstall.rb @@ -59,7 +59,7 @@ def uninstall Uninstall.uninstall_kegs( kegs_by_rack, - casks: casks, + casks:, force: args.force?, ignore_dependencies: args.ignore_dependencies?, named_args: args.named, diff --git a/Library/Homebrew/cmd/untap.rb b/Library/Homebrew/cmd/untap.rb index 90696f7f5512b7..b734ae04e87d58 100644 --- a/Library/Homebrew/cmd/untap.rb +++ b/Library/Homebrew/cmd/untap.rb @@ -2,12 +2,11 @@ # frozen_string_literal: true require "cli/parser" +require "untap" module Homebrew - module_function - sig { returns(CLI::Parser) } - def untap_args + def self.untap_args Homebrew::CLI::Parser.new do description <<~EOS Remove a tapped formula repository. @@ -20,46 +19,15 @@ def untap_args end sig { void } - def untap + def self.untap args = untap_args.parse args.named.to_installed_taps.each do |tap| odie "Untapping #{tap} is not allowed" if tap.core_tap? && Homebrew::EnvConfig.no_install_from_api? if Homebrew::EnvConfig.no_install_from_api? || (!tap.core_tap? && !tap.core_cask_tap?) - installed_formula_names = T.let(nil, T.nilable(T::Set[String])) - installed_tap_formulae = tap.formula_names.filter_map do |formula_name| - # initialise lazily in case there's no formulae in this tap - installed_formula_names ||= Set.new(Formula.installed_formula_names) - next unless installed_formula_names.include?(formula_name) - - formula = begin - Formulary.factory("#{tap.name}/#{formula_name}") - rescue - # Don't blow up because of a single unavailable formula. - next - end - - # Can't use Formula#any_version_installed? because it doesn't consider - # taps correctly. - formula if formula.installed_kegs.any? { |keg| keg.tab.tap == tap } - end - - installed_cask_tokens = T.let(nil, T.nilable(T::Set[String])) - installed_tap_casks = tap.cask_tokens.filter_map do |cask_token| - # initialise lazily in case there's no casks in this tap - installed_cask_tokens ||= Set.new(Cask::Caskroom.tokens) - next unless installed_cask_tokens.include?(cask_token) - - cask = begin - Cask::CaskLoader.load("#{tap.name}/#{cask_token}") - rescue - # Don't blow up because of a single unavailable cask. - next - end - - cask if cask.installed? - end + installed_tap_formulae = Untap.installed_formulae_for(tap:) + installed_tap_casks = Untap.installed_casks_for(tap:) if installed_tap_formulae.present? || installed_tap_casks.present? installed_names = (installed_tap_formulae + installed_tap_casks.map(&:token)).join("\n") diff --git a/Library/Homebrew/cmd/update-report.rb b/Library/Homebrew/cmd/update-report.rb index e2ed7f96a7104f..0c455f3e4b0bb2 100644 --- a/Library/Homebrew/cmd/update-report.rb +++ b/Library/Homebrew/cmd/update-report.rb @@ -109,7 +109,7 @@ def output_update_report odie "update-report should not be called directly!" if initial_revision.empty? || current_revision.empty? if initial_revision != current_revision - auto_update_header args: args + auto_update_header(args:) updated = true @@ -146,7 +146,7 @@ def output_update_report hub = ReporterHub.new updated_taps = [] - Tap.select(&:installed?).each do |tap| + Tap.installed.each do |tap| next if !tap.git? || tap.git_repo.origin_url.nil? next if (tap.core_tap? || tap.core_cask_tap?) && !Homebrew::EnvConfig.no_install_from_api? @@ -219,7 +219,7 @@ def output_update_report end unless updated_taps.empty? - auto_update_header args: args + auto_update_header(args:) puts "Updated #{Utils.pluralize("tap", updated_taps.count, include_count: true)} (#{updated_taps.to_sentence})." updated = true end @@ -254,7 +254,7 @@ def output_update_report Commands.rebuild_commands_completion_list link_completions_manpages_and_docs - Tap.select(&:installed?).each(&:link_completions_and_manpages) + Tap.installed.each(&:link_completions_and_manpages) failed_fetch_dirs = ENV["HOMEBREW_MISSING_REMOTE_REF_DIRS"]&.split("\n") if failed_fetch_dirs.present? @@ -689,7 +689,7 @@ def migrate_formula_rename(force:, verbose:) end next if oldnames_to_migrate.empty? - Migrator.migrate_if_needed(formula, force: force) + Migrator.migrate_if_needed(formula, force:) end end @@ -743,7 +743,7 @@ def select_formula_or_cask(key) def add(reporter, auto_update: false) @reporters << reporter - report = reporter.report(auto_update: auto_update).delete_if { |_k, v| v.empty? } + report = reporter.report(auto_update:).delete_if { |_k, v| v.empty? } @hash.update(report) { |_key, oldval, newval| oldval.concat(newval) } end diff --git a/Library/Homebrew/cmd/update-reset.sh b/Library/Homebrew/cmd/update-reset.sh index f87d623b257ee4..be92b1e37b77c5 100644 --- a/Library/Homebrew/cmd/update-reset.sh +++ b/Library/Homebrew/cmd/update-reset.sh @@ -75,9 +75,21 @@ homebrew-update-reset() { echo ohai "Resetting ${DIR}..." - head="$(git -C "${DIR}" symbolic-ref refs/remotes/origin/HEAD)" - head="${head#refs/remotes/origin/}" - git -C "${DIR}" checkout --force -B "${head}" origin/HEAD + # HOMEBREW_* variables here may all set by bin/brew or the user + # shellcheck disable=SC2154 + if [[ "${DIR}" == "${HOMEBREW_REPOSITORY}" && + (-n "${HOMEBREW_UPDATE_TO_TAG}" || + (-z "${HOMEBREW_DEVELOPER}" && -z "${HOMEBREW_DEV_CMD_RUN}")) ]] + then + local latest_git_tag + latest_git_tag="$(git -C "${DIR}" tag --list --sort="-version:refname" | head -n1)" + + git -C "${DIR}" checkout --force -B stable "refs/tags/${latest_git_tag}" + else + head="$(git -C "${DIR}" symbolic-ref refs/remotes/origin/HEAD)" + head="${head#refs/remotes/origin/}" + git -C "${DIR}" checkout --force -B "${head}" origin/HEAD + fi echo done } diff --git a/Library/Homebrew/cmd/update.sh b/Library/Homebrew/cmd/update.sh index 4df690c542eae7..b3806891df25cf 100644 --- a/Library/Homebrew/cmd/update.sh +++ b/Library/Homebrew/cmd/update.sh @@ -622,6 +622,26 @@ EOS [[ -n "${SKIP_FETCH_CORE_REPOSITORY}" && "${DIR}" == "${HOMEBREW_CORE_REPOSITORY}" ]] && continue fi + if [[ -z "${UPDATING_MESSAGE_SHOWN}" ]] + then + if [[ -n "${HOMEBREW_UPDATE_AUTO}" ]] + then + # Outputting a command but don't want to run it, hence single quotes. + # shellcheck disable=SC2016 + ohai 'Auto-updating Homebrew...' >&2 + if [[ -z "${HOMEBREW_NO_ENV_HINTS}" && -z "${HOMEBREW_AUTO_UPDATE_SECS}" ]] + then + # shellcheck disable=SC2016 + echo 'Adjust how often this is run with HOMEBREW_AUTO_UPDATE_SECS or disable with' >&2 + # shellcheck disable=SC2016 + echo 'HOMEBREW_NO_AUTO_UPDATE. Hide these hints with HOMEBREW_NO_ENV_HINTS (see `man brew`).' >&2 + fi + else + ohai 'Updating Homebrew...' >&2 + fi + UPDATING_MESSAGE_SHOWN=1 + fi + # The upstream repository's default branch may not be master; # check refs/remotes/origin/HEAD to see what the default # origin branch name is, and use that. If not set, fall back to "master". @@ -693,14 +713,6 @@ EOS # Touch FETCH_HEAD to confirm we've checked for an update. [[ -f "${DIR}/.git/FETCH_HEAD" ]] && touch "${DIR}/.git/FETCH_HEAD" [[ -z "${HOMEBREW_UPDATE_FORCE}" ]] && [[ "${UPSTREAM_SHA_HTTP_CODE}" == "304" ]] && exit - elif [[ -n "${HOMEBREW_UPDATE_AUTO}" ]] - then - FORCE_AUTO_UPDATE="$(git config homebrew.forceautoupdate 2>/dev/null || echo "false")" - if [[ "${FORCE_AUTO_UPDATE}" != "true" ]] - then - # Don't try to do a `git fetch` that may take longer than expected. - exit - fi fi # HOMEBREW_VERBOSE isn't modified here so ignore subshell warning. diff --git a/Library/Homebrew/cmd/upgrade.rb b/Library/Homebrew/cmd/upgrade.rb index ed712f3070f24e..9aa4d07187739a 100644 --- a/Library/Homebrew/cmd/upgrade.rb +++ b/Library/Homebrew/cmd/upgrade.rb @@ -75,6 +75,9 @@ def upgrade_args env: :display_install_times, description: "Print install times for each package at the end of the run.", }], + [:switch, "--overwrite", { + description: "Delete files that already exist in the prefix while linking.", + }], ].each do |args| options = args.pop send(*args, **options) @@ -137,8 +140,8 @@ def upgrade only_upgrade_formulae = formulae.present? && casks.blank? only_upgrade_casks = casks.present? && formulae.blank? - upgrade_outdated_formulae(formulae, args: args) unless only_upgrade_casks - upgrade_outdated_casks(casks, args: args) unless only_upgrade_formulae + upgrade_outdated_formulae(formulae, args:) unless only_upgrade_casks + upgrade_outdated_casks(casks, args:) unless only_upgrade_formulae Cleanup.periodic_clean!(dry_run: args.dry_run?) @@ -229,6 +232,7 @@ def upgrade_outdated_formulae(formulae, args:) keep_tmp: args.keep_tmp?, debug_symbols: args.debug_symbols?, force: args.force?, + overwrite: args.overwrite?, debug: args.debug?, quiet: args.quiet?, verbose: args.verbose?, @@ -269,7 +273,7 @@ def upgrade_outdated_casks(casks, args:) require_sha: args.require_sha?, skip_cask_deps: args.skip_cask_deps?, verbose: args.verbose?, - args: args, + args:, ) end end diff --git a/Library/Homebrew/cmd/uses.rb b/Library/Homebrew/cmd/uses.rb index d7d2e72b3d9786..211d679e5622ad 100644 --- a/Library/Homebrew/cmd/uses.rb +++ b/Library/Homebrew/cmd/uses.rb @@ -69,7 +69,7 @@ def self.uses # If the formula doesn't exist: fake the needed formula object name. # This is a legacy use of OpenStruct that should be refactored. # rubocop:disable Style/OpenStructUse - args.named.map { |name| OpenStruct.new name: name, full_name: name } + args.named.map { |name| OpenStruct.new name:, full_name: name } # rubocop:enable Style/OpenStructUse end @@ -80,7 +80,7 @@ def self.uses !args.include_optional? && !args.skip_recommended? - uses = intersection_of_dependents(use_runtime_dependents, used_formulae, args: args) + uses = intersection_of_dependents(use_runtime_dependents, used_formulae, args:) return if uses.empty? diff --git a/Library/Homebrew/commands.rb b/Library/Homebrew/commands.rb index 7d490c31e7ee60..d44418a0ce373f 100644 --- a/Library/Homebrew/commands.rb +++ b/Library/Homebrew/commands.rb @@ -116,7 +116,7 @@ def self.internal_developer_commands_paths def self.official_external_commands_paths(quiet:) OFFICIAL_CMD_TAPS.flat_map do |tap_name, cmds| tap = Tap.fetch(tap_name) - tap.install(quiet: quiet) unless tap.installed? + tap.install(quiet:) unless tap.installed? cmds.map(&method(:external_ruby_v2_cmd_path)).compact end end diff --git a/Library/Homebrew/compilers.rb b/Library/Homebrew/compilers.rb index 93c106a1026ac6..9133c6fa8f139c 100644 --- a/Library/Homebrew/compilers.rb +++ b/Library/Homebrew/compilers.rb @@ -54,7 +54,7 @@ def self.create(spec, &block) version = 9999 exact_major_match = false end - new(type, version, exact_major_match: exact_major_match, &block) + new(type, version, exact_major_match:, &block) end def fails_with?(compiler) diff --git a/Library/Homebrew/completions.rb b/Library/Homebrew/completions.rb index 4e60b8209aacb3..60d50f155587dd 100644 --- a/Library/Homebrew/completions.rb +++ b/Library/Homebrew/completions.rb @@ -72,7 +72,7 @@ module Completions sig { void } def self.link! Settings.write :linkcompletions, true - Tap.select(&:installed?).each do |tap| + Tap.installed.each do |tap| Utils::Link.link_completions tap.path, "brew completions link" end end @@ -80,7 +80,7 @@ def self.link! sig { void } def self.unlink! Settings.write :linkcompletions, false - Tap.select(&:installed?).each do |tap| + Tap.installed.each do |tap| next if tap.official? Utils::Link.unlink_completions tap.path @@ -94,7 +94,7 @@ def self.link_completions? sig { returns(T::Boolean) } def self.completions_to_link? - Tap.select(&:installed?).each do |tap| + Tap.installed.each do |tap| next if tap.official? SHELLS.each do |shell| diff --git a/Library/Homebrew/dependencies_helpers.rb b/Library/Homebrew/dependencies_helpers.rb index 64ead61a76fc83..0f0b6928a084c1 100644 --- a/Library/Homebrew/dependencies_helpers.rb +++ b/Library/Homebrew/dependencies_helpers.rb @@ -25,7 +25,7 @@ def recursive_includes(klass, root_dependent, includes, ignores) cache_key = "recursive_includes_#{includes}_#{ignores}" - klass.expand(root_dependent, cache_key: cache_key) do |dependent, dep| + klass.expand(root_dependent, cache_key:) do |dependent, dep| klass.prune if ignores.any? { |ignore| dep.public_send(ignore) } klass.prune if includes.none? do |include| # Ignore indirect test dependencies diff --git a/Library/Homebrew/dependency.rb b/Library/Homebrew/dependency.rb index d4ea978768595f..b11d2cff0a6e7a 100644 --- a/Library/Homebrew/dependency.rb +++ b/Library/Homebrew/dependency.rb @@ -74,7 +74,7 @@ def installed?(minimum_version: nil, minimum_revision: nil) end def satisfied?(inherited_options = [], minimum_version: nil, minimum_revision: nil) - installed?(minimum_version: minimum_version, minimum_revision: minimum_revision) && + installed?(minimum_version:, minimum_revision:) && missing_options(inherited_options).empty? end @@ -133,14 +133,14 @@ def expand(dependent, deps = dependent.deps, cache_key: nil, &block) when :skip next if @expand_stack.include? dep.name - expanded_deps.concat(expand(dep.to_formula, cache_key: cache_key, &block)) + expanded_deps.concat(expand(dep.to_formula, cache_key:, &block)) when :keep_but_prune_recursive_deps expanded_deps << dep else next if @expand_stack.include? dep.name dep_formula = dep.to_formula - expanded_deps.concat(expand(dep_formula, cache_key: cache_key, &block)) + expanded_deps.concat(expand(dep_formula, cache_key:, &block)) # Fixes names for renamed/aliased formulae. dep = dep.dup_with_formula_name(dep_formula) @@ -249,7 +249,7 @@ def hash sig { params(minimum_version: T.nilable(Version), minimum_revision: T.nilable(Integer)).returns(T::Boolean) } def installed?(minimum_version: nil, minimum_revision: nil) - use_macos_install? || super(minimum_version: minimum_version, minimum_revision: minimum_revision) + use_macos_install? || super(minimum_version:, minimum_revision:) end sig { returns(T::Boolean) } @@ -276,7 +276,7 @@ def uses_from_macos? sig { override.params(formula: Formula).returns(T.self_type) } def dup_with_formula_name(formula) - self.class.new(formula.full_name.to_s, tags, bounds: bounds) + self.class.new(formula.full_name.to_s, tags, bounds:) end sig { returns(String) } diff --git a/Library/Homebrew/description_cache_store.rb b/Library/Homebrew/description_cache_store.rb index f882e6f67c5f7e..24f1ed07f5d700 100644 --- a/Library/Homebrew/description_cache_store.rb +++ b/Library/Homebrew/description_cache_store.rb @@ -34,7 +34,7 @@ def populate_if_empty!(eval_all: Homebrew::EnvConfig.eval_all?) return unless eval_all return unless database.empty? - Formula.all(eval_all: eval_all).each { |f| update!(f.full_name, f.desc) } + Formula.all(eval_all:).each { |f| update!(f.full_name, f.desc) } end # Use an update report to update the {DescriptionCacheStore}. @@ -100,7 +100,7 @@ def populate_if_empty!(eval_all: Homebrew::EnvConfig.eval_all?) return unless eval_all return unless database.empty? - Cask::Cask.all(eval_all: eval_all) + Cask::Cask.all(eval_all:) .each { |c| update!(c.full_name, [c.name.join(", "), c.desc.presence]) } end diff --git a/Library/Homebrew/descriptions.rb b/Library/Homebrew/descriptions.rb index 725ff2354fe34a..80e9fa89df6cb2 100644 --- a/Library/Homebrew/descriptions.rb +++ b/Library/Homebrew/descriptions.rb @@ -11,7 +11,7 @@ class Descriptions # Given a regex, find all formulae whose specified fields contain a match. def self.search(string_or_regex, field, cache_store, eval_all = Homebrew::EnvConfig.eval_all?) - cache_store.populate_if_empty!(eval_all: eval_all) + cache_store.populate_if_empty!(eval_all:) results = case field when :name diff --git a/Library/Homebrew/dev-cmd/audit.rb b/Library/Homebrew/dev-cmd/audit.rb index 2b464047cc4083..9c065dd43db18c 100644 --- a/Library/Homebrew/dev-cmd/audit.rb +++ b/Library/Homebrew/dev-cmd/audit.rb @@ -189,7 +189,7 @@ def self.audit # Run tap audits first named_arg_taps = [*audit_formulae, *audit_casks].map(&:tap).uniq if !args.tap && !no_named_args - tap_problems = Tap.select(&:installed?).each_with_object({}) do |tap, problems| + tap_problems = Tap.installed.each_with_object({}) do |tap, problems| next if args.tap && tap != args.tap next if named_arg_taps&.exclude?(tap) @@ -210,20 +210,20 @@ def self.audit only = only_cops ? ["style"] : args.only options = { - new_formula: new_formula, - strict: strict, - online: online, + new_formula:, + strict:, + online:, git: args.git?, - only: only, + only:, except: args.except, - spdx_license_data: spdx_license_data, - spdx_exception_data: spdx_exception_data, + spdx_license_data:, + spdx_exception_data:, style_offenses: style_offenses&.for_path(f.path), - tap_audit: tap_audit, + tap_audit:, }.compact errors = os_arch_combinations.flat_map do |os, arch| - SimulateSystem.with os: os, arch: arch do + SimulateSystem.with(os:, arch:) do odebug "Auditing Formula #{f} on os #{os} and arch #{arch}" audit_proc = proc { FormulaAuditor.new(Formulary.factory(path), **options).tap(&:audit) } @@ -251,7 +251,7 @@ def self.audit errors = os_arch_combinations.flat_map do |os, arch| next [] if os == :linux - SimulateSystem.with os: os, arch: arch do + SimulateSystem.with(os:, arch:) do odebug "Auditing Cask #{cask} on os #{os} and arch #{arch}" Cask::Auditor.audit( diff --git a/Library/Homebrew/dev-cmd/bottle.rb b/Library/Homebrew/dev-cmd/bottle.rb index 24469cc7dee351..b082796d11470d 100644 --- a/Library/Homebrew/dev-cmd/bottle.rb +++ b/Library/Homebrew/dev-cmd/bottle.rb @@ -96,13 +96,13 @@ def self.bottle if args.merge? Homebrew.install_bundler_gems!(groups: ["ast"]) - return merge(args: args) + return merge(args:) end gnu_tar_formula_ensure_installed_if_needed!(only_json_tab: args.only_json_tab?) args.named.to_resolved_formulae(uniq: false).each do |formula| - bottle_formula formula, args: args + bottle_formula formula, args: end end @@ -153,7 +153,7 @@ def self.keg_contain?(string, keg, ignores, formula_and_runtime_deps_names = nil end end - keg_contain_absolute_symlink_starting_with?(string, keg, args: args) || result + keg_contain_absolute_symlink_starting_with?(string, keg, args:) || result end def self.keg_contain_absolute_symlink_starting_with?(string, keg, args:) @@ -482,7 +482,7 @@ def self.bottle_formula(formula, args:) else HOMEBREW_REPOSITORY end.to_s - if keg_contain?(repository_reference, keg, ignores + ALLOWABLE_HOMEBREW_REPOSITORY_LINKS, args: args) + if keg_contain?(repository_reference, keg, ignores + ALLOWABLE_HOMEBREW_REPOSITORY_LINKS, args:) odie "Bottle contains non-relocatable reference to #{repository_reference}!" end @@ -490,16 +490,16 @@ def self.bottle_formula(formula, args:) if args.skip_relocation? skip_relocation = true else - relocatable = false if keg_contain?(prefix_check, keg, ignores, formula_and_runtime_deps_names, args: args) - relocatable = false if keg_contain?(cellar, keg, ignores, formula_and_runtime_deps_names, args: args) - if keg_contain?(HOMEBREW_LIBRARY.to_s, keg, ignores, formula_and_runtime_deps_names, args: args) + relocatable = false if keg_contain?(prefix_check, keg, ignores, formula_and_runtime_deps_names, args:) + relocatable = false if keg_contain?(cellar, keg, ignores, formula_and_runtime_deps_names, args:) + if keg_contain?(HOMEBREW_LIBRARY.to_s, keg, ignores, formula_and_runtime_deps_names, args:) relocatable = false end if prefix != prefix_check - relocatable = false if keg_contain_absolute_symlink_starting_with?(prefix, keg, args: args) - relocatable = false if keg_contain?("#{prefix}/etc", keg, ignores, args: args) - relocatable = false if keg_contain?("#{prefix}/var", keg, ignores, args: args) - relocatable = false if keg_contain?("#{prefix}/share/vim", keg, ignores, args: args) + relocatable = false if keg_contain_absolute_symlink_starting_with?(prefix, keg, args:) + relocatable = false if keg_contain?("#{prefix}/etc", keg, ignores, args:) + relocatable = false if keg_contain?("#{prefix}/var", keg, ignores, args:) + relocatable = false if keg_contain?("#{prefix}/share/vim", keg, ignores, args:) end skip_relocation = relocatable && !keg.require_relocation? end @@ -661,7 +661,7 @@ def self.merge(args:) tag.to_sym end - sha256_hash = { cellar: cellar, tag_sym => tag_hash["sha256"] } + sha256_hash = { cellar:, tag_sym => tag_hash["sha256"] } bottle.sha256 sha256_hash break if all_bottle @@ -735,7 +735,7 @@ def self.merge(args:) require "utils/ast" formula_ast = Utils::AST::FormulaAST.new(path.read) - checksums = old_checksums(formula, formula_ast, bottle_hash, args: args) + checksums = old_checksums(formula, formula_ast, bottle_hash, args:) update_or_add = checksums.nil? ? "add" : "update" checksums&.each(&bottle.method(:sha256)) diff --git a/Library/Homebrew/dev-cmd/bump-cask-pr.rb b/Library/Homebrew/dev-cmd/bump-cask-pr.rb index d2fcd366daa7bc..e51cc9390b7b58 100644 --- a/Library/Homebrew/dev-cmd/bump-cask-pr.rb +++ b/Library/Homebrew/dev-cmd/bump-cask-pr.rb @@ -89,19 +89,13 @@ def bump_cask_pr odie "This cask is not in a tap!" if cask.tap.blank? odie "This cask's tap is not a Git repository!" unless cask.tap.git? - if ENV.fetch("HOMEBREW_TEST_BOT_AUTOBUMP", false).blank? && - (cask.tap.core_cask_tap? && - (autobump_file_path = cask.tap.path/Tap::HOMEBREW_TAP_AUTOBUMP_FILE) && - autobump_file_path.exist? && - autobump_file_path.readlines(chomp: true).include?(cask.token)) - odie <<~EOS - Whoops, the #{cask.token} cask has its version update - pull requests automatically opened by BrewTestBot! - We'd still love your contributions, though, so try another one - that's not in the autobump list: - #{Formatter.url("#{cask.tap.remote}/blob/master/.github/autobump.txt")} - EOS - end + odie <<~EOS unless cask.tap.allow_bump?(cask.token) + Whoops, the #{cask.token} cask has its version update + pull requests automatically opened by BrewTestBot! + We'd still love your contributions, though, so try another one + that's not in the autobump list: + #{Formatter.url("#{cask.tap.remote}/blob/master/.github/autobump.txt")} + EOS new_version = BumpVersionParser.new( general: args.version, @@ -129,7 +123,7 @@ def bump_cask_pr raise UsageError, "No `--version`, `--url` or `--sha256` argument specified!" end - check_pull_requests(cask, args: args, new_version: new_version) + check_pull_requests(cask, args:, new_version:) replacement_pairs ||= [] branch_name = "bump-#{cask.token}" @@ -155,7 +149,7 @@ def bump_cask_pr # For simplicity, our naming defers to the arm version if we multiple architectures are specified branch_version = new_version.arm || new_version.general if branch_version.is_a?(Cask::DSL::Version) - commit_version = shortened_version(branch_version, cask: cask) + commit_version = shortened_version(branch_version, cask:) branch_name = "bump-#{cask.token}-#{branch_version.tr(",:", "-")}" commit_message ||= "#{cask.token} #{commit_version}" end @@ -172,18 +166,18 @@ def bump_cask_pr read_only_run: args.dry_run?, silent: args.quiet?) - run_cask_audit(cask, old_contents, args: args) - run_cask_style(cask, old_contents, args: args) + run_cask_audit(cask, old_contents, args:) + run_cask_style(cask, old_contents, args:) pr_info = { - branch_name: branch_name, - commit_message: commit_message, - old_contents: old_contents, + branch_name:, + commit_message:, + old_contents:, pr_message: "Created with `brew bump-cask-pr`.", sourcefile_path: cask.sourcefile_path, tap: cask.tap, } - GitHub.create_bump_pr(pr_info, args: args) + GitHub.create_bump_pr(pr_info, args:) end sig { params(version: Cask::DSL::Version, cask: Cask::Cask).returns(Cask::DSL::Version) } @@ -207,7 +201,7 @@ def replace_version_and_checksum(cask, new_hash, new_version, replacement_pairs) # When blocks are absent, arch is not relevant. For consistency, we simulate the arm architecture. arch_options = cask.on_system_blocks_exist? ? OnSystem::ARCH_OPTIONS : [:arm] arch_options.each do |arch| - SimulateSystem.with arch: arch do + SimulateSystem.with(arch:) do old_cask = Cask::CaskLoader.load(cask.sourcefile_path) old_version = old_cask.version bump_version = new_version.send(arch) || new_version.general @@ -278,7 +272,7 @@ def check_pull_requests(cask, args:, new_version:) cask.token, tap_remote_repo, state: "closed", - version: shortened_version(version, cask: cask), + version: shortened_version(version, cask:), file: cask.sourcefile_path.relative_path_from(cask.tap.path).to_s, quiet: args.quiet?, ) diff --git a/Library/Homebrew/dev-cmd/bump-formula-pr.rb b/Library/Homebrew/dev-cmd/bump-formula-pr.rb index f4acd43a8f5e30..3402a62a6fb3b7 100644 --- a/Library/Homebrew/dev-cmd/bump-formula-pr.rb +++ b/Library/Homebrew/dev-cmd/bump-formula-pr.rb @@ -72,6 +72,8 @@ def bump_formula_pr_args "or specified ." switch "-f", "--force", description: "Remove all mirrors if `--mirror` was not specified." + switch "--install-dependencies", + description: "Install missing dependencies required to update resources." flag "--python-package-name=", description: "Use the specified when finding Python resources for . " \ "If no package name is specified, it will be inferred from the formula's stable URL." @@ -112,19 +114,13 @@ def bump_formula_pr odie "This formula is not in a tap!" if formula.tap.blank? odie "This formula's tap is not a Git repository!" unless formula.tap.git? - if ENV.fetch("HOMEBREW_TEST_BOT_AUTOBUMP", nil).blank? && - (formula.tap.core_tap? && - (autobump_file_path = formula.tap.path/Tap::HOMEBREW_TAP_AUTOBUMP_FILE) && - autobump_file_path.exist? && - autobump_file_path.readlines(chomp: true).include?(formula.name)) - odie <<~EOS - Whoops, the #{formula.name} formula has its version update - pull requests automatically opened by BrewTestBot! - We'd still love your contributions, though, so try another one - that's not in the autobump list: - #{Formatter.url("#{formula.tap.remote}/blob/master/.github/autobump.txt")} - EOS - end + odie <<~EOS unless formula.tap.allow_bump?(formula.name) + Whoops, the #{formula.name} formula has its version update + pull requests automatically opened by BrewTestBot! + We'd still love your contributions, though, so try another one + that's not in the autobump list: + #{Formatter.url("#{formula.tap.remote}/blob/master/.github/autobump.txt")} + EOS formula_spec = formula.stable odie "#{formula}: no stable specification found!" if formula_spec.blank? @@ -138,10 +134,10 @@ def bump_formula_pr remote_branch = formula.tap.git_repo.origin_branch_name previous_branch = "-" - check_open_pull_requests(formula, tap_remote_repo, args: args) + check_open_pull_requests(formula, tap_remote_repo, args:) new_version = args.version - check_new_version(formula, tap_remote_repo, version: new_version, args: args) if new_version.present? + check_new_version(formula, tap_remote_repo, version: new_version, args:) if new_version.present? opoo "This formula has patches that may be resolved upstream." if formula.patchlist.present? if formula.resources.any? { |resource| !resource.name.start_with?("homebrew-") } @@ -153,7 +149,7 @@ def bump_formula_pr new_mirror ||= determine_mirror(new_url) new_mirrors ||= [new_mirror] if new_mirror.present? - check_for_mirrors(formula, old_mirrors, new_mirrors, args: args) if new_url.present? + check_for_mirrors(formula, old_mirrors, new_mirrors, args:) if new_url.present? old_hash = formula_spec.checksum&.hexdigest new_hash = args.sha256 @@ -165,10 +161,10 @@ def bump_formula_pr old_version = old_formula_version.to_s forced_version = new_version.present? new_url_hash = if new_url.present? && new_hash.present? - check_new_version(formula, tap_remote_repo, url: new_url, args: args) if new_version.blank? + check_new_version(formula, tap_remote_repo, url: new_url, args:) if new_version.blank? true elsif new_tag.present? && new_revision.present? - check_new_version(formula, tap_remote_repo, url: old_url, tag: new_tag, args: args) if new_version.blank? + check_new_version(formula, tap_remote_repo, url: old_url, tag: new_tag, args:) if new_version.blank? false elsif old_hash.blank? if new_tag.blank? && new_version.blank? && new_revision.blank? @@ -183,7 +179,7 @@ def bump_formula_pr and old tag are both #{new_tag}. EOS end - check_new_version(formula, tap_remote_repo, url: old_url, tag: new_tag, args: args) if new_version.blank? + check_new_version(formula, tap_remote_repo, url: old_url, tag: new_tag, args:) if new_version.blank? resource_path, forced_version = fetch_resource_and_forced_version(formula, new_version, old_url, tag: new_tag) new_revision = Utils.popen_read("git", "-C", resource_path.to_s, "rev-parse", "-q", "--verify", "HEAD") new_revision = new_revision.strip @@ -210,7 +206,7 @@ def bump_formula_pr #{new_url} EOS end - check_new_version(formula, tap_remote_repo, url: new_url, args: args) if new_version.blank? + check_new_version(formula, tap_remote_repo, url: new_url, args:) if new_version.blank? resource_path, forced_version = fetch_resource_and_forced_version(formula, new_version, new_url) Utils::Tar.validate_file(resource_path) new_hash = resource_path.sha256 @@ -343,11 +339,12 @@ def bump_formula_pr package_name: args.python_package_name, extra_packages: args.python_extra_packages, exclude_packages: args.python_exclude_packages, + install_dependencies: args.install_dependencies?, silent: args.quiet?, ignore_non_pypi_packages: true end - run_audit(formula, alias_rename, old_contents, args: args) + run_audit(formula, alias_rename, old_contents, args:) pr_message = "Created with `brew bump-formula-pr`." if resources_checked.nil? && formula.resources.any? { |resource| !resource.name.start_with?("homebrew-") } @@ -382,18 +379,18 @@ def bump_formula_pr pr_info = { sourcefile_path: formula.path, - old_contents: old_contents, + old_contents:, additional_files: alias_rename, - remote: remote, - remote_branch: remote_branch, + remote:, + remote_branch:, branch_name: "bump-#{formula.name}-#{new_formula_version}", commit_message: "#{formula.name} #{new_formula_version}", - previous_branch: previous_branch, + previous_branch:, tap: formula.tap, - tap_remote_repo: tap_remote_repo, - pr_message: pr_message, + tap_remote_repo:, + pr_message:, } - GitHub.create_bump_pr(pr_info, args: args) + GitHub.create_bump_pr(pr_info, args:) end def determine_mirror(url) @@ -459,7 +456,7 @@ def check_new_version(formula, tap_remote_repo, args:, version: nil, url: nil, t end check_throttle(formula, version) - check_closed_pull_requests(formula, tap_remote_repo, args: args, version: version) + check_closed_pull_requests(formula, tap_remote_repo, args:, version:) end def check_throttle(formula, new_version) @@ -475,7 +472,7 @@ def check_throttle(formula, new_version) def check_closed_pull_requests(formula, tap_remote_repo, args:, version:) # if we haven't already found open requests, try for an exact match across closed requests GitHub.check_for_duplicate_pull_requests(formula.name, tap_remote_repo, - version: version, + version:, state: "closed", file: formula.path.relative_path_from(formula.tap.path).to_s, quiet: args.quiet?) diff --git a/Library/Homebrew/dev-cmd/bump.rb b/Library/Homebrew/dev-cmd/bump.rb index 77ccaf62248539..008d2f7794f7aa 100644 --- a/Library/Homebrew/dev-cmd/bump.rb +++ b/Library/Homebrew/dev-cmd/bump.rb @@ -35,6 +35,8 @@ def bump_args description: "Check only formulae." switch "--cask", "--casks", description: "Check only casks." + flag "--tap=", + description: "Check formulae and casks within the given tap, specified as `/`." switch "--installed", description: "Check formulae and casks that are currently installed." switch "--no-fork", @@ -49,6 +51,7 @@ def bump_args hidden: true conflicts "--cask", "--formula" + conflicts "--tap=", "--installed" conflicts "--no-pull-requests", "--open-pr" named_args [:formula, :cask], without_api: true @@ -68,7 +71,14 @@ def bump odisabled "brew bump --force" if args.force? Homebrew.with_no_api_env do - formulae_and_casks = if args.installed? + formulae_and_casks = if args.tap + tap = Tap.fetch(args.tap) + raise UsageError, "`--tap` cannot be used with official taps." if tap.official? + + formulae = args.cask? ? [] : tap.formula_files.map { |path| Formulary.factory(path) } + casks = args.formula? ? [] : tap.cask_files.map { |path| Cask::CaskLoader.load(path) } + formulae + casks + elsif args.installed? formulae = args.cask? ? [] : Formula.installed casks = args.formula? ? [] : Cask::Caskroom.casks formulae + casks @@ -102,6 +112,12 @@ def bump end end + sig { params(formula_or_cask: T.any(Formula, Cask::Cask), args: CLI::Args).returns(T::Boolean) } + def skip_repology?(formula_or_cask, args:) + (ENV["CI"].present? && args.open_pr? && formula_or_cask.livecheckable?) || + (formula_or_cask.is_a?(Formula) && formula_or_cask.versioned_formula?) + end + sig { params(formulae_and_casks: T::Array[T.any(Formula, Cask::Cask)], args: CLI::Args).void } def handle_formula_and_casks(formulae_and_casks, args) Livecheck.load_other_tap_strategies(formulae_and_casks) @@ -137,17 +153,13 @@ def handle_formula_and_casks(formulae_and_casks, args) Repology::HOMEBREW_CASK end - package_data = if formula_or_cask.is_a?(Formula) && formula_or_cask.versioned_formula? - nil - else - Repology.single_package_query(name, repository: repository) - end + package_data = Repology.single_package_query(name, repository:) unless skip_repology?(formula_or_cask, args:) retrieve_and_display_info_and_open_pr( formula_or_cask, name, package_data&.values&.first, - args: args, + args:, ambiguous_cask: ambiguous_casks.include?(formula_or_cask), ) end @@ -208,8 +220,8 @@ def handle_api_response(args) formula_or_cask, name, repositories, - args: args, - ambiguous_cask: ambiguous_cask, + args:, + ambiguous_cask:, ) end end @@ -220,16 +232,20 @@ def handle_api_response(args) } def skip_ineligible_formulae(formula_or_cask) if formula_or_cask.is_a?(Formula) - return false if !formula_or_cask.disabled? && !formula_or_cask.head_only? - + skip = formula_or_cask.disabled? || formula_or_cask.head_only? name = formula_or_cask.name text = "Formula is #{formula_or_cask.disabled? ? "disabled" : "HEAD-only"}.\n" else - return false unless formula_or_cask.disabled? - + skip = formula_or_cask.disabled? name = formula_or_cask.token text = "Cask is disabled.\n" end + unless formula_or_cask.tap.allow_bump?(name) + skip = true + text = "#{text.split.first} is on autobump list.\n" + end + return false unless skip + ohai name puts text true @@ -269,7 +285,7 @@ def livecheck_result(formula_or_cask) version_info = Livecheck.latest_version( formula_or_cask, - referenced_formula_or_cask: referenced_formula_or_cask, + referenced_formula_or_cask:, json: true, full_name: false, verbose: true, debug: false ) return "unable to get versions" if version_info.blank? @@ -292,24 +308,20 @@ def livecheck_result(formula_or_cask) def retrieve_pull_requests(formula_or_cask, name, state:, version: nil) tap_remote_repo = formula_or_cask.tap&.remote_repo || formula_or_cask.tap&.full_name pull_requests = begin - GitHub.fetch_pull_requests(name, tap_remote_repo, state: state, version: version) + GitHub.fetch_pull_requests(name, tap_remote_repo, state:, version:) rescue GitHub::API::ValidationFailedError => e odebug "Error fetching pull requests for #{formula_or_cask} #{name}: #{e}" nil end - if pull_requests&.any? - pull_requests = pull_requests.map { |pr| "#{pr["title"]} (#{Formatter.url(pr["html_url"])})" }.join(", ") - end - - pull_requests + pull_requests&.map { |pr| "#{pr["title"]} (#{Formatter.url(pr["html_url"])})" }&.join(", ") end sig { params( formula_or_cask: T.any(Formula, Cask::Cask), repositories: T::Array[T.untyped], - args: T.untyped, + args: CLI::Args, name: String, ).returns(VersionBumpInfo) } @@ -326,7 +338,7 @@ def retrieve_versions_by_arch(formula_or_cask:, repositories:, args:, name:) arch_options = is_cask_with_blocks ? OnSystem::ARCH_OPTIONS : [:arm] arch_options.each do |arch| - SimulateSystem.with arch: arch do + SimulateSystem.with(arch:) do version_key = is_cask_with_blocks ? arch : :general # We reload the formula/cask here to ensure we're getting the correct version for the current arch @@ -401,14 +413,14 @@ def retrieve_versions_by_arch(formula_or_cask:, repositories:, args:, name:) end.presence VersionBumpInfo.new( - type: type, - multiple_versions: multiple_versions, - version_name: version_name, - current_version: current_version, - repology_latest: repology_latest, - new_version: new_version, - open_pull_requests: open_pull_requests, - closed_pull_requests: closed_pull_requests, + type:, + multiple_versions:, + version_name:, + current_version:, + repology_latest:, + new_version:, + open_pull_requests:, + closed_pull_requests:, ) end @@ -417,15 +429,15 @@ def retrieve_versions_by_arch(formula_or_cask:, repositories:, args:, name:) formula_or_cask: T.any(Formula, Cask::Cask), name: String, repositories: T::Array[T.untyped], - args: T.untyped, + args: CLI::Args, ambiguous_cask: T::Boolean, ).void } def retrieve_and_display_info_and_open_pr(formula_or_cask, name, repositories, args:, ambiguous_cask: false) - version_info = retrieve_versions_by_arch(formula_or_cask: formula_or_cask, - repositories: repositories, - args: args, - name: name) + version_info = retrieve_versions_by_arch(formula_or_cask:, + repositories:, + args:, + name:) current_version = version_info.current_version new_version = version_info.new_version @@ -467,18 +479,16 @@ def retrieve_and_display_info_and_open_pr(formula_or_cask, name, repositories, a puts <<~EOS Current #{version_label} #{current_versions} Latest livecheck version: #{new_versions} + EOS + puts <<~EOS unless skip_repology?(formula_or_cask, args:) Latest Repology version: #{repology_latest} EOS - if formula_or_cask.is_a?(Formula) - require "formula_auditor" - auditor = FormulaAuditor.new(formula_or_cask) - if auditor.synced_with_other_formulae? - outdated_synced_formulae = synced_with(auditor, formula_or_cask, new_version.general) - puts <<~EOS if outdated_synced_formulae.present? - Version syncing: #{title_name} version should be kept in sync with - #{outdated_synced_formulae.join(", ")}. - EOS - end + if formula_or_cask.is_a?(Formula) && formula_or_cask.synced_with_other_formulae? + outdated_synced_formulae = synced_with(formula_or_cask, new_version.general) + puts <<~EOS if outdated_synced_formulae.present? + Version syncing: #{title_name} version should be kept in sync with + #{outdated_synced_formulae.join(", ")}. + EOS end puts <<~EOS unless args.no_pull_requests? Open pull requests: #{open_pull_requests || "none"} @@ -521,15 +531,14 @@ def retrieve_and_display_info_and_open_pr(formula_or_cask, name, repositories, a sig { params( - auditor: FormulaAuditor, formula: Formula, new_version: T.nilable(T.any(Version, Cask::DSL::Version)), ).returns(T::Array[String]) } - def synced_with(auditor, formula, new_version) + def synced_with(formula, new_version) synced_with = [] - auditor.synced_versions_formulae_json.each do |synced_formulae| + formula.tap&.synced_versions_formulae&.each do |synced_formulae| next unless synced_formulae.include?(formula.name) synced_formulae.each do |synced_formula| diff --git a/Library/Homebrew/dev-cmd/contributions.rb b/Library/Homebrew/dev-cmd/contributions.rb old mode 100755 new mode 100644 index c05cf2726daad7..4c38746a30d21f --- a/Library/Homebrew/dev-cmd/contributions.rb +++ b/Library/Homebrew/dev-cmd/contributions.rb @@ -71,7 +71,7 @@ def contributions # committer details to match the ones on GitHub. # TODO: Switch to using the GitHub APIs instead of `git log` if # they ever support trailers. - results[username] = scan_repositories(repos, username, args, from: from) + results[username] = scan_repositories(repos, username, args, from:) grand_totals[username] = total(results[username]) contributions = contribution_types.filter_map do |type| @@ -85,7 +85,7 @@ def contributions puts [ "#{username} contributed", *contributions.to_sentence, - "#{time_period(from: from, to: args.to)}.", + "#{time_period(from:, to: args.to)}.", ].join(" ") end @@ -167,7 +167,7 @@ def scan_repositories(repos, person, args, from:) data[repo] = { author: author_commits, committer: committer_commits, - coauthorship: git_log_trailers_cmd(T.must(repo_path), person, "Co-authored-by", from: from, to: args.to), + coauthorship: git_log_trailers_cmd(T.must(repo_path), person, "Co-authored-by", from:, to: args.to), review: count_reviews(repo_full_name, person, args), } end @@ -203,7 +203,7 @@ def git_log_trailers_cmd(repo_path, person, trailer, from:, to:) sig { params(repo_full_name: String, person: String, args: Homebrew::CLI::Args).returns(Integer) } def count_reviews(repo_full_name, person, args) - GitHub.count_issues("", is: "pr", repo: repo_full_name, reviewed_by: person, review: "approved", args: args) + GitHub.count_issues("", is: "pr", repo: repo_full_name, reviewed_by: person, review: "approved", args:) rescue GitHub::API::ValidationFailedError if args.verbose? onoe "Couldn't search GitHub for PRs by #{person}. Their profile might be private. Defaulting to 0." diff --git a/Library/Homebrew/dev-cmd/create.rb b/Library/Homebrew/dev-cmd/create.rb index d2ea1599389938..ed2ce73a626038 100644 --- a/Library/Homebrew/dev-cmd/create.rb +++ b/Library/Homebrew/dev-cmd/create.rb @@ -74,9 +74,9 @@ def create args = create_args.parse path = if args.cask? - create_cask(args: args) + create_cask(args:) else - create_formula(args: args) + create_formula(args:) end exec_editor path @@ -181,7 +181,7 @@ def create_formula(args:) args.set_version, tap: args.tap, url: args.named.first, - mode: mode, + mode:, license: args.set_license, fetch: !args.no_fetch?, head: args.HEAD?, diff --git a/Library/Homebrew/dev-cmd/determine-test-runners.rb b/Library/Homebrew/dev-cmd/determine-test-runners.rb old mode 100755 new mode 100644 diff --git a/Library/Homebrew/dev-cmd/generate-cask-api.rb b/Library/Homebrew/dev-cmd/generate-cask-api.rb index 3cf93c86af9867..61f2ab84034231 100644 --- a/Library/Homebrew/dev-cmd/generate-cask-api.rb +++ b/Library/Homebrew/dev-cmd/generate-cask-api.rb @@ -46,7 +46,7 @@ def generate_cask_api raise TapUnavailableError, tap.name unless tap.installed? unless args.dry_run? - directories = ["_data/cask", "api/cask", "api/cask-source", "cask"].freeze + directories = ["_data/cask", "api/cask", "api/cask-source", "cask", "api/internal/v3"].freeze FileUtils.rm_rf directories FileUtils.mkdir_p directories end @@ -74,6 +74,9 @@ def generate_cask_api onoe "Error while generating data for cask '#{path.stem}'." raise end + + homebrew_cask_tap_json = JSON.generate(tap.to_internal_api_hash) + File.write("api/internal/v3/homebrew-cask.json", homebrew_cask_tap_json) unless args.dry_run? end end end diff --git a/Library/Homebrew/dev-cmd/generate-formula-api.rb b/Library/Homebrew/dev-cmd/generate-formula-api.rb index 9926fd04f5a4a0..9c7f30548afed7 100644 --- a/Library/Homebrew/dev-cmd/generate-formula-api.rb +++ b/Library/Homebrew/dev-cmd/generate-formula-api.rb @@ -74,7 +74,7 @@ def generate_formula_api raise end - homebrew_core_tap_json = JSON.generate(tap.to_api_hash) + homebrew_core_tap_json = JSON.generate(tap.to_internal_api_hash) File.write("api/internal/v3/homebrew-core.json", homebrew_core_tap_json) unless args.dry_run? canonical_json = JSON.pretty_generate(tap.formula_renames.merge(tap.alias_table)) File.write("_data/formula_canonical.json", "#{canonical_json}\n") unless args.dry_run? diff --git a/Library/Homebrew/dev-cmd/install-bundler-gems.rb b/Library/Homebrew/dev-cmd/install-bundler-gems.rb index 78165720c16a7d..167bfa804f3932 100644 --- a/Library/Homebrew/dev-cmd/install-bundler-gems.rb +++ b/Library/Homebrew/dev-cmd/install-bundler-gems.rb @@ -36,6 +36,6 @@ def install_bundler_gems Homebrew.forget_user_gem_groups! end - Homebrew.install_bundler_gems!(groups: groups) + Homebrew.install_bundler_gems!(groups:) end end diff --git a/Library/Homebrew/dev-cmd/irb.rb b/Library/Homebrew/dev-cmd/irb.rb index 785191d218fd75..59b52cb6678a90 100644 --- a/Library/Homebrew/dev-cmd/irb.rb +++ b/Library/Homebrew/dev-cmd/irb.rb @@ -12,7 +12,7 @@ def f(*args) end def c(config: nil) - Cask::CaskLoader.load(self, config: config) + Cask::CaskLoader.load(self, config:) end end @@ -22,7 +22,7 @@ def f(*args) end def c(config: nil) - to_s.c(config: config) + to_s.c(config:) end end diff --git a/Library/Homebrew/dev-cmd/pr-publish.rb b/Library/Homebrew/dev-cmd/pr-publish.rb index 1b732fe28731fc..ea0415f71efc37 100644 --- a/Library/Homebrew/dev-cmd/pr-publish.rb +++ b/Library/Homebrew/dev-cmd/pr-publish.rb @@ -23,7 +23,7 @@ def pr_publish_args description: "Branch to use the workflow from (default: `master`)." flag "--message=", depends_on: "--autosquash", - description: "Message to include when autosquashing revision bumps, deletions, and rebuilds." + description: "Message to include when autosquashing revision bumps, deletions and rebuilds." flag "--tap=", description: "Target tap repository (default: `homebrew/core`)." flag "--workflow=", diff --git a/Library/Homebrew/dev-cmd/pr-pull.rb b/Library/Homebrew/dev-cmd/pr-pull.rb index 0186df88e1373b..7c07c711cae297 100644 --- a/Library/Homebrew/dev-cmd/pr-pull.rb +++ b/Library/Homebrew/dev-cmd/pr-pull.rb @@ -51,7 +51,7 @@ def self.pr_pull_args description: "Specify a committer name and email in `git`'s standard author format." flag "--message=", depends_on: "--autosquash", - description: "Message to include when autosquashing revision bumps, deletions, and rebuilds." + description: "Message to include when autosquashing revision bumps, deletions and rebuilds." flag "--artifact=", description: "Download artifacts with the specified name (default: `bottles`)." flag "--tap=", @@ -163,12 +163,12 @@ def self.reword_package_commit(commit, file, git_repo:, reason: "", verbose: fal package_name = package_file.basename.to_s.chomp(".rb") odebug "Cherry-picking #{package_file}: #{commit}" - Utils::Git.cherry_pick!(git_repo.to_s, commit, verbose: verbose, resolve: resolve) + Utils::Git.cherry_pick!(git_repo.to_s, commit, verbose:, resolve:) old_package = Utils::Git.file_at_commit(git_repo.to_s, file, "HEAD^") new_package = Utils::Git.file_at_commit(git_repo.to_s, file, "HEAD") - bump_subject = determine_bump_subject(old_package, new_package, package_file, reason: reason).strip + bump_subject = determine_bump_subject(old_package, new_package, package_file, reason:).strip subject, body, trailers = separate_commit_message(git_repo.commit_message) if subject != bump_subject && !subject.start_with?("#{package_name}:") @@ -214,13 +214,13 @@ def self.squash_package_commits(commits, file, git_repo:, reason: "", verbose: f trailers = [trailers + co_author_trailers].flatten.uniq.compact # Apply the patch series but don't commit anything yet. - Utils::Git.cherry_pick!(git_repo.pathname, "--no-commit", *commits, verbose: verbose, resolve: resolve) + Utils::Git.cherry_pick!(git_repo.pathname, "--no-commit", *commits, verbose:, resolve:) # Determine the bump subject by comparing the original state of the tree to its current state. package_file = git_repo.pathname / file old_package = Utils::Git.file_at_commit(git_repo.pathname, file, "#{commits.first}^") new_package = package_file.read - bump_subject = determine_bump_subject(old_package, new_package, package_file, reason: reason) + bump_subject = determine_bump_subject(old_package, new_package, package_file, reason:) # Commit with the new subject, body, and trailers. safe_system("git", "-C", git_repo.pathname, "commit", "--quiet", @@ -273,14 +273,14 @@ def self.autosquash!(original_commit, tap:, reason: "", verbose: false, resolve: if files.length == 1 && files_to_commits[files.first].length == 1 # If there's a 1:1 mapping of commits to files, just cherry pick and (maybe) reword. reword_package_commit( - commit, files.first, git_repo: git_repo, reason: reason, verbose: verbose, resolve: resolve + commit, files.first, git_repo:, reason:, verbose:, resolve: ) processed_commits << commit elsif files.length == 1 && files_to_commits[files.first].length > 1 # If multiple commits modify a single file, squash them down into a single commit. file = files.first commits = files_to_commits[file] - squash_package_commits(commits, file, git_repo: git_repo, reason: reason, verbose: verbose, resolve: resolve) + squash_package_commits(commits, file, git_repo:, reason:, verbose:, resolve:) processed_commits += commits else # We can't split commits (yet) so just raise an error. @@ -362,7 +362,7 @@ def self.changed_packages(tap, original_commit) def self.pr_check_conflicts(repo, pull_request) long_build_pr_files = GitHub.issues( - repo: repo, state: "open", labels: "no long build conflict", + repo:, state: "open", labels: "no long build conflict", ).each_with_object({}) do |long_build_pr, hash| next unless long_build_pr.key?("pull_request") @@ -459,15 +459,15 @@ def self.pr_pull odebug "Pull request merge-base: #{original_commit}" unless args.no_commit? - cherry_pick_pr!(user, repo, pr, path: tap.path, args: args) unless args.no_cherry_pick? + cherry_pick_pr!(user, repo, pr, path: tap.path, args:) unless args.no_cherry_pick? if args.autosquash? && !args.dry_run? - autosquash!(original_commit, tap: tap, cherry_picked: !args.no_cherry_pick?, + autosquash!(original_commit, tap:, cherry_picked: !args.no_cherry_pick?, verbose: args.verbose?, resolve: args.resolve?, reason: args.message) end signoff!(git_repo, pull_request: pr, dry_run: args.dry_run?) unless args.clean? end - unless formulae_need_bottles?(tap, original_commit, pr_labels, args: args) + unless formulae_need_bottles?(tap, original_commit, pr_labels, args:) ohai "Skipping artifacts for ##{pr} as the formulae don't need bottles" next end diff --git a/Library/Homebrew/dev-cmd/release.rb b/Library/Homebrew/dev-cmd/release.rb old mode 100755 new mode 100644 diff --git a/Library/Homebrew/dev-cmd/test.rb b/Library/Homebrew/dev-cmd/test.rb index abc4471b6180e3..43072b7264c7ef 100644 --- a/Library/Homebrew/dev-cmd/test.rb +++ b/Library/Homebrew/dev-cmd/test.rb @@ -102,7 +102,7 @@ def test end end rescue Exception => e # rubocop:disable Lint/RescueException - retry if retry_test?(f, args: args) + retry if retry_test?(f, args:) ofail "#{f.full_name}: failed" $stderr.puts e, Utils::Backtrace.clean(e) ensure diff --git a/Library/Homebrew/dev-cmd/typecheck.rb b/Library/Homebrew/dev-cmd/typecheck.rb index 3b17cb54039c73..1978fdb07716e7 100644 --- a/Library/Homebrew/dev-cmd/typecheck.rb +++ b/Library/Homebrew/dev-cmd/typecheck.rb @@ -41,7 +41,7 @@ def self.typecheck update = args.update? || args.update_all? groups = update ? Homebrew.valid_gem_groups : ["typecheck"] - Homebrew.install_bundler_gems!(groups: groups) + Homebrew.install_bundler_gems!(groups:) HOMEBREW_LIBRARY_PATH.cd do if update diff --git a/Library/Homebrew/dev-cmd/unbottled.rb b/Library/Homebrew/dev-cmd/unbottled.rb index 33b56d2b3c90c7..8ac5fb9dbb9938 100644 --- a/Library/Homebrew/dev-cmd/unbottled.rb +++ b/Library/Homebrew/dev-cmd/unbottled.rb @@ -65,7 +65,7 @@ def unbottled raise "Unknown arch #{@bottle_tag.arch}." end - Homebrew::SimulateSystem.with os: os, arch: arch do + Homebrew::SimulateSystem.with(os:, arch:) do all = args.eval_all? if args.total? if !all && !Homebrew::EnvConfig.eval_all? diff --git a/Library/Homebrew/dev-cmd/update-maintainers.rb b/Library/Homebrew/dev-cmd/update-maintainers.rb index 557b02e580bbf8..75811fd79fc41b 100644 --- a/Library/Homebrew/dev-cmd/update-maintainers.rb +++ b/Library/Homebrew/dev-cmd/update-maintainers.rb @@ -33,7 +33,7 @@ def self.update_maintainers members = { plc: GitHub.members_by_team("Homebrew", "plc"), tsc: GitHub.members_by_team("Homebrew", "tsc"), - maintainers: maintainers, + maintainers:, } sentences = {} diff --git a/Library/Homebrew/dev-cmd/update-python-resources.rb b/Library/Homebrew/dev-cmd/update-python-resources.rb index d11035f04bcf0a..169dede9dab65a 100644 --- a/Library/Homebrew/dev-cmd/update-python-resources.rb +++ b/Library/Homebrew/dev-cmd/update-python-resources.rb @@ -19,6 +19,8 @@ def update_python_resources_args description: "Suppress any output." switch "--ignore-non-pypi-packages", description: "Don't fail if is not a PyPI package." + switch "--install-dependencies", + description: "Install missing dependencies required to update resources." flag "--version=", description: "Use the specified when finding resources for . " \ "If no version is specified, the current version for will be used." @@ -43,6 +45,7 @@ def update_python_resources package_name: args.package_name, extra_packages: args.extra_packages, exclude_packages: args.exclude_packages, + install_dependencies: args.install_dependencies?, print_only: args.print_only?, silent: args.silent?, verbose: args.verbose?, diff --git a/Library/Homebrew/diagnostic.rb b/Library/Homebrew/diagnostic.rb index 244c9353835df4..5c6d81e605e0e1 100644 --- a/Library/Homebrew/diagnostic.rb +++ b/Library/Homebrew/diagnostic.rb @@ -21,7 +21,7 @@ module Diagnostic def self.missing_deps(formulae, hide = nil) missing = {} formulae.each do |f| - missing_dependencies = f.missing_dependencies(hide: hide) + missing_dependencies = f.missing_dependencies(hide:) next if missing_dependencies.empty? yield f.full_name, missing_dependencies if block_given? @@ -545,7 +545,7 @@ def check_tap_git_branch return if ENV["CI"] return unless Utils::Git.available? - commands = Tap.select(&:installed?).filter_map do |tap| + commands = Tap.installed.filter_map do |tap| next if tap.git_repo.default_origin_branch? "git -C $(brew --repo #{tap.name}) checkout #{tap.git_repo.origin_branch_name}" @@ -794,7 +794,7 @@ def check_for_external_cmd_name_conflict def check_for_tap_ruby_files_locations bad_tap_files = {} - Tap.select(&:installed?).each do |tap| + Tap.installed.each do |tap| unused_formula_dirs = tap.potential_formula_dirs - [tap.formula_dir] unused_formula_dirs.each do |dir| next unless dir.exist? @@ -835,26 +835,20 @@ def check_deleted_formula deleted_formulae = kegs.filter_map do |keg| tap = Tab.for_keg(keg).tap + tap_keg_name = tap ? "#{tap}/#{keg.name}" : keg.name loadable = [ Formulary::FromAPILoader, - Formulary::FromDefaultNameLoader, + Formulary::FromTapLoader, Formulary::FromNameLoader, ].any? do |loader_class| loader = begin - loader_class.try_new(keg.name, warn: false) + loader_class.try_new(tap_keg_name, warn: false) rescue TapFormulaAmbiguityError => e e.loaders.first end - if loader - # If we know the tap, ignore all other taps. - next false if tap && loader.tap != tap - - next true - end - - false + loader.instance_of?(Formulary::FromTapLoader) ? loader.path.exist? : loader.present? end keg.name unless loadable diff --git a/Library/Homebrew/download_strategy.rb b/Library/Homebrew/download_strategy.rb index e98ca84d637ece..6b7375e25bd65c 100644 --- a/Library/Homebrew/download_strategy.rb +++ b/Library/Homebrew/download_strategy.rb @@ -107,7 +107,7 @@ def stage(&block) UnpackStrategy.detect(cached_location, prioritize_extension: true, ref_type: @ref_type, ref: @ref) - .extract_nestedly(basename: basename, + .extract_nestedly(basename:, prioritize_extension: true, verbose: verbose? && !quiet?) chdir(&block) if block @@ -162,7 +162,7 @@ def ohai(*args) end def silent_command(*args, **options) - system_command(*args, print_stderr: false, env: env, **options) + system_command(*args, print_stderr: false, env:, **options) end def command!(*args, **options) @@ -442,7 +442,7 @@ def fetch(timeout: nil) puts "Already downloaded: #{cached_location}" else begin - _fetch(url: url, resolved_url: resolved_url, timeout: Utils::Timer.remaining!(end_time)) + _fetch(url:, resolved_url:, timeout: Utils::Timer.remaining!(end_time)) rescue ErrorDuringExecution raise CurlDownloadStrategyError, url end @@ -473,7 +473,7 @@ def clear_cache end def resolved_time_file_size(timeout: nil) - _, _, time, file_size = resolve_url_basename_time_file_size(url, timeout: timeout) + _, _, time, file_size = resolve_url_basename_time_file_size(url, timeout:) [time, file_size] end @@ -489,7 +489,7 @@ def resolve_url_basename_time_file_size(url, timeout: nil) return @resolved_info_cache[url] if @resolved_info_cache.include?(url) begin - parsed_output = curl_headers(url.to_s, wanted_headers: ["content-disposition"], timeout: timeout) + parsed_output = curl_headers(url.to_s, wanted_headers: ["content-disposition"], timeout:) rescue ErrorDuringExecution return [url, parse_basename(url), nil, nil, false] end @@ -559,7 +559,7 @@ def _fetch(url:, resolved_url:, timeout:) end def _curl_download(resolved_url, to, timeout) - curl_download resolved_url, to: to, try_partial: @try_partial, timeout: timeout + curl_download resolved_url, to:, try_partial: @try_partial, timeout: end # Curl options to be always passed to curl, @@ -611,7 +611,7 @@ class HomebrewCurlDownloadStrategy < CurlDownloadStrategy def _curl_download(resolved_url, to, timeout) raise HomebrewCurlDownloadStrategyError, url unless Formula["curl"].any_version_installed? - curl_download resolved_url, to: to, try_partial: @try_partial, timeout: timeout, use_homebrew_curl: true + curl_download resolved_url, to:, try_partial: @try_partial, timeout:, use_homebrew_curl: true end def curl_output(*args, **options) @@ -666,7 +666,7 @@ def combined_mirrors def resolve_url_basename_time_file_size(url, timeout: nil) if url == self.url - super("#{apache_mirrors["preferred"]}#{apache_mirrors["path_info"]}", timeout: timeout) + super("#{apache_mirrors["preferred"]}#{apache_mirrors["path_info"]}", timeout:) else super end @@ -698,7 +698,7 @@ def _fetch(url:, resolved_url:, timeout:) query.nil? ? [url, "-X", "POST"] : [url, "-d", query] end - curl_download(*args, to: temporary_path, try_partial: @try_partial, timeout: timeout) + curl_download(*args, to: temporary_path, try_partial: @try_partial, timeout:) end end @@ -709,7 +709,7 @@ def _fetch(url:, resolved_url:, timeout:) class NoUnzipCurlDownloadStrategy < CurlDownloadStrategy def stage UnpackStrategy::Uncompressed.new(cached_location) - .extract(basename: basename, + .extract(basename:, verbose: verbose? && !quiet?) yield if block_given? end @@ -821,18 +821,18 @@ def repo_valid? def clone_repo(timeout: nil) case @ref_type when :revision - fetch_repo cached_location, @url, @ref, timeout: timeout + fetch_repo cached_location, @url, @ref, timeout: when :revisions # nil is OK for main_revision, as fetch_repo will then get latest main_revision = @ref[:trunk] - fetch_repo cached_location, @url, main_revision, ignore_externals: true, timeout: timeout + fetch_repo(cached_location, @url, main_revision, ignore_externals: true, timeout:) externals do |external_name, external_url| fetch_repo cached_location/external_name, external_url, @ref[external_name], ignore_externals: true, - timeout: timeout + timeout: end else - fetch_repo cached_location, @url, timeout: timeout + fetch_repo cached_location, @url, timeout: end end alias update clone_repo @@ -893,10 +893,10 @@ def cache_version sig { params(timeout: T.nilable(Time)).void } def update(timeout: nil) config_repo - update_repo(timeout: timeout) - checkout(timeout: timeout) + update_repo(timeout:) + checkout(timeout:) reset - update_submodules(timeout: timeout) if submodules? + update_submodules(timeout:) if submodules? end def shallow_dir? @@ -1018,8 +1018,8 @@ def clone_repo(timeout: nil) configure_sparse_checkout if partial_clone_sparse_checkout? - checkout(timeout: timeout) - update_submodules(timeout: timeout) if submodules? + checkout(timeout:) + update_submodules(timeout:) if submodules? end sig { params(timeout: T.nilable(Time)).void } diff --git a/Library/Homebrew/downloadable.rb b/Library/Homebrew/downloadable.rb index 143729d88a30ab..629cc9867aa5b0 100644 --- a/Library/Homebrew/downloadable.rb +++ b/Library/Homebrew/downloadable.rb @@ -75,7 +75,7 @@ def downloader raise ArgumentError, "attempted to use a Downloadable without a URL!" if primary_url.blank? download_strategy.new(primary_url, download_name, version, - mirrors: mirrors, cache: cache, **T.must(@url).specs) + mirrors:, cache:, **T.must(@url).specs) end end @@ -84,7 +84,7 @@ def fetch(verify_download_integrity: true, timeout: nil) cache.mkpath begin - downloader.fetch(timeout: timeout) + downloader.fetch(timeout:) rescue ErrorDuringExecution, CurlDownloadStrategyError => e raise DownloadError.new(self, e) end diff --git a/Library/Homebrew/extend/ENV.rb b/Library/Homebrew/extend/ENV.rb index 0a95b5ebb1b340..051acbb11a4757 100644 --- a/Library/Homebrew/extend/ENV.rb +++ b/Library/Homebrew/extend/ENV.rb @@ -44,10 +44,10 @@ def activate_extensions!(env: nil) def with_build_environment(env: nil, cc: nil, build_bottle: false, bottle_arch: nil, debug_symbols: false, &_block) old_env = to_hash.dup tmp_env = to_hash.dup.extend(EnvActivation) - T.cast(tmp_env, EnvActivation).activate_extensions!(env: env) + T.cast(tmp_env, EnvActivation).activate_extensions!(env:) T.cast(tmp_env, T.any(Superenv, Stdenv)) - .setup_build_environment(cc: cc, build_bottle: build_bottle, bottle_arch: bottle_arch, - debug_symbols: debug_symbols) + .setup_build_environment(cc:, build_bottle:, bottle_arch:, + debug_symbols:) replace(tmp_env) begin diff --git a/Library/Homebrew/extend/ENV/super.rb b/Library/Homebrew/extend/ENV/super.rb index 5813648146fec7..6beeb4cb2f4081 100644 --- a/Library/Homebrew/extend/ENV/super.rb +++ b/Library/Homebrew/extend/ENV/super.rb @@ -109,6 +109,7 @@ def setup_build_environment(formula: nil, cc: nil, build_bottle: false, bottle_a # D - Generate debugging information # f - Pass `-no_fixup_chains` to `ld` whenever it # is invoked with `-undefined dynamic_lookup` + # o - Pass `-oso_prefix` to `ld` whenever it is invoked # # These flags will also be present: # a - apply fix for apr-1-config path diff --git a/Library/Homebrew/extend/kernel.rb b/Library/Homebrew/extend/kernel.rb index 8de3f244dabc72..c30dc24d7bcb1c 100644 --- a/Library/Homebrew/extend/kernel.rb +++ b/Library/Homebrew/extend/kernel.rb @@ -55,7 +55,7 @@ def oh1_title(title, truncate: :auto) end def oh1(title, truncate: :auto) - puts oh1_title(title, truncate: truncate) + puts oh1_title(title, truncate:) end # Print a message prefixed with "Warning" (do this rarely). @@ -147,16 +147,18 @@ def odeprecated(method, replacement = nil, disable = true if disable_for_developers && Homebrew::EnvConfig.developer? if disable || Homebrew.raise_deprecation_exceptions? + puts "::error::#{message}" if ENV["GITHUB_ACTIONS"] exception = MethodDeprecatedError.new(message) exception.set_backtrace(backtrace) raise exception elsif !Homebrew.auditing? + puts "::warning::#{message}" if ENV["GITHUB_ACTIONS"] opoo message end end def odisabled(method, replacement = nil, **options) - options = { disable: true, caller: caller }.merge(options) + options = { disable: true, caller: }.merge(options) # This odeprecated should stick around indefinitely. odeprecated(method, replacement, **options) end @@ -364,8 +366,8 @@ def ensure_formula_installed!(formula_or_name, reason: "", latest: false, end # Call this method itself with redirected stdout redirect_stdout(file) do - return ensure_formula_installed!(formula_or_name, latest: latest, - reason: reason, output_to_stderr: false) + return ensure_formula_installed!(formula_or_name, latest:, + reason:, output_to_stderr: false) end end @@ -403,7 +405,7 @@ def ensure_executable!(name, formula_name = nil, reason: "") ].compact.first return executable if executable.exist? - ensure_formula_installed!(formula_name, reason: reason).opt_bin/name + ensure_formula_installed!(formula_name, reason:).opt_bin/name end def paths @@ -429,7 +431,7 @@ def disk_usage_readable(size_in_bytes) if ((size * 10).to_i % 10).zero? "#{size.to_i}#{unit}" else - "#{format("%.1f", size: size)}#{unit}" + "#{format("%.1f", size:)}#{unit}" end end diff --git a/Library/Homebrew/extend/os/linux/cleaner.rb b/Library/Homebrew/extend/os/linux/cleaner.rb index 8a21e6e91dcbe0..e1e34f09ad1afd 100644 --- a/Library/Homebrew/extend/os/linux/cleaner.rb +++ b/Library/Homebrew/extend/os/linux/cleaner.rb @@ -4,7 +4,7 @@ class Cleaner private - sig { params(path: Pathname).returns(T.nilable(T::Boolean)) } + sig { params(path: Pathname).returns(T::Boolean) } def executable_path?(path) path.elf? || path.text_executable? end diff --git a/Library/Homebrew/extend/os/linux/extend/ENV/std.rb b/Library/Homebrew/extend/os/linux/extend/ENV/std.rb index 58c741e1d45d98..4d52ae95fe99d1 100644 --- a/Library/Homebrew/extend/os/linux/extend/ENV/std.rb +++ b/Library/Homebrew/extend/os/linux/extend/ENV/std.rb @@ -4,8 +4,8 @@ module Stdenv def setup_build_environment(formula: nil, cc: nil, build_bottle: false, bottle_arch: nil, testing_formula: false, debug_symbols: false) - generic_setup_build_environment(formula: formula, cc: cc, build_bottle: build_bottle, bottle_arch: bottle_arch, - testing_formula: testing_formula, debug_symbols: debug_symbols) + generic_setup_build_environment(formula:, cc:, build_bottle:, bottle_arch:, + testing_formula:, debug_symbols:) prepend_path "CPATH", HOMEBREW_PREFIX/"include" prepend_path "LIBRARY_PATH", HOMEBREW_PREFIX/"lib" diff --git a/Library/Homebrew/extend/os/linux/extend/ENV/super.rb b/Library/Homebrew/extend/os/linux/extend/ENV/super.rb index 2bfe76d6f389cd..3959b393ccdf15 100644 --- a/Library/Homebrew/extend/os/linux/extend/ENV/super.rb +++ b/Library/Homebrew/extend/os/linux/extend/ENV/super.rb @@ -15,8 +15,8 @@ def self.bin # @private def setup_build_environment(formula: nil, cc: nil, build_bottle: false, bottle_arch: nil, testing_formula: false, debug_symbols: false) - generic_setup_build_environment(formula: formula, cc: cc, build_bottle: build_bottle, bottle_arch: bottle_arch, - testing_formula: testing_formula, debug_symbols: debug_symbols) + generic_setup_build_environment(formula:, cc:, build_bottle:, bottle_arch:, + testing_formula:, debug_symbols:) self["HOMEBREW_OPTIMIZATION_LEVEL"] = "O2" self["HOMEBREW_DYNAMIC_LINKER"] = determine_dynamic_linker_path self["HOMEBREW_RPATH_PATHS"] = determine_rpath_paths(@formula) diff --git a/Library/Homebrew/extend/os/linux/install.rb b/Library/Homebrew/extend/os/linux/install.rb index bf23f152a01cce..943ae7bea95c7c 100644 --- a/Library/Homebrew/extend/os/linux/install.rb +++ b/Library/Homebrew/extend/os/linux/install.rb @@ -31,7 +31,7 @@ module Install private_constant :GCC_RUNTIME_LIBS def self.perform_preinstall_checks(all_fatal: false, cc: nil) - generic_perform_preinstall_checks(all_fatal: all_fatal, cc: cc) + generic_perform_preinstall_checks(all_fatal:, cc:) symlink_ld_so setup_preferred_gcc_libs end diff --git a/Library/Homebrew/extend/os/linux/linkage_checker.rb b/Library/Homebrew/extend/os/linux/linkage_checker.rb index 01250a02a1bb89..6725e7245330bc 100644 --- a/Library/Homebrew/extend/os/linux/linkage_checker.rb +++ b/Library/Homebrew/extend/os/linux/linkage_checker.rb @@ -29,7 +29,7 @@ class LinkageChecker private def check_dylibs(rebuild_cache:) - generic_check_dylibs(rebuild_cache: rebuild_cache) + generic_check_dylibs(rebuild_cache:) # glibc and gcc are implicit dependencies. # No other linkage to system libraries is expected or desired. diff --git a/Library/Homebrew/extend/os/mac/cleaner.rb b/Library/Homebrew/extend/os/mac/cleaner.rb index 9f2425ca284a9c..600eec82e2cae3 100644 --- a/Library/Homebrew/extend/os/mac/cleaner.rb +++ b/Library/Homebrew/extend/os/mac/cleaner.rb @@ -6,6 +6,7 @@ class Cleaner undef executable_path? + sig { params(path: Pathname).returns(T::Boolean) } def executable_path?(path) path.mach_o_executable? || path.text_executable? end diff --git a/Library/Homebrew/extend/os/mac/development_tools.rb b/Library/Homebrew/extend/os/mac/development_tools.rb index d86403c7d68f5b..df43d554bbfedd 100644 --- a/Library/Homebrew/extend/os/mac/development_tools.rb +++ b/Library/Homebrew/extend/os/mac/development_tools.rb @@ -35,6 +35,18 @@ def default_compiler :clang end + sig { returns(Version) } + def ld64_version + @ld64_version ||= begin + json = Utils.popen_read("/usr/bin/ld", "-version_details") + if $CHILD_STATUS.success? + Version.parse(JSON.parse(json)["version"]) + else + Version::NULL + end + end + end + sig { returns(T::Boolean) } def curl_handles_most_https_certificates? # The system Curl is too old for some modern HTTPS certificates on diff --git a/Library/Homebrew/extend/os/mac/diagnostic.rb b/Library/Homebrew/extend/os/mac/diagnostic.rb index 52cccd8d382fdd..98774d3a92ca2e 100644 --- a/Library/Homebrew/extend/os/mac/diagnostic.rb +++ b/Library/Homebrew/extend/os/mac/diagnostic.rb @@ -180,7 +180,7 @@ def check_xcode_minimum_version xcode += " => #{MacOS::Xcode.prefix}" unless MacOS::Xcode.default_prefix? <<~EOS - Your Xcode (#{xcode}) is too outdated. + Your Xcode (#{xcode}) at #{MacOS::Xcode.bundle_path} is too outdated. Please update to Xcode #{MacOS::Xcode.latest_version} (or delete it). #{MacOS::Xcode.update_instructions} EOS diff --git a/Library/Homebrew/extend/os/mac/extend/ENV/shared.rb b/Library/Homebrew/extend/os/mac/extend/ENV/shared.rb index 1939f9edf1952a..393f1901dc827b 100644 --- a/Library/Homebrew/extend/os/mac/extend/ENV/shared.rb +++ b/Library/Homebrew/extend/os/mac/extend/ENV/shared.rb @@ -14,9 +14,9 @@ module SharedEnvExtension } def setup_build_environment(formula: nil, cc: nil, build_bottle: false, bottle_arch: nil, testing_formula: false, debug_symbols: false) - generic_shared_setup_build_environment(formula: formula, cc: cc, build_bottle: build_bottle, - bottle_arch: bottle_arch, testing_formula: testing_formula, - debug_symbols: debug_symbols) + generic_shared_setup_build_environment(formula:, cc:, build_bottle:, + bottle_arch:, testing_formula:, + debug_symbols:) # Normalise the system Perl version used, where multiple may be available self["VERSIONER_PERL_VERSION"] = MacOS.preferred_perl_version @@ -35,15 +35,9 @@ def no_weak_imports_support? sig { returns(T::Boolean) } def no_fixup_chains_support? - return false if MacOS.version <= :catalina - - # NOTE: `-version_details` is supported in Xcode 10.2 at the earliest. - ld_version_details = JSON.parse(Utils.safe_popen_read("/usr/bin/ld", "-version_details")) - ld_version = Version.parse(ld_version_details["version"]) - # This is supported starting Xcode 13, which ships ld64-711. # https://developer.apple.com/documentation/xcode-release-notes/xcode-13-release-notes # https://en.wikipedia.org/wiki/Xcode#Xcode_11.0_-_14.x_(since_SwiftUI_framework)_2 - ld_version >= 711 + DevelopmentTools.ld64_version >= 711 end end diff --git a/Library/Homebrew/extend/os/mac/extend/ENV/std.rb b/Library/Homebrew/extend/os/mac/extend/ENV/std.rb index 0312bfc5bd4ce7..51e79be5060243 100644 --- a/Library/Homebrew/extend/os/mac/extend/ENV/std.rb +++ b/Library/Homebrew/extend/os/mac/extend/ENV/std.rb @@ -12,8 +12,8 @@ def homebrew_extra_pkg_config_paths def setup_build_environment(formula: nil, cc: nil, build_bottle: false, bottle_arch: nil, testing_formula: false, debug_symbols: false) - generic_setup_build_environment(formula: formula, cc: cc, build_bottle: build_bottle, bottle_arch: bottle_arch, - testing_formula: testing_formula, debug_symbols: debug_symbols) + generic_setup_build_environment(formula:, cc:, build_bottle:, bottle_arch:, + testing_formula:, debug_symbols:) append "LDFLAGS", "-Wl,-headerpad_max_install_names" @@ -23,7 +23,7 @@ def setup_build_environment(formula: nil, cc: nil, build_bottle: false, bottle_a self["LC_CTYPE"] = "C" # Add lib and include etc. from the current macosxsdk to compiler flags: - macosxsdk(formula: @formula, testing_formula: testing_formula) + macosxsdk(formula: @formula, testing_formula:) return unless MacOS::Xcode.without_clt? diff --git a/Library/Homebrew/extend/os/mac/extend/ENV/super.rb b/Library/Homebrew/extend/os/mac/extend/ENV/super.rb index 5cd1731b969041..bfcd39695e8520 100644 --- a/Library/Homebrew/extend/os/mac/extend/ENV/super.rb +++ b/Library/Homebrew/extend/os/mac/extend/ENV/super.rb @@ -99,8 +99,8 @@ def setup_build_environment(formula: nil, cc: nil, build_bottle: false, bottle_a MacOS::CLT::PKG_PATH end - generic_setup_build_environment(formula: formula, cc: cc, build_bottle: build_bottle, bottle_arch: bottle_arch, - testing_formula: testing_formula, debug_symbols: debug_symbols) + generic_setup_build_environment(formula:, cc:, build_bottle:, bottle_arch:, + testing_formula:, debug_symbols:) # Filter out symbols known not to be defined since GNU Autotools can't # reliably figure this out with Xcode 8 and above. @@ -140,6 +140,9 @@ def setup_build_environment(formula: nil, cc: nil, build_bottle: false, bottle_a # See: https://github.com/python/cpython/issues/97524 # https://github.com/pybind/pybind11/pull/4301 no_fixup_chains + + # Strip build prefixes from linker where supported, for deterministic builds. + append_to_cccfg "o" if DevelopmentTools.ld64_version >= 512 end def no_weak_imports diff --git a/Library/Homebrew/extend/os/mac/formula.rb b/Library/Homebrew/extend/os/mac/formula.rb index a5dbd1684c62c3..1d427eed33434a 100644 --- a/Library/Homebrew/extend/os/mac/formula.rb +++ b/Library/Homebrew/extend/os/mac/formula.rb @@ -18,8 +18,8 @@ def valid_platform? ).returns(T::Array[String]) } def std_cmake_args(install_prefix: prefix, install_libdir: "lib", find_framework: "LAST") - args = generic_std_cmake_args(install_prefix: install_prefix, install_libdir: install_libdir, - find_framework: find_framework) + args = generic_std_cmake_args(install_prefix:, install_libdir:, + find_framework:) # Avoid false positives for clock_gettime support on 10.11. # CMake cache entries for other weak symbols may be added here as needed. diff --git a/Library/Homebrew/extend/os/mac/keg_relocate.rb b/Library/Homebrew/extend/os/mac/keg_relocate.rb index 783f391e275fe6..dee1be95457774 100644 --- a/Library/Homebrew/extend/os/mac/keg_relocate.rb +++ b/Library/Homebrew/extend/os/mac/keg_relocate.rb @@ -133,7 +133,7 @@ def fixed_name(file, bad_name) VARIABLE_REFERENCE_RX = /^@(loader_|executable_|r)path/ def each_linkage_for(file, linkage_type, resolve_variable_references: false, &block) - file.public_send(linkage_type, resolve_variable_references: resolve_variable_references) + file.public_send(linkage_type, resolve_variable_references:) .grep_v(VARIABLE_REFERENCE_RX) .each(&block) end diff --git a/Library/Homebrew/extend/os/mac/unpack_strategy/zip.rb b/Library/Homebrew/extend/os/mac/unpack_strategy/zip.rb index 37c9ccc636f7d7..da2ec316920e00 100644 --- a/Library/Homebrew/extend/os/mac/unpack_strategy/zip.rb +++ b/Library/Homebrew/extend/os/mac/unpack_strategy/zip.rb @@ -17,7 +17,7 @@ def extract_to_dir(unpack_dir, basename:, verbose:) # (Also, Homebrew's ZIP artifact automatically deletes this folder.) return system_command! "ditto", args: ["-x", "-k", path, unpack_dir], - verbose: verbose, + verbose:, print_stderr: false end @@ -26,9 +26,9 @@ def extract_to_dir(unpack_dir, basename:, verbose:) rescue ErrorDuringExecution => e raise unless e.stderr.include?("End-of-central-directory signature not found.") - system_command! "ditto", + system_command!("ditto", args: ["-x", "-k", path, unpack_dir], - verbose: verbose + verbose:) nil end @@ -45,12 +45,12 @@ def extract_to_dir(unpack_dir, basename:, verbose:) # `ditto` keeps Finder attributes intact and does not skip volume labels # like `unzip` does, which can prevent disk images from being unzipped. - system_command! "ditto", + system_command!("ditto", args: ["-x", "-k", path, tmp_unpack_dir], - verbose: verbose + verbose:) volumes.each do |volume| - FileUtils.mv tmp_unpack_dir/volume, unpack_dir/volume, verbose: verbose + FileUtils.mv tmp_unpack_dir/volume, unpack_dir/volume, verbose: end end end diff --git a/Library/Homebrew/formula.rb b/Library/Homebrew/formula.rb index f2b683c75613cf..0a5b11abdcc99a 100644 --- a/Library/Homebrew/formula.rb +++ b/Library/Homebrew/formula.rb @@ -525,6 +525,14 @@ def versioned_formulae end.sort_by(&:version).reverse end + # Whether this {Formula} is version-synced with other formulae. + sig { returns(T::Boolean) } + def synced_with_other_formulae? + return false if @tap.nil? + + @tap.synced_versions_formulae.any? { |synced_formulae| synced_formulae.include?(name) } + end + # A named {Resource} for the currently active {SoftwareSpec}. # Additional downloads can be defined as {#resource}s. # {Resource#stage} will create a temporary directory and yield to a block. @@ -544,7 +552,7 @@ def oldname sig { returns(T::Array[String]) } def oldnames @oldnames ||= if (tap = self.tap) - Tap.reverse_tap_migrations_renames.fetch("#{tap}/#{name}", []) + + Tap.tap_migration_oldnames(tap, name) + tap.formula_reverse_renames.fetch(name, []) else [] @@ -1400,7 +1408,7 @@ def patch def brew(fetch: true, keep_tmp: false, debug_symbols: false, interactive: false) @prefix_returns_versioned_prefix = true active_spec.fetch if fetch - stage(interactive: interactive, debug_symbols: debug_symbols) do |staging| + stage(interactive:, debug_symbols:) do |staging| staging.retain! if keep_tmp || debug_symbols prepare_patches @@ -1497,7 +1505,7 @@ def outdated_kegs(fetch_head: false) end if current_version || - ((head_version = latest_head_version) && !head_version_outdated?(head_version, fetch_head: fetch_head)) + ((head_version = latest_head_version) && !head_version_outdated?(head_version, fetch_head:)) [] else all_kegs += old_installed_formulae.flat_map(&:installed_kegs) @@ -1556,7 +1564,7 @@ def old_installed_formulae # @private sig { params(fetch_head: T::Boolean).returns(T::Boolean) } def outdated?(fetch_head: false) - !outdated_kegs(fetch_head: fetch_head).empty? + !outdated_kegs(fetch_head:).empty? rescue Migrator::MigrationNeededError true end @@ -2069,14 +2077,14 @@ def tap_git_head # @private def recursive_dependencies(&block) cache_key = "Formula#recursive_dependencies" unless block - Dependency.expand(self, cache_key: cache_key, &block) + Dependency.expand(self, cache_key:, &block) end # The full set of Requirements for this formula's dependency tree. # @private def recursive_requirements(&block) cache_key = "Formula#recursive_requirements" unless block - Requirement.expand(self, cache_key: cache_key, &block) + Requirement.expand(self, cache_key:, &block) end # Returns a Keg for the opt_prefix or installed_prefix if they exist. @@ -2132,8 +2140,8 @@ def runtime_formula_dependencies(read_from_tab: true, undeclared: true) Formula.cache[:runtime_formula_dependencies] ||= {} Formula.cache[:runtime_formula_dependencies][cache_key] ||= runtime_dependencies( - read_from_tab: read_from_tab, - undeclared: undeclared, + read_from_tab:, + undeclared:, ).filter_map do |d| d.to_formula rescue FormulaUnavailableError @@ -2190,7 +2198,7 @@ def merge_spec_dependables(dependables) all_dependables.map do |dependable| { - dependable: dependable, + dependable:, # Now find the list of specs each dependency was a part of. specs: dependables.filter_map { |spec, spec_deps| spec if spec_deps&.include?(dependable) }, } @@ -2285,7 +2293,7 @@ def to_hash end # @private - def to_api_hash + def to_internal_api_hash api_hash = { "desc" => desc, "license" => SPDX.license_expression_to_string(license), @@ -2348,14 +2356,14 @@ def to_api_hash # @private def to_hash_with_variations(hash_method: :to_hash) - if loaded_from_api? && hash_method == :to_api_hash + if loaded_from_api? && hash_method == :to_internal_api_hash raise ArgumentError, "API Hash must be generated from Ruby source files" end namespace_prefix = case hash_method when :to_hash "Variations" - when :to_api_hash + when :to_internal_api_hash "APIVariations" else raise ArgumentError, "Unknown hash method #{hash_method.inspect}" @@ -2376,15 +2384,15 @@ def to_hash_with_variations(hash_method: :to_hash) if path.exist? && on_system_blocks_exist? formula_contents = path.read OnSystem::ALL_OS_ARCH_COMBINATIONS.each do |os, arch| - bottle_tag = Utils::Bottles::Tag.new(system: os, arch: arch) + bottle_tag = Utils::Bottles::Tag.new(system: os, arch:) next unless bottle_tag.valid_combination? - Homebrew::SimulateSystem.with os: os, arch: arch do + Homebrew::SimulateSystem.with(os:, arch:) do variations_namespace = Formulary.class_s("#{namespace_prefix}#{bottle_tag.to_sym.capitalize}") variations_formula_class = Formulary.load_formula(name, path, formula_contents, variations_namespace, flags: self.class.build_flags, ignore_errors: true) variations_formula = variations_formula_class.new(name, path, :stable, - alias_path: alias_path, force_bottle: force_bottle) + alias_path:, force_bottle:) variations_formula.public_send(hash_method).each do |key, value| next if value.to_s == hash[key].to_s @@ -2396,7 +2404,7 @@ def to_hash_with_variations(hash_method: :to_hash) end end - hash["variations"] = variations if hash_method != :to_api_hash || variations.present? + hash["variations"] = variations if hash_method != :to_internal_api_hash || variations.present? hash end @@ -2555,7 +2563,7 @@ def on_system_blocks_exist? # @private def fetch(verify_download_integrity: true) - active_spec.fetch(verify_download_integrity: verify_download_integrity) + active_spec.fetch(verify_download_integrity:) end # @private @@ -2653,7 +2661,7 @@ def install; end ).void } def inreplace(paths, before = nil, after = nil, audit_result = true, &block) # rubocop:disable Style/OptionalBooleanParameter - Utils::Inreplace.inreplace(paths, before, after, audit_result: audit_result, &block) + Utils::Inreplace.inreplace(paths, before, after, audit_result:, &block) rescue Utils::Inreplace::Error => e onoe e.to_s raise BuildError.new(self, "inreplace", Array(paths), {}) @@ -2661,15 +2669,8 @@ def inreplace(paths, before = nil, after = nil, audit_result = true, &block) # r protected + sig { params(home: Pathname).void } def setup_home(home) - # keep Homebrew's site-packages in sys.path when using system Python - user_site_packages = home/"Library/Python/2.7/lib/python/site-packages" - user_site_packages.mkpath - (user_site_packages/"homebrew.pth").write <<~PYTHON - import site; site.addsitedir("#{HOMEBREW_PREFIX}/lib/python2.7/site-packages") - import sys, os; sys.path = (os.environ["PYTHONPATH"].split(os.pathsep) if "PYTHONPATH" in os.environ else []) + ["#{HOMEBREW_PREFIX}/lib/python2.7/site-packages"] + sys.path - PYTHON - # Don't let bazel write to tmp directories we don't control or clean. (home/".bazelrc").write "startup --output_user_root=#{home}/_bazel" end @@ -2678,7 +2679,7 @@ def setup_home(home) # @private def declared_runtime_dependencies cache_key = "Formula#declared_runtime_dependencies" unless build.any_args_or_options? - Dependency.expand(self, cache_key: cache_key) do |_, dependency| + Dependency.expand(self, cache_key:) do |_, dependency| Dependency.prune if dependency.build? next if dependency.required? @@ -2976,7 +2977,7 @@ def common_stage_test_env end def stage(interactive: false, debug_symbols: false) - active_spec.stage(debug_symbols: debug_symbols) do |staging| + active_spec.stage(debug_symbols:) do |staging| @source_modified_time = active_spec.source_modified_time @buildpath = Pathname.pwd env_home = T.must(buildpath)/".brew_home" @@ -3249,13 +3250,7 @@ def sha256(val) # sha256 high_sierra: "91dd0caca9bd3f38c439d5a7b6f68440c4274945615fae035ff0a369264b8a2f" # end # - # Homebrew maintainers aim to bottle all formulae that require compilation. - # - # Formulae that can be installed without compilation should be tagged with: - #
bottle :unneeded
- # - # Formulae which should not be bottled should be tagged with: - #
bottle :disable, "reasons"
+ # Homebrew maintainers aim to bottle all formulae. sig { params(block: T.proc.bind(BottleSpecification).void).void } def bottle(&block) stable.bottle(&block) diff --git a/Library/Homebrew/formula_auditor.rb b/Library/Homebrew/formula_auditor.rb index dd45ad3341d17f..648f35bbdb12b3 100644 --- a/Library/Homebrew/formula_auditor.rb +++ b/Library/Homebrew/formula_auditor.rb @@ -140,27 +140,13 @@ def self.aliases @aliases ||= Formula.aliases + Formula.tap_aliases end - def synced_versions_formulae_json - @synced_versions_formulae_json ||= JSON.parse(File.read("#{formula.tap.path}/synced_versions_formulae.json")) - end - - def synced_with_other_formulae? - return false unless formula.tap - - synced_versions_formulae_file = "#{formula.tap.path}/synced_versions_formulae.json" - return false unless File.exist?(synced_versions_formulae_file) - - synced_versions_formulae_json.any? { |synced_version_formulae| synced_version_formulae.include?(formula.name) } - end - def audit_synced_versions_formulae - return unless formula.tap - return unless synced_with_other_formulae? + return unless formula.synced_with_other_formulae? name = formula.name version = formula.version - synced_versions_formulae_json.each do |synced_version_formulae| + formula.tap.synced_versions_formulae.each do |synced_version_formulae| next unless synced_version_formulae.include?(name) synced_version_formulae.each do |synced_formula| @@ -256,6 +242,7 @@ def audit_license return if user.blank? tag = SharedAudits.github_tag_from_url(formula.stable.url) + tag ||= formula.stable.specs[:tag] github_license = GitHub.get_repo_license(user, repo, ref: tag) return unless github_license return if (licenses + ["NOASSERTION"]).include?(github_license) @@ -579,7 +566,7 @@ def audit_homepage user_agents: [:browser, :default], check_content: true, strict: @strict, - use_homebrew_curl: use_homebrew_curl, + use_homebrew_curl:, )) problem http_content_problem end @@ -706,7 +693,7 @@ def audit_specs ra = ResourceAuditor.new( spec, spec_name, - online: @online, strict: @strict, only: @only, except: except, + online: @online, strict: @strict, only: @only, except:, use_homebrew_curl: spec.using == :homebrew_curl ).audit ra.problems.each do |message| @@ -795,7 +782,7 @@ def audit_specs tag ||= stable.version if @online - error = SharedAudits.gitlab_release(owner, repo, tag, formula: formula) + error = SharedAudits.gitlab_release(owner, repo, tag, formula:) problem error if error end when %r{^https://github.com/([\w-]+)/([\w-]+)} @@ -805,7 +792,7 @@ def audit_specs tag ||= formula.stable.specs[:tag] if @online - error = SharedAudits.github_release(owner, repo, tag, formula: formula) + error = SharedAudits.github_release(owner, repo, tag, formula:) problem error if error end end @@ -969,11 +956,11 @@ def audit private def problem(message, location: nil, corrected: false) - @problems << ({ message: message, location: location, corrected: corrected }) + @problems << ({ message:, location:, corrected: }) end def new_formula_problem(message, location: nil, corrected: false) - @new_formula_problems << ({ message: message, location: location, corrected: corrected }) + @new_formula_problems << ({ message:, location:, corrected: }) end def head_only?(formula) @@ -989,7 +976,7 @@ def linux_only_gcc_dep?(formula) return false if variations.blank? MacOSVersion::SYMBOLS.keys.product(OnSystem::ARCH_OPTIONS).each do |os, arch| - bottle_tag = Utils::Bottles::Tag.new(system: os, arch: arch) + bottle_tag = Utils::Bottles::Tag.new(system: os, arch:) next unless bottle_tag.valid_combination? variation_dependencies = variations.dig(bottle_tag.to_sym, "dependencies") diff --git a/Library/Homebrew/formula_installer.rb b/Library/Homebrew/formula_installer.rb index 4d7a21cf960bd3..116a6e28ac8b97 100644 --- a/Library/Homebrew/formula_installer.rb +++ b/Library/Homebrew/formula_installer.rb @@ -206,8 +206,10 @@ def prelude case deprecate_disable_type when :deprecated + puts "::warning::#{message}" if ENV["GITHUB_ACTIONS"] opoo message when :disabled + puts "::error::#{message}" if ENV["GITHUB_ACTIONS"] raise CannotInstallFormulaError, message end end @@ -419,8 +421,8 @@ def install oh1 "Installing #{Formatter.identifier(formula.full_name)} #{options}".strip if show_header? if (tap = formula.tap) && tap.should_report_analytics? - Utils::Analytics.report_event(:formula_install, package_name: formula.name, tap_name: tap.name, -on_request: installed_on_request?, options: options) + Utils::Analytics.report_package_event(:formula_install, package_name: formula.name, tap_name: tap.name, +on_request: installed_on_request?, options:) end self.class.attempted << formula @@ -597,7 +599,7 @@ def expand_requirements def expand_dependencies_for_formula(formula, inherited_options) # Cache for this expansion only. FormulaInstaller has a lot of inputs which can alter expansion. cache_key = "FormulaInstaller-#{formula.full_name}-#{Time.now.to_f}" - Dependency.expand(formula, cache_key: cache_key) do |dependent, dep| + Dependency.expand(formula, cache_key:) do |dependent, dep| inherited_options[dep.name] |= inherited_options_for(dep) build = effective_build_options_for( dependent, @@ -664,7 +666,7 @@ def install_dependencies(deps) puts "All dependencies for #{formula.full_name} are satisfied." elsif !deps.empty? oh1 "Installing dependencies for #{formula.full_name}: " \ - "#{deps.map(&:first).map(&Formatter.method(:identifier)).to_sentence}", + "#{deps.map(&:first).map { Formatter.identifier(_1) }.to_sentence}", truncate: false deps.each { |dep, options| install_dependency(dep, options) } end @@ -732,7 +734,7 @@ def install_dependency(dep, inherited_options) fi = FormulaInstaller.new( df, - options: options, + options:, link_keg: keg_had_linked_keg ? keg_was_linked : nil, installed_as_dependency: true, installed_on_request: df.any_version_installed? && tab.present? && tab.installed_on_request, @@ -1184,7 +1186,7 @@ def fetch_dependencies return if deps.empty? oh1 "Fetching dependencies for #{formula.full_name}: " \ - "#{deps.map(&:first).map(&Formatter.method(:identifier)).to_sentence}", + "#{deps.map(&:first).map { Formatter.identifier(_1) }.to_sentence}", truncate: false deps.each { |(dep, _options)| fetch_dependency(dep) } @@ -1280,7 +1282,7 @@ def pour keg = Keg.new(formula.prefix) skip_linkage = formula.bottle_specification.skip_relocation? - keg.replace_placeholders_with_locations tab.changed_files, skip_linkage: skip_linkage + keg.replace_placeholders_with_locations(tab.changed_files, skip_linkage:) cellar = formula.bottle_specification.tag_to_cellar(Utils::Bottles.tag) return if [:any, :any_skip_relocation].include?(cellar) diff --git a/Library/Homebrew/formulary.rb b/Library/Homebrew/formulary.rb index 9a43cef169cbc9..c1fa055f6fedff 100644 --- a/Library/Homebrew/formulary.rb +++ b/Library/Homebrew/formulary.rb @@ -145,7 +145,7 @@ def self.namespace_key(identifier) def self.load_formula_from_path(name, path, flags:, ignore_errors:) contents = path.open("r") { |f| ensure_utf8_encoding(f).read } namespace = "FormulaNamespace#{namespace_key(path.to_s)}" - klass = load_formula(name, path, contents, namespace, flags: flags, ignore_errors: ignore_errors) + klass = load_formula(name, path, contents, namespace, flags:, ignore_errors:) platform_cache[:path] ||= {} platform_cache[:path][path] = klass end @@ -305,7 +305,7 @@ def self.load_formula_from_api(name, flags:) rebuild bottles_stable["rebuild"] bottles_stable["files"].each do |tag, bottle_spec| cellar = Formulary.convert_to_string_or_symbol bottle_spec["cellar"] - sha256 cellar: cellar, tag.to_sym => bottle_spec["sha256"] + sha256 cellar:, tag.to_sym => bottle_spec["sha256"] end end end @@ -434,8 +434,8 @@ def self.resolve( flags: T.unsafe(nil) ) options = { - force_bottle: force_bottle, - flags: flags, + force_bottle:, + flags:, }.compact if name.include?("/") || File.exist?(name) @@ -523,12 +523,12 @@ def initialize(name, path, alias_path: T.unsafe(nil), tap: T.unsafe(nil)) # a formula that was loaded in another way. def get_formula(spec, alias_path: nil, force_bottle: false, flags: [], ignore_errors: false) alias_path ||= self.alias_path - klass(flags: flags, ignore_errors: ignore_errors) - .new(name, path, spec, alias_path: alias_path, tap: tap, force_bottle: force_bottle) + klass(flags:, ignore_errors:) + .new(name, path, spec, alias_path:, tap:, force_bottle:) end def klass(flags:, ignore_errors:) - load_file(flags: flags, ignore_errors: ignore_errors) unless Formulary.formula_class_defined_from_path?(path) + load_file(flags:, ignore_errors:) unless Formulary.formula_class_defined_from_path?(path) Formulary.formula_class_get_from_path(path) end @@ -537,7 +537,7 @@ def klass(flags:, ignore_errors:) def load_file(flags:, ignore_errors:) raise FormulaUnavailableError, name unless path.file? - Formulary.load_formula_from_path(name, path, flags: flags, ignore_errors: ignore_errors) + Formulary.load_formula_from_path(name, path, flags:, ignore_errors:) end end @@ -574,9 +574,9 @@ def initialize(bottle_name) def get_formula(spec, force_bottle: false, flags: [], ignore_errors: false, **) formula = begin - contents = Utils::Bottles.formula_contents @bottle_filename, name: name - Formulary.from_contents(name, path, contents, spec, force_bottle: force_bottle, - flags: flags, ignore_errors: ignore_errors) + contents = Utils::Bottles.formula_contents(@bottle_filename, name:) + Formulary.from_contents(name, path, contents, spec, force_bottle:, + flags:, ignore_errors:) rescue FormulaUnreadableError => e opoo <<~EOS Unreadable formula in #{@bottle_filename}: @@ -620,18 +620,18 @@ def self.try_new(ref, from: T.unsafe(nil), warn: false) path = alias_path.resolved_path { - alias_path: alias_path, - tap: tap, + alias_path:, + tap:, } else { - tap: tap, + tap:, } end elsif (tap = Homebrew::API.tap_from_source_download(path)) # Don't treat cache symlinks as aliases. { - tap: tap, + tap:, } else {} @@ -651,7 +651,7 @@ def initialize(path, alias_path: T.unsafe(nil), tap: T.unsafe(nil)) options = { alias_path: (alias_path if alias_dir == tap&.alias_dir), - tap: tap, + tap:, }.compact super(name, path, **options) @@ -667,7 +667,7 @@ class FromURILoader < FormulaLoader def self.try_new(ref, from: T.unsafe(nil), warn: false) ref = ref.to_s - new(ref, from: from) if URL_START_REGEX.match?(ref) + new(ref, from:) if URL_START_REGEX.match?(ref) end attr_reader :url @@ -722,7 +722,7 @@ class FromTapLoader < FormulaLoader def self.try_new(ref, from: T.unsafe(nil), warn: false) ref = ref.to_s - return unless (name_tap_type = Formulary.tap_formula_name_type(ref, warn: warn)) + return unless (name_tap_type = Formulary.tap_formula_name_type(ref, warn:)) name, tap, type = name_tap_type path = Formulary.find_formula_in_tap(name, tap) @@ -734,14 +734,14 @@ def self.try_new(ref, from: T.unsafe(nil), warn: false) {} end - new(name, path, tap: tap, **options) + new(name, path, tap:, **options) end sig { params(name: String, path: Pathname, tap: Tap, alias_name: String).void } def initialize(name, path, tap:, alias_name: T.unsafe(nil)) options = { alias_path: (tap.alias_dir/alias_name if alias_name), - tap: tap, + tap:, }.compact super(name, path, **options) @@ -765,22 +765,6 @@ def load_file(flags:, ignore_errors:) end end - class FromDefaultNameLoader < FromTapLoader - sig { - params(ref: T.any(String, Pathname, URI::Generic), from: Symbol, warn: T::Boolean) - .returns(T.nilable(T.attached_class)) - } - def self.try_new(ref, from: T.unsafe(nil), warn: false) - return unless ref.is_a?(String) - return unless (name = ref[HOMEBREW_DEFAULT_TAP_FORMULA_REGEX, :name]) - return unless (tap = CoreTap.instance).installed? - - return unless (loader = super("#{tap}/#{name}", warn: warn)) - - loader if loader.path.exist? - end - end - # Loads a formula from a name, as long as it exists only in a single tap. class FromNameLoader < FromTapLoader sig { @@ -789,11 +773,19 @@ class FromNameLoader < FromTapLoader } def self.try_new(ref, from: T.unsafe(nil), warn: false) return unless ref.is_a?(String) - return if ref.include?("/") + return unless ref.match?(/\A#{HOMEBREW_TAP_FORMULA_NAME_REGEX}\Z/o) name = ref - loaders = Tap.filter_map { |tap| super("#{tap}/#{name}", warn: warn) }.select { _1.path.exist? } + # If it exists in the default tap, never treat it as ambiguous with another tap. + if (core_tap = CoreTap.instance).installed? && + (loader = super("#{core_tap}/#{name}", warn:))&.path&.exist? + return loader + end + + loaders = Tap.select { |tap| tap.installed? && !tap.core_tap? } + .filter_map { |tap| super("#{tap}/#{name}", warn:) } + .select { |tap| tap.path.exist? } case loaders.count when 1 @@ -869,7 +861,7 @@ def initialize(name, path, contents) def klass(flags:, ignore_errors:) namespace = "FormulaNamespace#{Digest::MD5.hexdigest(contents.to_s)}" - Formulary.load_formula(name, path, contents, namespace, flags: flags, ignore_errors: ignore_errors) + Formulary.load_formula(name, path, contents, namespace, flags:, ignore_errors:) end end @@ -893,7 +885,7 @@ def self.try_new(ref, from: T.unsafe(nil), warn: false) ref = "#{CoreTap.instance}/#{name}" - return unless (name_tap_type = Formulary.tap_formula_name_type(ref, warn: warn)) + return unless (name_tap_type = Formulary.tap_formula_name_type(ref, warn:)) name, tap, type = name_tap_type @@ -903,28 +895,28 @@ def self.try_new(ref, from: T.unsafe(nil), warn: false) {} end - new(name, tap: tap, **options) + new(name, tap:, **options) end sig { params(name: String, tap: Tap, alias_name: String).void } def initialize(name, tap: T.unsafe(nil), alias_name: T.unsafe(nil)) options = { alias_path: (CoreTap.instance.alias_dir/alias_name if alias_name), - tap: tap, + tap:, }.compact super(name, Formulary.core_path(name), **options) end def klass(flags:, ignore_errors:) - load_from_api(flags: flags) unless Formulary.formula_class_defined_from_api?(name) + load_from_api(flags:) unless Formulary.formula_class_defined_from_api?(name) Formulary.formula_class_get_from_api(name) end private def load_from_api(flags:) - Formulary.load_formula_from_api(name, flags: flags) + Formulary.load_formula_from_api(name, flags:) end end @@ -962,11 +954,11 @@ def self.factory( return platform_cache[:formulary_factory][cache_key] end - loader_options = { from: from, warn: warn }.compact - formula_options = { alias_path: alias_path, - force_bottle: force_bottle, - flags: flags, - ignore_errors: ignore_errors }.compact + loader_options = { from:, warn: }.compact + formula_options = { alias_path:, + force_bottle:, + flags:, + ignore_errors: }.compact formula = loader_for(ref, **loader_options) .get_formula(spec, **formula_options) @@ -1005,9 +997,9 @@ def self.from_rack( keg = kegs.find(&:linked?) || kegs.find(&:optlinked?) || kegs.max_by(&:version) options = { - alias_path: alias_path, - force_bottle: force_bottle, - flags: flags, + alias_path:, + force_bottle:, + flags:, }.compact if keg @@ -1049,11 +1041,11 @@ def self.from_keg( formula_name = keg.rack.basename.to_s options = { - alias_path: alias_path, + alias_path:, from: :keg, warn: false, - force_bottle: force_bottle, - flags: flags, + force_bottle:, + flags:, }.compact f = if tap.nil? @@ -1096,10 +1088,10 @@ def self.from_contents( ignore_errors: T.unsafe(nil) ) options = { - alias_path: alias_path, - force_bottle: force_bottle, - flags: flags, - ignore_errors: ignore_errors, + alias_path:, + force_bottle:, + flags:, + ignore_errors:, }.compact FormulaContentsLoader.new(name, path, contents).get_formula(spec, **options) end @@ -1151,9 +1143,7 @@ def self.tap_formula_name_type(tapped_name, warn:) new_name = tap.core_tap? ? name : "#{tap}/#{name}" type = :rename elsif (new_tap_name = tap.tap_migrations[name].presence) - new_tap_user, new_tap_repo, new_name = new_tap_name.split("/", 3) - new_name ||= name - new_tap = Tap.fetch(new_tap_user, new_tap_repo) + new_tap, new_name = Tap.with_formula_name(new_tap_name) || [Tap.fetch(new_tap_name), name] new_tap.ensure_installed! new_tapped_name = "#{new_tap}/#{new_name}" @@ -1176,7 +1166,7 @@ def self.tap_formula_name_type(tapped_name, warn:) end def self.loader_for(ref, from: T.unsafe(nil), warn: true) - options = { from: from, warn: warn }.compact + options = { from:, warn: }.compact [ FromBottleLoader, @@ -1184,7 +1174,6 @@ def self.loader_for(ref, from: T.unsafe(nil), warn: true) FromAPILoader, FromTapLoader, FromPathLoader, - FromDefaultNameLoader, FromNameLoader, FromKegLoader, FromCacheLoader, diff --git a/Library/Homebrew/git_repository.rb b/Library/Homebrew/git_repository.rb index c50626f5fd246e..5bff80e06dbe4b 100644 --- a/Library/Homebrew/git_repository.rb +++ b/Library/Homebrew/git_repository.rb @@ -38,14 +38,14 @@ def origin_url=(origin) # Gets the full commit hash of the HEAD commit. sig { params(safe: T::Boolean).returns(T.nilable(String)) } def head_ref(safe: false) - popen_git("rev-parse", "--verify", "--quiet", "HEAD", safe: safe) + popen_git("rev-parse", "--verify", "--quiet", "HEAD", safe:) end # Gets a short commit hash of the HEAD commit. sig { params(length: T.nilable(Integer), safe: T::Boolean).returns(T.nilable(String)) } def short_head_ref(length: nil, safe: false) short_arg = length.present? ? "--short=#{length}" : "--short" - popen_git("rev-parse", short_arg, "--verify", "--quiet", "HEAD", safe: safe) + popen_git("rev-parse", short_arg, "--verify", "--quiet", "HEAD", safe:) end # Gets the relative date of the last commit, e.g. "1 hour ago" @@ -57,7 +57,7 @@ def last_committed # Gets the name of the currently checked-out branch, or HEAD if the repository is in a detached HEAD state. sig { params(safe: T::Boolean).returns(T.nilable(String)) } def branch_name(safe: false) - popen_git("rev-parse", "--abbrev-ref", "HEAD", safe: safe) + popen_git("rev-parse", "--abbrev-ref", "HEAD", safe:) end # Change the name of a local branch @@ -104,7 +104,7 @@ def set_head_origin_auto # Gets the full commit message of the specified commit, or of the HEAD commit if unspecified. sig { params(commit: String, safe: T::Boolean).returns(T.nilable(String)) } def commit_message(commit = "HEAD", safe: false) - popen_git("log", "-1", "--pretty=%B", commit, "--", safe: safe, err: :out)&.strip + popen_git("log", "-1", "--pretty=%B", commit, "--", safe:, err: :out)&.strip end sig { returns(String) } @@ -128,6 +128,6 @@ def popen_git(*args, safe: false, err: nil) raise "Git is unavailable" end - Utils.popen_read(Utils::Git.git, *args, safe: safe, chdir: pathname, err: err).chomp.presence + Utils.popen_read(Utils::Git.git, *args, safe:, chdir: pathname, err:).chomp.presence end end diff --git a/Library/Homebrew/github_packages.rb b/Library/Homebrew/github_packages.rb index b54ae151378d76..9b1766ea600c3c 100644 --- a/Library/Homebrew/github_packages.rb +++ b/Library/Homebrew/github_packages.rb @@ -67,7 +67,7 @@ def upload_bottles(bottles_hash, keep_old:, dry_run:, warn_on_error:) bottles_hash.each do |formula_full_name, bottle_hash| # First, check that we won't encounter an error in the middle of uploading bottles. preupload_check(user, token, skopeo, formula_full_name, bottle_hash, - keep_old: keep_old, dry_run: dry_run, warn_on_error: warn_on_error) + keep_old:, dry_run:, warn_on_error:) end # We intentionally iterate over `bottles_hash` twice to @@ -76,7 +76,7 @@ def upload_bottles(bottles_hash, keep_old:, dry_run:, warn_on_error:) bottles_hash.each do |formula_full_name, bottle_hash| # Next, upload the bottles after checking them all. upload_bottle(user, token, skopeo, formula_full_name, bottle_hash, - keep_old: keep_old, dry_run: dry_run, warn_on_error: warn_on_error) + keep_old:, dry_run:, warn_on_error:) end # rubocop:enable Style/CombinableLoops end @@ -207,7 +207,7 @@ def download(user, token, skopeo, image_uri, root, dry_run:) puts "#{skopeo} #{args.join(" ")} --src-creds=#{user}:$HOMEBREW_GITHUB_PACKAGES_TOKEN" else args << "--src-creds=#{user}:#{token}" - system_command!(skopeo, verbose: true, print_stdout: true, args: args) + system_command!(skopeo, verbose: true, print_stdout: true, args:) end end @@ -263,7 +263,7 @@ def preupload_check(user, token, skopeo, _formula_full_name, bottle_hash, keep_o def upload_bottle(user, token, skopeo, formula_full_name, bottle_hash, keep_old:, dry_run:, warn_on_error:) # We run the preupload check twice to prevent TOCTOU bugs. result = preupload_check(user, token, skopeo, formula_full_name, bottle_hash, - keep_old: keep_old, dry_run: dry_run, warn_on_error: warn_on_error) + keep_old:, dry_run:, warn_on_error:) formula_name, org, repo, version, rebuild, version_rebuild, image_name, image_uri, keep_old = *result @@ -272,7 +272,7 @@ def upload_bottle(user, token, skopeo, formula_full_name, bottle_hash, keep_old: root.mkpath if keep_old - download(user, token, skopeo, image_uri, root, dry_run: dry_run) + download(user, token, skopeo, image_uri, root, dry_run:) else write_image_layout(root) end @@ -368,8 +368,8 @@ def upload_bottle(user, token, skopeo, formula_full_name, bottle_hash, keep_old: end platform_hash = { - architecture: architecture, - os: os, + architecture:, + os:, "os.version" => os_version, }.compact_blank @@ -446,7 +446,7 @@ def upload_bottle(user, token, skopeo, formula_full_name, bottle_hash, keep_old: args << "--dest-creds=#{user}:#{token}" retry_count = 0 begin - system_command!(skopeo, verbose: true, print_stdout: true, args: args) + system_command!(skopeo, verbose: true, print_stdout: true, args:) rescue ErrorDuringExecution retry_count += 1 odie "Cannot perform an upload to registry after retrying multiple times!" if retry_count >= 10 @@ -486,8 +486,8 @@ def write_image_config(platform_hash, tar_sha256, blobs) def write_image_index(manifests, blobs, annotations) image_index = { schemaVersion: 2, - manifests: manifests, - annotations: annotations, + manifests:, + annotations:, } validate_schema!(IMAGE_INDEX_SCHEMA_URI, image_index) write_hash(blobs, image_index) @@ -500,7 +500,7 @@ def write_index_json(index_json_sha256, index_json_size, root, annotations) mediaType: "application/vnd.oci.image.index.v1+json", digest: "sha256:#{index_json_sha256}", size: index_json_size, - annotations: annotations, + annotations:, }], } validate_schema!(IMAGE_INDEX_SCHEMA_URI, index_json) diff --git a/Library/Homebrew/github_releases.rb b/Library/Homebrew/github_releases.rb index fdd08efdf85311..599ae363b90485 100644 --- a/Library/Homebrew/github_releases.rb +++ b/Library/Homebrew/github_releases.rb @@ -34,7 +34,7 @@ def upload_bottles(bottles_hash) remote_file = tag_hash["filename"] local_file = tag_hash["local_filename"] odebug "Uploading #{remote_file}" - GitHub.upload_release_asset user, repo, release["id"], local_file: local_file, remote_file: remote_file + GitHub.upload_release_asset user, repo, release["id"], local_file:, remote_file: end end end diff --git a/Library/Homebrew/github_runner_matrix.rb b/Library/Homebrew/github_runner_matrix.rb index 812876741b5dcc..a8ea015b0c3b34 100644 --- a/Library/Homebrew/github_runner_matrix.rb +++ b/Library/Homebrew/github_runner_matrix.rb @@ -100,7 +100,7 @@ def create_runner(platform, arch, spec, macos_version = nil) raise "Unexpected platform: #{platform}" if VALID_PLATFORMS.exclude?(platform) raise "Unexpected arch: #{arch}" if VALID_ARCHES.exclude?(arch) - runner = GitHubRunner.new(platform: platform, arch: arch, spec: spec, macos_version: macos_version) + runner = GitHubRunner.new(platform:, arch:, spec:, macos_version:) runner.active = active_runner?(runner) runner.freeze end @@ -147,7 +147,7 @@ def generate_runners! spec = MacOSRunnerSpec.new( name: "macOS #{version}-x86_64", - runner: runner, + runner:, timeout: runner_timeout, cleanup: !runner.end_with?(ephemeral_suffix), ) @@ -167,7 +167,7 @@ def generate_runners! runner_timeout /= 2 if runner_timeout < GITHUB_ACTIONS_LONG_TIMEOUT spec = MacOSRunnerSpec.new( name: "macOS #{version}-arm64", - runner: runner, + runner:, timeout: runner_timeout, cleanup: !runner.end_with?(ephemeral_suffix), ) @@ -214,7 +214,7 @@ def formulae_have_untested_dependents?(runner) next false unless formula.public_send(:"#{arch}_compatible?") next false if macos_version.present? && !formula.compatible_with?(macos_version) - compatible_dependents = formula.dependents(platform: platform, arch: arch, macos_version: macos_version&.to_sym) + compatible_dependents = formula.dependents(platform:, arch:, macos_version: macos_version&.to_sym) .dup compatible_dependents.select! do |dependent_f| diff --git a/Library/Homebrew/help.rb b/Library/Homebrew/help.rb index a90d5a2d493d0d..94b68616eff3b6 100644 --- a/Library/Homebrew/help.rb +++ b/Library/Homebrew/help.rb @@ -59,7 +59,7 @@ def self.help(cmd = nil, empty_argv: false, usage_error: nil, remaining_args: [] # Display command-specific (or generic) help in response to `UsageError`. if usage_error - $stderr.puts path ? command_help(cmd, path, remaining_args: remaining_args) : HOMEBREW_HELP + $stderr.puts path ? command_help(cmd, path, remaining_args:) : HOMEBREW_HELP $stderr.puts onoe usage_error exit 1 @@ -69,7 +69,7 @@ def self.help(cmd = nil, empty_argv: false, usage_error: nil, remaining_args: [] return if path.nil? # Display help for internal command (or generic help if undocumented). - puts command_help(cmd, path, remaining_args: remaining_args) + puts command_help(cmd, path, remaining_args:) exit 0 end @@ -78,7 +78,7 @@ def self.command_help(cmd, path, remaining_args:) output = if Commands.valid_internal_cmd?(cmd) || Commands.valid_internal_dev_cmd?(cmd) || Commands.external_ruby_v2_cmd_path(cmd) - parser_help(path, remaining_args: remaining_args) + parser_help(path, remaining_args:) end output ||= comment_help(path) diff --git a/Library/Homebrew/install.rb b/Library/Homebrew/install.rb index efc67360e5ab9a..82b0465d9a3381 100644 --- a/Library/Homebrew/install.rb +++ b/Library/Homebrew/install.rb @@ -78,7 +78,7 @@ def install_formula?( installed_head_version = formula.latest_head_version if installed_head_version && - !formula.head_version_outdated?(installed_head_version, fetch_head: fetch_head) + !formula.head_version_outdated?(installed_head_version, fetch_head:) new_head_installed = true end prefix_installed = formula.prefix.exist? && !formula.prefix.children.empty? @@ -245,30 +245,30 @@ def install_formulae( skip_post_install: false ) formula_installers = formulae_to_install.filter_map do |formula| - Migrator.migrate_if_needed(formula, force: force, dry_run: dry_run) + Migrator.migrate_if_needed(formula, force:, dry_run:) build_options = formula.build formula_installer = FormulaInstaller.new( formula, options: build_options.used_options, - build_bottle: build_bottle, - force_bottle: force_bottle, - bottle_arch: bottle_arch, - ignore_deps: ignore_deps, - only_deps: only_deps, - include_test_formulae: include_test_formulae, - build_from_source_formulae: build_from_source_formulae, - cc: cc, - git: git, - interactive: interactive, - keep_tmp: keep_tmp, - debug_symbols: debug_symbols, - force: force, - overwrite: overwrite, - debug: debug, - quiet: quiet, - verbose: verbose, - skip_post_install: skip_post_install, + build_bottle:, + force_bottle:, + bottle_arch:, + ignore_deps:, + only_deps:, + include_test_formulae:, + build_from_source_formulae:, + cc:, + git:, + interactive:, + keep_tmp:, + debug_symbols:, + force:, + overwrite:, + debug:, + quiet:, + verbose:, + skip_post_install:, ) begin @@ -355,7 +355,7 @@ def install_formula(formula_installer) upgrade = formula.linked? && formula.outdated? && !formula.head? && !Homebrew::EnvConfig.no_install_upgrade? - Upgrade.install_formula(formula_installer, upgrade: upgrade) + Upgrade.install_formula(formula_installer, upgrade:) end end end diff --git a/Library/Homebrew/keg.rb b/Library/Homebrew/keg.rb index 5b5d25e8fc1936..98256534659c8e 100644 --- a/Library/Homebrew/keg.rb +++ b/Library/Homebrew/keg.rb @@ -408,16 +408,16 @@ def link(verbose: false, dry_run: false, overwrite: false) ObserverPathnameExtension.reset_counts! - optlink(verbose: verbose, dry_run: dry_run, overwrite: overwrite) unless dry_run + optlink(verbose:, dry_run:, overwrite:) unless dry_run # yeah indeed, you have to force anything you need in the main tree into # these dirs REMEMBER that *NOT* everything needs to be in the main tree - link_dir("etc", verbose: verbose, dry_run: dry_run, overwrite: overwrite) { :mkpath } - link_dir("bin", verbose: verbose, dry_run: dry_run, overwrite: overwrite) { :skip_dir } - link_dir("sbin", verbose: verbose, dry_run: dry_run, overwrite: overwrite) { :skip_dir } - link_dir("include", verbose: verbose, dry_run: dry_run, overwrite: overwrite) { :link } + link_dir("etc", verbose:, dry_run:, overwrite:) { :mkpath } + link_dir("bin", verbose:, dry_run:, overwrite:) { :skip_dir } + link_dir("sbin", verbose:, dry_run:, overwrite:) { :skip_dir } + link_dir("include", verbose:, dry_run:, overwrite:) { :link } - link_dir("share", verbose: verbose, dry_run: dry_run, overwrite: overwrite) do |relative_path| + link_dir("share", verbose:, dry_run:, overwrite:) do |relative_path| case relative_path.to_s when INFOFILE_RX then :info when "locale/locale.alias", @@ -436,7 +436,7 @@ def link(verbose: false, dry_run: false, overwrite: false) end end - link_dir("lib", verbose: verbose, dry_run: dry_run, overwrite: overwrite) do |relative_path| + link_dir("lib", verbose:, dry_run:, overwrite:) do |relative_path| case relative_path.to_s when "charset.alias" :skip_file @@ -462,7 +462,7 @@ def link(verbose: false, dry_run: false, overwrite: false) end end - link_dir("Frameworks", verbose: verbose, dry_run: dry_run, overwrite: overwrite) do |relative_path| + link_dir("Frameworks", verbose:, dry_run:, overwrite:) do |relative_path| # Frameworks contain symlinks pointing into a subdir, so we have to use # the :link strategy. However, for Foo.framework and # Foo.framework/Versions we have to use :mkpath so that multiple formulae @@ -473,11 +473,9 @@ def link(verbose: false, dry_run: false, overwrite: false) :link end end - unless dry_run - make_relative_symlink(linked_keg_record, path, verbose: verbose, dry_run: dry_run, overwrite: overwrite) - end + make_relative_symlink(linked_keg_record, path, verbose:, dry_run:, overwrite:) unless dry_run rescue LinkError - unlink(verbose: verbose) + unlink(verbose:) raise else ObserverPathnameExtension.n @@ -512,16 +510,16 @@ def aliases def optlink(verbose: false, dry_run: false, overwrite: false) opt_record.delete if opt_record.symlink? || opt_record.exist? - make_relative_symlink(opt_record, path, verbose: verbose, dry_run: dry_run, overwrite: overwrite) + make_relative_symlink(opt_record, path, verbose:, dry_run:, overwrite:) aliases.each do |a| alias_opt_record = opt_record.parent/a alias_opt_record.delete if alias_opt_record.symlink? || alias_opt_record.exist? - make_relative_symlink(alias_opt_record, path, verbose: verbose, dry_run: dry_run, overwrite: overwrite) + make_relative_symlink(alias_opt_record, path, verbose:, dry_run:, overwrite:) end oldname_opt_records.each do |record| record.delete - make_relative_symlink(record, path, verbose: verbose, dry_run: dry_run, overwrite: overwrite) + make_relative_symlink(record, path, verbose:, dry_run:, overwrite:) end end @@ -641,10 +639,10 @@ def link_dir(relative_dir, verbose: false, dry_run: false, overwrite: false) when :info next if File.basename(src) == "dir" # skip historical local 'dir' files - make_relative_symlink dst, src, verbose: verbose, dry_run: dry_run, overwrite: overwrite + make_relative_symlink(dst, src, verbose:, dry_run:, overwrite:) dst.install_info else - make_relative_symlink dst, src, verbose: verbose, dry_run: dry_run, overwrite: overwrite + make_relative_symlink dst, src, verbose:, dry_run:, overwrite: end elsif src.directory? # if the dst dir already exists, then great! walk the rest of the tree tho @@ -658,10 +656,10 @@ def link_dir(relative_dir, verbose: false, dry_run: false, overwrite: false) when :skip_dir Find.prune when :mkpath - dst.mkpath unless resolve_any_conflicts(dst, verbose: verbose, dry_run: dry_run, overwrite: overwrite) + dst.mkpath unless resolve_any_conflicts(dst, verbose:, dry_run:, overwrite:) else - unless resolve_any_conflicts(dst, verbose: verbose, dry_run: dry_run, overwrite: overwrite) - make_relative_symlink dst, src, verbose: verbose, dry_run: dry_run, overwrite: overwrite + unless resolve_any_conflicts(dst, verbose:, dry_run:, overwrite:) + make_relative_symlink(dst, src, verbose:, dry_run:, overwrite:) Find.prune end end diff --git a/Library/Homebrew/keg_relocate.rb b/Library/Homebrew/keg_relocate.rb index 69809a5859f615..2a79b84f54be8c 100644 --- a/Library/Homebrew/keg_relocate.rb +++ b/Library/Homebrew/keg_relocate.rb @@ -128,7 +128,7 @@ def prepare_relocation_to_locations def replace_placeholders_with_locations(files, skip_linkage: false) relocation = prepare_relocation_to_locations.freeze relocate_dynamic_linkage(relocation) unless skip_linkage - replace_text_in_files(relocation, files: files) + replace_text_in_files(relocation, files:) end def openjdk_dep_name_if_applicable @@ -143,7 +143,7 @@ def replace_text_in_files(relocation, files: nil) files ||= text_files | libtool_files changed_files = T.let([], Array) - files.map(&path.method(:join)).group_by { |f| f.stat.ino }.each_value do |first, *rest| + files.map { path.join(_1) }.group_by { |f| f.stat.ino }.each_value do |first, *rest| s = first.open("rb", &:read) next unless relocation.replace_text(s) diff --git a/Library/Homebrew/language/python.rb b/Library/Homebrew/language/python.rb index 5887cc6ab20804..d9bb9bb0199b5e 100644 --- a/Library/Homebrew/language/python.rb +++ b/Library/Homebrew/language/python.rb @@ -6,6 +6,7 @@ module Language # # @api public module Python + sig { params(python: T.any(String, Pathname)).returns(T.nilable(Version)) } def self.major_minor_version(python) version = `#{python} --version 2>&1`.chomp[/(\d\.\d+)/, 1] return unless version @@ -13,10 +14,12 @@ def self.major_minor_version(python) Version.new(version) end + sig { params(python: T.any(String, Pathname)).returns(Pathname) } def self.homebrew_site_packages(python = "python3.7") HOMEBREW_PREFIX/site_packages(python) end + sig { params(python: T.any(String, Pathname)).returns(String) } def self.site_packages(python = "python3.7") if (python == "pypy") || (python == "pypy3") "site-packages" @@ -38,7 +41,7 @@ def self.each_python(build, &block) ENV["PYTHONPATH"] = if python_formula.latest_version_installed? nil else - homebrew_site_packages(python) + homebrew_site_packages(python).to_s end block&.call python, version end @@ -70,6 +73,7 @@ def self.in_sys_path?(python, path) quiet_system python, "-c", script end + sig { params(prefix: Pathname, python: T.any(String, Pathname)).returns(T::Array[String]) } def self.setup_install_args(prefix, python = "python3") shim = <<~PYTHON import setuptools, tokenize @@ -110,8 +114,8 @@ def python_shebang_rewrite_info(python_path) ) end - sig { params(formula: T.untyped, use_python_from_path: T::Boolean).returns(Utils::Shebang::RewriteInfo) } - def detected_python_shebang(formula = self, use_python_from_path: false) + sig { params(formula: Formula, use_python_from_path: T::Boolean).returns(Utils::Shebang::RewriteInfo) } + def detected_python_shebang(formula = T.cast(self, Formula), use_python_from_path: false) python_path = if use_python_from_path "/usr/bin/env python3" else @@ -137,12 +141,21 @@ module Virtualenv # # @param venv_root [Pathname, String] the path to the root of the virtualenv # (often `libexec/"venv"`) - # @param python [String] which interpreter to use (e.g. "python3" + # @param python [String, Pathname] which interpreter to use (e.g. "python3" # or "python3.x") # @param formula [Formula] the active {Formula} # @return [Virtualenv] a {Virtualenv} instance - def virtualenv_create(venv_root, python = "python", formula = self, system_site_packages: true, - without_pip: true) + sig { + params( + venv_root: T.any(String, Pathname), + python: T.any(String, Pathname), + formula: Formula, + system_site_packages: T::Boolean, + without_pip: T::Boolean, + ).returns(Virtualenv) + } + def virtualenv_create(venv_root, python = "python", formula = T.cast(self, Formula), + system_site_packages: true, without_pip: true) # Limit deprecation to 3.12+ for now (or if we can't determine the version). # Some used this argument for setuptools, which we no longer bundle since 3.12. unless without_pip @@ -154,7 +167,7 @@ def virtualenv_create(venv_root, python = "python", formula = self, system_site_ ENV.refurbish_args venv = Virtualenv.new formula, venv_root, python - venv.create(system_site_packages: system_site_packages, without_pip: without_pip) + venv.create(system_site_packages:, without_pip:) # Find any Python bindings provided by recursive dependencies formula_deps = formula.recursive_dependencies @@ -169,9 +182,7 @@ def virtualenv_create(venv_root, python = "python", formula = self, system_site_ "import site; site.addsitedir('#{dep_site_packages}')\n" end - unless pth_contents.empty? - (venv_root/Language::Python.site_packages(python)/"homebrew_deps.pth").write pth_contents.join - end + (venv.site_packages/"homebrew_deps.pth").write pth_contents.join unless pth_contents.empty? venv end @@ -184,6 +195,7 @@ def virtualenv_create(venv_root, python = "python", formula = self, system_site_ # corresponding depends_on statement. # # @api private + sig { params(python: String).returns(T::Boolean) } def needs_python?(python) return true if build.with?(python) @@ -197,6 +209,14 @@ def needs_python?(python) # formula preference for python or python@x.y, or to resolve an ambiguous # case where it's not clear whether python or python@x.y should be the # default guess. + sig { + params( + using: T.nilable(String), + system_site_packages: T::Boolean, + without_pip: T::Boolean, + link_manpages: T::Boolean, + ).returns(Virtualenv) + } def virtualenv_install_with_resources(using: nil, system_site_packages: true, without_pip: true, link_manpages: false) python = using @@ -205,13 +225,13 @@ def virtualenv_install_with_resources(using: nil, system_site_packages: true, wi raise FormulaUnknownPythonError, self if wanted.empty? raise FormulaAmbiguousPythonError, self if wanted.size > 1 - python = wanted.first + python = T.must(wanted.first) python = "python3" if python == "python" end - venv = virtualenv_create(libexec, python.delete("@"), system_site_packages: system_site_packages, - without_pip: without_pip) + venv = virtualenv_create(libexec, python.delete("@"), system_site_packages:, + without_pip:) venv.pip_install resources - venv.pip_install_and_link(buildpath, link_manpages: link_manpages) + venv.pip_install_and_link(T.must(buildpath), link_manpages:) venv end @@ -229,17 +249,29 @@ class Virtualenv # @param formula [Formula] the active {Formula} # @param venv_root [Pathname, String] the path to the root of the # virtualenv - # @param python [String] which interpreter to use, e.g. "python" or - # "python2" + # @param python [String, Pathname] which interpreter to use, e.g. + # "python" or "python2" + sig { params(formula: Formula, venv_root: T.any(String, Pathname), python: T.any(String, Pathname)).void } def initialize(formula, venv_root, python) @formula = formula @venv_root = Pathname.new(venv_root) @python = python end + sig { returns(Pathname) } + def root + @venv_root + end + + sig { returns(Pathname) } + def site_packages + @venv_root/Language::Python.site_packages(@python) + end + # Obtains a copy of the virtualenv library and creates a new virtualenv on disk. # # @return [void] + sig { params(system_site_packages: T::Boolean, without_pip: T::Boolean).void } def create(system_site_packages: true, without_pip: true) return if (@venv_root/"bin/python").exist? @@ -285,14 +317,20 @@ def create(system_site_packages: true, without_pip: true) # Multiline strings are allowed and treated as though they represent # the contents of a `requirements.txt`. # @return [void] + sig { + params( + targets: T.any(String, Pathname, Resource, T::Array[T.any(String, Pathname, Resource)]), + build_isolation: T::Boolean, + ).void + } def pip_install(targets, build_isolation: true) targets = Array(targets) targets.each do |t| - if t.respond_to? :stage - t.stage { do_install(Pathname.pwd, build_isolation: build_isolation) } + if t.is_a?(Resource) + t.stage { do_install(Pathname.pwd, build_isolation:) } else - t = t.lines.map(&:strip) if t.respond_to?(:lines) && t.include?("\n") - do_install(t, build_isolation: build_isolation) + t = t.lines.map(&:strip) if t.is_a?(String) && t.include?("\n") + do_install(t, build_isolation:) end end end @@ -302,11 +340,18 @@ def pip_install(targets, build_isolation: true) # # @param (see #pip_install) # @return (see #pip_install) + sig { + params( + targets: T.any(String, Pathname, Resource, T::Array[T.any(String, Pathname, Resource)]), + link_manpages: T::Boolean, + build_isolation: T::Boolean, + ).void + } def pip_install_and_link(targets, link_manpages: false, build_isolation: true) bin_before = Dir[@venv_root/"bin/*"].to_set man_before = Dir[@venv_root/"share/man/man*/*"].to_set if link_manpages - pip_install(targets, build_isolation: build_isolation) + pip_install(targets, build_isolation:) bin_after = Dir[@venv_root/"bin/*"].to_set bin_to_link = (bin_after - bin_before).to_a @@ -322,9 +367,15 @@ def pip_install_and_link(targets, link_manpages: false, build_isolation: true) private + sig { + params( + targets: T.any(String, Pathname, T::Array[T.any(String, Pathname)]), + build_isolation: T::Boolean, + ).void + } def do_install(targets, build_isolation: true) targets = Array(targets) - args = @formula.std_pip_args(prefix: false, build_isolation: build_isolation) + args = @formula.std_pip_args(prefix: false, build_isolation:) @formula.system @python, "-m", "pip", "--python=#{@venv_root}/bin/python", "install", *args, *targets end end diff --git a/Library/Homebrew/linkage_checker.rb b/Library/Homebrew/linkage_checker.rb index e7c6e2c3b1961c..6a0bfa39622da2 100644 --- a/Library/Homebrew/linkage_checker.rb +++ b/Library/Homebrew/linkage_checker.rb @@ -31,7 +31,7 @@ def initialize(keg, formula = nil, cache_db:, rebuild_cache: false) @files_missing_rpaths = [] @executable_path_dylibs = [] - check_dylibs(rebuild_cache: rebuild_cache) + check_dylibs(rebuild_cache:) end def display_normal_output @@ -63,15 +63,15 @@ def display_reverse_output end def display_test_output(puts_output: true, strict: false) - display_items "Missing libraries", @broken_dylibs, puts_output: puts_output - display_items "Broken dependencies", @broken_deps, puts_output: puts_output - display_items "Unwanted system libraries", @unwanted_system_dylibs, puts_output: puts_output - display_items "Conflicting libraries", @version_conflict_deps, puts_output: puts_output + display_items("Missing libraries", @broken_dylibs, puts_output:) + display_items("Broken dependencies", @broken_deps, puts_output:) + display_items("Unwanted system libraries", @unwanted_system_dylibs, puts_output:) + display_items("Conflicting libraries", @version_conflict_deps, puts_output:) return unless strict - display_items "Undeclared dependencies with linkage", @undeclared_deps, puts_output: puts_output - display_items "Files with missing rpath", @files_missing_rpaths, puts_output: puts_output - display_items "@executable_path references in libraries", @executable_path_dylibs, puts_output: puts_output + display_items("Undeclared dependencies with linkage", @undeclared_deps, puts_output:) + display_items("Files with missing rpath", @files_missing_rpaths, puts_output:) + display_items "@executable_path references in libraries", @executable_path_dylibs, puts_output: end sig { params(test: T::Boolean, strict: T::Boolean).returns(T::Boolean) } @@ -179,7 +179,7 @@ def check_dylibs(rebuild_cache:) return unless keg_files_dylibs_was_empty - store&.update!(keg_files_dylibs: keg_files_dylibs) + store&.update!(keg_files_dylibs:) end alias generic_check_dylibs check_dylibs diff --git a/Library/Homebrew/linux_runner_spec.rb b/Library/Homebrew/linux_runner_spec.rb index 816f82d4e972ed..43244819c03fa3 100644 --- a/Library/Homebrew/linux_runner_spec.rb +++ b/Library/Homebrew/linux_runner_spec.rb @@ -21,12 +21,12 @@ class LinuxRunnerSpec < T::Struct } def to_h { - name: name, - runner: runner, - container: container, - workdir: workdir, - timeout: timeout, - cleanup: cleanup, + name:, + runner:, + container:, + workdir:, + timeout:, + cleanup:, } end end diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index ef864b7dd2ba06..6ab47d4992ba74 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -128,11 +128,11 @@ def resolve_livecheck_reference( if debug # Print the chain of references for debugging puts "Reference Chain:" - puts package_or_resource_name(first_formula_or_cask, full_name: full_name) + puts package_or_resource_name(first_formula_or_cask, full_name:) references << referenced_formula_or_cask references.each do |ref_formula_or_cask| - puts package_or_resource_name(ref_formula_or_cask, full_name: full_name) + puts package_or_resource_name(ref_formula_or_cask, full_name:) end end @@ -145,8 +145,8 @@ def resolve_livecheck_reference( referenced_formula_or_cask, first_formula_or_cask, references, - full_name: full_name, - debug: debug, + full_name:, + debug:, ) # Returning references along with the final referenced formula/cask @@ -225,7 +225,7 @@ def run_checks( name = package_or_resource_name(formula_or_cask, full_name: use_full_name) referenced_formula_or_cask, livecheck_references = - resolve_livecheck_reference(formula_or_cask, full_name: use_full_name, debug: debug) + resolve_livecheck_reference(formula_or_cask, full_name: use_full_name, debug:) if debug && i.positive? puts <<~EOS @@ -243,11 +243,11 @@ def run_checks( referenced_formula_or_cask, name, full_name: use_full_name, - verbose: verbose, + verbose:, ) end - skip_info ||= SkipConditions.skip_information(formula_or_cask, full_name: use_full_name, verbose: verbose) + skip_info ||= SkipConditions.skip_information(formula_or_cask, full_name: use_full_name, verbose:) if skip_info.present? next skip_info if json && !newer_only @@ -279,9 +279,9 @@ def run_checks( else version_info = latest_version( formula_or_cask, - referenced_formula_or_cask: referenced_formula_or_cask, - livecheck_references: livecheck_references, - json: json, full_name: use_full_name, verbose: verbose, debug: debug + referenced_formula_or_cask:, + livecheck_references:, + json:, full_name: use_full_name, verbose:, debug: ) version_info[:latest] if version_info.present? end @@ -289,20 +289,20 @@ def run_checks( check_for_resources = check_resources && formula_or_cask.is_a?(Formula) && formula_or_cask.resources.present? if check_for_resources resource_version_info = formula_or_cask.resources.map do |resource| - res_skip_info ||= SkipConditions.skip_information(resource, verbose: verbose) + res_skip_info ||= SkipConditions.skip_information(resource, verbose:) if res_skip_info.present? res_skip_info else res_version_info = resource_version( resource, latest.to_s, - json: json, - debug: debug, - quiet: quiet, - verbose: verbose, + json:, + debug:, + quiet:, + verbose:, ) if res_version_info.empty? - status_hash(resource, "error", ["Unable to get versions"], verbose: verbose) + status_hash(resource, "error", ["Unable to get versions"], verbose:) else res_version_info end @@ -319,7 +319,7 @@ def run_checks( next version_info if version_info.is_a?(Hash) && version_info[:status] && version_info[:messages] latest_info = status_hash(formula_or_cask, "error", [no_versions_msg], full_name: use_full_name, - verbose: verbose) + verbose:) if check_for_resources unless verbose resource_version_info.map! do |info| @@ -383,8 +383,8 @@ def run_checks( next info end puts if debug - print_latest_version(info, verbose: verbose, ambiguous_cask: ambiguous_casks.include?(formula_or_cask)) - print_resources_info(resource_version_info, verbose: verbose) if check_for_resources + print_latest_version(info, verbose:, ambiguous_cask: ambiguous_casks.include?(formula_or_cask)) + print_resources_info(resource_version_info, verbose:) if check_for_resources nil rescue => e Homebrew.failed = true @@ -394,7 +394,7 @@ def run_checks( progress&.increment unless quiet status_hash(formula_or_cask, "error", [e.to_s], full_name: use_full_name, - verbose: verbose) + verbose:) end elsif !quiet name = package_or_resource_name(formula_or_cask, full_name: use_full_name) @@ -402,7 +402,7 @@ def run_checks( onoe "#{Tty.blue}#{name}#{Tty.reset}: #{e}" $stderr.puts Utils::Backtrace.clean(e) if debug && !e.is_a?(Livecheck::Error) - print_resources_info(resource_version_info, verbose: verbose) if check_for_resources + print_resources_info(resource_version_info, verbose:) if check_for_resources nil end end @@ -425,9 +425,9 @@ def run_checks( def package_or_resource_name(package_or_resource, full_name: false) case package_or_resource when Formula - formula_name(package_or_resource, full_name: full_name) + formula_name(package_or_resource, full_name:) when Cask::Cask - cask_name(package_or_resource, full_name: full_name) + cask_name(package_or_resource, full_name:) when Resource package_or_resource.name else @@ -465,9 +465,9 @@ def status_hash(package_or_resource, status_str, messages = nil, full_name: fals status_hash = {} if formula - status_hash[:formula] = formula_name(formula, full_name: full_name) + status_hash[:formula] = formula_name(formula, full_name:) elsif cask - status_hash[:cask] = cask_name(cask, full_name: full_name) + status_hash[:cask] = cask_name(cask, full_name:) elsif resource status_hash[:resource] = resource.name end @@ -512,7 +512,7 @@ def print_resources_info(info, verbose: false) if r_info[:status] && r_info[:messages] SkipConditions.print_skip_information(r_info) else - print_latest_version(r_info, verbose: verbose) + print_latest_version(r_info, verbose:) end end end @@ -673,19 +673,19 @@ def latest_version( if debug if formula - puts "Formula: #{formula_name(formula, full_name: full_name)}" + puts "Formula: #{formula_name(formula, full_name:)}" puts "Head only?: true" if formula.head_only? elsif cask - puts "Cask: #{cask_name(formula_or_cask, full_name: full_name)}" + puts "Cask: #{cask_name(formula_or_cask, full_name:)}" end puts "Livecheckable?: #{has_livecheckable ? "Yes" : "No"}" livecheck_references.each do |ref_formula_or_cask| case ref_formula_or_cask when Formula - puts "Formula Ref: #{formula_name(ref_formula_or_cask, full_name: full_name)}" + puts "Formula Ref: #{formula_name(ref_formula_or_cask, full_name:)}" when Cask::Cask - puts "Cask Ref: #{cask_name(ref_formula_or_cask, full_name: full_name)}" + puts "Cask Ref: #{cask_name(ref_formula_or_cask, full_name:)}" end end end @@ -702,7 +702,7 @@ def latest_version( strategies = Strategy.from_url( url, - livecheck_strategy: livecheck_strategy, + livecheck_strategy:, url_provided: livecheck_url.present?, regex_provided: livecheck_regex.present?, block_provided: livecheck_strategy_block.present?, @@ -746,7 +746,7 @@ def latest_version( strategy_args = { regex: livecheck_regex, - homebrew_curl: homebrew_curl, + homebrew_curl:, } # TODO: Set `cask`/`url` args based on the presence of the keyword arg # in the strategy's `#find_versions` method once we figure out why @@ -769,7 +769,7 @@ def latest_version( puts messages unless json next if i + 1 < urls.length - return status_hash(formula_or_cask, "error", messages, full_name: full_name, verbose: verbose) + return status_hash(formula_or_cask, "error", messages, full_name:, verbose:) end if debug @@ -817,9 +817,9 @@ def latest_version( version_info[:meta][:references] = livecheck_references.map do |ref_formula_or_cask| case ref_formula_or_cask when Formula - { formula: formula_name(ref_formula_or_cask, full_name: full_name) } + { formula: formula_name(ref_formula_or_cask, full_name:) } when Cask::Cask - { cask: cask_name(ref_formula_or_cask, full_name: full_name) } + { cask: cask_name(ref_formula_or_cask, full_name:) } end end end @@ -897,7 +897,7 @@ def resource_version( strategies = Strategy.from_url( url, - livecheck_strategy: livecheck_strategy, + livecheck_strategy:, url_provided: livecheck_url.present?, regex_provided: livecheck_regex.present?, block_provided: livecheck_strategy_block.present?, @@ -934,7 +934,7 @@ def resource_version( next if strategy.blank? strategy_args = { - url: url, + url:, regex: livecheck_regex, homebrew_curl: false, }.compact @@ -949,7 +949,7 @@ def resource_version( puts messages unless json next if i + 1 < urls.length - return status_hash(resource, "error", messages, verbose: verbose) + return status_hash(resource, "error", messages, verbose:) end if debug @@ -989,7 +989,7 @@ def resource_version( res_current = T.must(resource.version) res_latest = Version.new(match_version_map.values.max_by { |v| LivecheckVersion.create(resource, v) }) - return status_hash(resource, "error", ["Unable to get versions"], verbose: verbose) if res_latest.blank? + return status_hash(resource, "error", ["Unable to get versions"], verbose:) if res_latest.blank? is_outdated = res_current < res_latest is_newer_than_upstream = res_current > res_latest @@ -1023,7 +1023,7 @@ def resource_version( rescue => e Homebrew.failed = true if json - status_hash(resource, "error", [e.to_s], verbose: verbose) + status_hash(resource, "error", [e.to_s], verbose:) elsif !quiet onoe "#{Tty.blue}#{resource.name}#{Tty.reset}: #{e}" $stderr.puts Utils::Backtrace.clean(e) if debug && !e.is_a?(Livecheck::Error) diff --git a/Library/Homebrew/livecheck/skip_conditions.rb b/Library/Homebrew/livecheck/skip_conditions.rb index a90d5e5d4f8cd0..2ee449ed88b69b 100644 --- a/Library/Homebrew/livecheck/skip_conditions.rb +++ b/Library/Homebrew/livecheck/skip_conditions.rb @@ -44,7 +44,7 @@ def package_or_resource_skip(package_or_resource, livecheckable, full_name: fals return {} if !package_or_resource.livecheck.skip? && skip_message.blank? skip_messages = skip_message ? [skip_message] : nil - Livecheck.status_hash(package_or_resource, "skipped", skip_messages, full_name: full_name, verbose: verbose) + Livecheck.status_hash(package_or_resource, "skipped", skip_messages, full_name:, verbose:) end sig { @@ -62,8 +62,8 @@ def formula_head_only(formula, _livecheckable, full_name: false, verbose: false) formula, "error", ["HEAD only formula must be installed to be livecheckable"], - full_name: full_name, - verbose: verbose, + full_name:, + verbose:, ) end @@ -78,7 +78,7 @@ def formula_head_only(formula, _livecheckable, full_name: false, verbose: false) def formula_deprecated(formula, livecheckable, full_name: false, verbose: false) return {} if !formula.deprecated? || livecheckable - Livecheck.status_hash(formula, "deprecated", full_name: full_name, verbose: verbose) + Livecheck.status_hash(formula, "deprecated", full_name:, verbose:) end sig { @@ -92,7 +92,7 @@ def formula_deprecated(formula, livecheckable, full_name: false, verbose: false) def formula_disabled(formula, livecheckable, full_name: false, verbose: false) return {} if !formula.disabled? || livecheckable - Livecheck.status_hash(formula, "disabled", full_name: full_name, verbose: verbose) + Livecheck.status_hash(formula, "disabled", full_name:, verbose:) end sig { @@ -106,7 +106,7 @@ def formula_disabled(formula, livecheckable, full_name: false, verbose: false) def formula_versioned(formula, livecheckable, full_name: false, verbose: false) return {} if !formula.versioned_formula? || livecheckable - Livecheck.status_hash(formula, "versioned", full_name: full_name, verbose: verbose) + Livecheck.status_hash(formula, "versioned", full_name:, verbose:) end sig { @@ -120,7 +120,7 @@ def formula_versioned(formula, livecheckable, full_name: false, verbose: false) def cask_discontinued(cask, livecheckable, full_name: false, verbose: false) return {} if !cask.discontinued? || livecheckable - Livecheck.status_hash(cask, "discontinued", full_name: full_name, verbose: verbose) + Livecheck.status_hash(cask, "discontinued", full_name:, verbose:) end sig { @@ -134,7 +134,7 @@ def cask_discontinued(cask, livecheckable, full_name: false, verbose: false) def cask_deprecated(cask, livecheckable, full_name: false, verbose: false) return {} if !cask.deprecated? || livecheckable - Livecheck.status_hash(cask, "deprecated", full_name: full_name, verbose: verbose) + Livecheck.status_hash(cask, "deprecated", full_name:, verbose:) end sig { @@ -148,7 +148,7 @@ def cask_deprecated(cask, livecheckable, full_name: false, verbose: false) def cask_disabled(cask, livecheckable, full_name: false, verbose: false) return {} if !cask.disabled? || livecheckable - Livecheck.status_hash(cask, "disabled", full_name: full_name, verbose: verbose) + Livecheck.status_hash(cask, "disabled", full_name:, verbose:) end sig { @@ -162,7 +162,7 @@ def cask_disabled(cask, livecheckable, full_name: false, verbose: false) def cask_version_latest(cask, livecheckable, full_name: false, verbose: false) return {} if !(cask.present? && cask.version&.latest?) || livecheckable - Livecheck.status_hash(cask, "latest", full_name: full_name, verbose: verbose) + Livecheck.status_hash(cask, "latest", full_name:, verbose:) end sig { @@ -176,7 +176,7 @@ def cask_version_latest(cask, livecheckable, full_name: false, verbose: false) def cask_url_unversioned(cask, livecheckable, full_name: false, verbose: false) return {} if !(cask.present? && cask.url&.unversioned?) || livecheckable - Livecheck.status_hash(cask, "unversioned", full_name: full_name, verbose: verbose) + Livecheck.status_hash(cask, "unversioned", full_name:, verbose:) end # Skip conditions for formulae. @@ -227,7 +227,7 @@ def skip_information(package_or_resource, full_name: false, verbose: false) return {} unless checks checks.each do |method_name| - skip_hash = send(method_name, package_or_resource, livecheckable, full_name: full_name, verbose: verbose) + skip_hash = send(method_name, package_or_resource, livecheckable, full_name:, verbose:) return skip_hash if skip_hash.present? end @@ -254,12 +254,12 @@ def referenced_skip_information( ) skip_info = SkipConditions.skip_information( livecheck_package_or_resource, - full_name: full_name, - verbose: verbose, + full_name:, + verbose:, ) return if skip_info.blank? - referenced_name = Livecheck.package_or_resource_name(livecheck_package_or_resource, full_name: full_name) + referenced_name = Livecheck.package_or_resource_name(livecheck_package_or_resource, full_name:) referenced_type = case livecheck_package_or_resource when Formula :formula diff --git a/Library/Homebrew/livecheck/strategy.rb b/Library/Homebrew/livecheck/strategy.rb index ea4a475901bb75..68f0d34bd1e738 100644 --- a/Library/Homebrew/livecheck/strategy.rb +++ b/Library/Homebrew/livecheck/strategy.rb @@ -192,7 +192,7 @@ def self.page_headers(url, homebrew_curl: false) url, wanted_headers: ["location", "content-disposition"], use_homebrew_curl: homebrew_curl, - user_agent: user_agent, + user_agent:, **DEFAULT_CURL_OPTIONS, ) rescue ErrorDuringExecution @@ -222,7 +222,7 @@ def self.page_content(url, homebrew_curl: false) *PAGE_CONTENT_CURL_ARGS, url, **DEFAULT_CURL_OPTIONS, use_homebrew_curl: homebrew_curl, - user_agent: user_agent + user_agent: ) next unless status.success? diff --git a/Library/Homebrew/livecheck/strategy/crate.rb b/Library/Homebrew/livecheck/strategy/crate.rb index f4e91e447d482e..f10f24271eaa61 100644 --- a/Library/Homebrew/livecheck/strategy/crate.rb +++ b/Library/Homebrew/livecheck/strategy/crate.rb @@ -83,7 +83,7 @@ def self.generate_input_values(url) ).returns(T::Hash[Symbol, T.untyped]) } def self.find_versions(url:, regex: nil, provided_content: nil, homebrew_curl: false, **_unused, &block) - match_data = { matches: {}, regex: regex, url: url } + match_data = { matches: {}, regex:, url: } match_data[:cached] = true if provided_content.is_a?(String) generated = generate_input_values(url) @@ -94,7 +94,7 @@ def self.find_versions(url:, regex: nil, provided_content: nil, homebrew_curl: f content = if provided_content provided_content else - match_data.merge!(Strategy.page_content(match_data[:url], homebrew_curl: homebrew_curl)) + match_data.merge!(Strategy.page_content(match_data[:url], homebrew_curl:)) match_data[:content] end return match_data unless content diff --git a/Library/Homebrew/livecheck/strategy/electron_builder.rb b/Library/Homebrew/livecheck/strategy/electron_builder.rb index 4b97ab479e2f33..7ec7dcb03f27e1 100644 --- a/Library/Homebrew/livecheck/strategy/electron_builder.rb +++ b/Library/Homebrew/livecheck/strategy/electron_builder.rb @@ -53,9 +53,9 @@ def self.find_versions(url:, regex: nil, provided_content: nil, **unused, &block end Yaml.find_versions( - url: url, - regex: regex, - provided_content: provided_content, + url:, + regex:, + provided_content:, **unused, &block || proc { |yaml| yaml["version"] } ) diff --git a/Library/Homebrew/livecheck/strategy/extract_plist.rb b/Library/Homebrew/livecheck/strategy/extract_plist.rb index a234fd295474a2..8f2e50e882678a 100644 --- a/Library/Homebrew/livecheck/strategy/extract_plist.rb +++ b/Library/Homebrew/livecheck/strategy/extract_plist.rb @@ -100,7 +100,7 @@ def self.find_versions(cask:, url: nil, regex: nil, **_unused, &block) raise ArgumentError, "The #{Utils.demodulize(T.must(name))} strategy only supports casks." end - match_data = { matches: {}, regex: regex, url: url } + match_data = { matches: {}, regex:, url: } unversioned_cask_checker = if url.present? && url != cask.url.to_s # Create a copy of the `cask` that uses the `livecheck` block URL diff --git a/Library/Homebrew/livecheck/strategy/git.rb b/Library/Homebrew/livecheck/strategy/git.rb index aaf061ba5473a2..7b5eeee405cb0d 100644 --- a/Library/Homebrew/livecheck/strategy/git.rb +++ b/Library/Homebrew/livecheck/strategy/git.rb @@ -130,7 +130,7 @@ def self.versions_from_tags(tags, regex = nil, &block) ).returns(T::Hash[Symbol, T.untyped]) } def self.find_versions(url:, regex: nil, **_unused, &block) - match_data = { matches: {}, regex: regex, url: url } + match_data = { matches: {}, regex:, url: } tags_data = tag_info(url, regex) tags = tags_data[:tags] diff --git a/Library/Homebrew/livecheck/strategy/github_latest.rb b/Library/Homebrew/livecheck/strategy/github_latest.rb index 178d91362e1200..74a9c35a405a68 100644 --- a/Library/Homebrew/livecheck/strategy/github_latest.rb +++ b/Library/Homebrew/livecheck/strategy/github_latest.rb @@ -80,7 +80,7 @@ def self.generate_input_values(url) ).returns(T::Hash[Symbol, T.untyped]) } def self.find_versions(url:, regex: GithubReleases::DEFAULT_REGEX, **_unused, &block) - match_data = { matches: {}, regex: regex, url: url } + match_data = { matches: {}, regex:, url: } generated = generate_input_values(url) return match_data if generated.blank? diff --git a/Library/Homebrew/livecheck/strategy/github_releases.rb b/Library/Homebrew/livecheck/strategy/github_releases.rb index c692bf5d0159c7..e2a8d35d8b5707 100644 --- a/Library/Homebrew/livecheck/strategy/github_releases.rb +++ b/Library/Homebrew/livecheck/strategy/github_releases.rb @@ -134,7 +134,7 @@ def self.versions_from_content(content, regex, &block) ).returns(T::Hash[Symbol, T.untyped]) } def self.find_versions(url:, regex: DEFAULT_REGEX, **_unused, &block) - match_data = { matches: {}, regex: regex, url: url } + match_data = { matches: {}, regex:, url: } generated = generate_input_values(url) return match_data if generated.blank? diff --git a/Library/Homebrew/livecheck/strategy/header_match.rb b/Library/Homebrew/livecheck/strategy/header_match.rb index 7c3991e08e07c3..ae2a7c76ce8103 100644 --- a/Library/Homebrew/livecheck/strategy/header_match.rb +++ b/Library/Homebrew/livecheck/strategy/header_match.rb @@ -81,9 +81,9 @@ def self.versions_from_headers(headers, regex = nil, &block) ).returns(T::Hash[Symbol, T.untyped]) } def self.find_versions(url:, regex: nil, homebrew_curl: false, **_unused, &block) - match_data = { matches: {}, regex: regex, url: url } + match_data = { matches: {}, regex:, url: } - headers = Strategy.page_headers(url, homebrew_curl: homebrew_curl) + headers = Strategy.page_headers(url, homebrew_curl:) # Merge the headers from all responses into one hash merged_headers = headers.reduce(&:merge) diff --git a/Library/Homebrew/livecheck/strategy/json.rb b/Library/Homebrew/livecheck/strategy/json.rb index 3a1b34da266a48..b27e990bdf4828 100644 --- a/Library/Homebrew/livecheck/strategy/json.rb +++ b/Library/Homebrew/livecheck/strategy/json.rb @@ -109,14 +109,14 @@ def self.versions_from_content(content, regex = nil, &block) def self.find_versions(url:, regex: nil, provided_content: nil, homebrew_curl: false, **_unused, &block) raise ArgumentError, "#{Utils.demodulize(T.must(name))} requires a `strategy` block" if block.blank? - match_data = { matches: {}, regex: regex, url: url } + match_data = { matches: {}, regex:, url: } return match_data if url.blank? || block.blank? content = if provided_content.is_a?(String) match_data[:cached] = true provided_content else - match_data.merge!(Strategy.page_content(url, homebrew_curl: homebrew_curl)) + match_data.merge!(Strategy.page_content(url, homebrew_curl:)) match_data[:content] end return match_data if content.blank? diff --git a/Library/Homebrew/livecheck/strategy/launchpad.rb b/Library/Homebrew/livecheck/strategy/launchpad.rb index 236058148475c2..b559f29a49b0a5 100644 --- a/Library/Homebrew/livecheck/strategy/launchpad.rb +++ b/Library/Homebrew/livecheck/strategy/launchpad.rb @@ -79,7 +79,7 @@ def self.generate_input_values(url) def self.find_versions(url:, regex: DEFAULT_REGEX, **unused, &block) generated = generate_input_values(url) - PageMatch.find_versions(url: generated[:url], regex: regex, **unused, &block) + PageMatch.find_versions(url: generated[:url], regex:, **unused, &block) end end end diff --git a/Library/Homebrew/livecheck/strategy/page_match.rb b/Library/Homebrew/livecheck/strategy/page_match.rb index 7f936941055368..5a44428861fcfa 100644 --- a/Library/Homebrew/livecheck/strategy/page_match.rb +++ b/Library/Homebrew/livecheck/strategy/page_match.rb @@ -94,14 +94,14 @@ def self.find_versions(url:, regex: nil, provided_content: nil, homebrew_curl: f raise ArgumentError, "#{Utils.demodulize(T.must(name))} requires a regex or `strategy` block" end - match_data = { matches: {}, regex: regex, url: url } + match_data = { matches: {}, regex:, url: } return match_data if url.blank? || (regex.blank? && block.blank?) content = if provided_content.is_a?(String) match_data[:cached] = true provided_content else - match_data.merge!(Strategy.page_content(url, homebrew_curl: homebrew_curl)) + match_data.merge!(Strategy.page_content(url, homebrew_curl:)) match_data[:content] end return match_data if content.blank? diff --git a/Library/Homebrew/livecheck/strategy/sparkle.rb b/Library/Homebrew/livecheck/strategy/sparkle.rb index 669f75047f5dac..5b9f9e1df8dcf4 100644 --- a/Library/Homebrew/livecheck/strategy/sparkle.rb +++ b/Library/Homebrew/livecheck/strategy/sparkle.rb @@ -128,15 +128,15 @@ def self.items_from_content(content) bundle_version = BundleVersion.new(short_version, version) if short_version || version data = { - title: title, - link: link, - channel: channel, - release_notes_link: release_notes_link, - pub_date: pub_date, - os: os, - url: url, - bundle_version: bundle_version, - minimum_system_version: minimum_system_version, + title:, + link:, + channel:, + release_notes_link:, + pub_date:, + os:, + url:, + bundle_version:, + minimum_system_version:, }.compact next if data.empty? @@ -229,7 +229,7 @@ def self.find_versions(url:, regex: nil, **_unused, &block) "#{Utils.demodulize(T.must(name))} only supports a regex when using a `strategy` block" end - match_data = { matches: {}, regex: regex, url: url } + match_data = { matches: {}, regex:, url: } match_data.merge!(Strategy.page_content(url)) content = match_data.delete(:content) diff --git a/Library/Homebrew/livecheck/strategy/xml.rb b/Library/Homebrew/livecheck/strategy/xml.rb index 7aa3870ba13d83..26c2e874d3dba0 100644 --- a/Library/Homebrew/livecheck/strategy/xml.rb +++ b/Library/Homebrew/livecheck/strategy/xml.rb @@ -149,14 +149,14 @@ def self.versions_from_content(content, regex = nil, &block) def self.find_versions(url:, regex: nil, provided_content: nil, homebrew_curl: false, **_unused, &block) raise ArgumentError, "#{Utils.demodulize(T.must(name))} requires a `strategy` block" if block.blank? - match_data = { matches: {}, regex: regex, url: url } + match_data = { matches: {}, regex:, url: } return match_data if url.blank? || block.blank? content = if provided_content.is_a?(String) match_data[:cached] = true provided_content else - match_data.merge!(Strategy.page_content(url, homebrew_curl: homebrew_curl)) + match_data.merge!(Strategy.page_content(url, homebrew_curl:)) match_data[:content] end return match_data if content.blank? diff --git a/Library/Homebrew/livecheck/strategy/yaml.rb b/Library/Homebrew/livecheck/strategy/yaml.rb index c86e06528a0ff2..60e2290df3b4c3 100644 --- a/Library/Homebrew/livecheck/strategy/yaml.rb +++ b/Library/Homebrew/livecheck/strategy/yaml.rb @@ -109,14 +109,14 @@ def self.versions_from_content(content, regex = nil, &block) def self.find_versions(url:, regex: nil, provided_content: nil, homebrew_curl: false, **_unused, &block) raise ArgumentError, "#{Utils.demodulize(T.must(name))} requires a `strategy` block" if block.blank? - match_data = { matches: {}, regex: regex, url: url } + match_data = { matches: {}, regex:, url: } return match_data if url.blank? || block.blank? content = if provided_content.is_a?(String) match_data[:cached] = true provided_content else - match_data.merge!(Strategy.page_content(url, homebrew_curl: homebrew_curl)) + match_data.merge!(Strategy.page_content(url, homebrew_curl:)) match_data[:content] end return match_data if content.blank? diff --git a/Library/Homebrew/locale.rb b/Library/Homebrew/locale.rb index df8996c4410b1f..b07b830585fbe2 100644 --- a/Library/Homebrew/locale.rb +++ b/Library/Homebrew/locale.rb @@ -63,9 +63,9 @@ def initialize(language, script, region) raise ArgumentError, "#{self.class} cannot be empty" if language.nil? && region.nil? && script.nil? { - language: language, - script: script, - region: region, + language:, + script:, + region:, }.each do |key, value| next if value.nil? diff --git a/Library/Homebrew/macos_runner_spec.rb b/Library/Homebrew/macos_runner_spec.rb index c808bb2e51c0c2..d8f1f0f47f65cb 100644 --- a/Library/Homebrew/macos_runner_spec.rb +++ b/Library/Homebrew/macos_runner_spec.rb @@ -10,10 +10,10 @@ class MacOSRunnerSpec < T::Struct sig { returns({ name: String, runner: String, timeout: Integer, cleanup: T::Boolean }) } def to_h { - name: name, - runner: runner, - timeout: timeout, - cleanup: cleanup, + name:, + runner:, + timeout:, + cleanup:, } end end diff --git a/Library/Homebrew/manpages.rb b/Library/Homebrew/manpages.rb index cac8e2d5d82a97..9e05bb81514d06 100644 --- a/Library/Homebrew/manpages.rb +++ b/Library/Homebrew/manpages.rb @@ -3,6 +3,10 @@ require "cli/parser" require "erb" +require "kramdown" +require "manpages/parser/ronn" +require "manpages/converter/kramdown" +require "manpages/converter/roff" SOURCE_PATH = (HOMEBREW_LIBRARY_PATH/"manpages").freeze TARGET_MAN_PATH = (HOMEBREW_REPOSITORY/"manpages").freeze @@ -30,9 +34,17 @@ module Manpages def self.regenerate_man_pages(quiet:) Homebrew.install_bundler_gems!(groups: ["man"]) - markup = build_man_page(quiet: quiet) - convert_man_page(markup, TARGET_DOC_PATH/"Manpage.md") - convert_man_page(markup, TARGET_MAN_PATH/"brew.1") + markup = build_man_page(quiet:) + root, warnings = Parser::Ronn.parse(markup) + $stderr.puts(warnings) + + roff, warnings = Converter::Kramdown.convert(root) + $stderr.puts(warnings) + File.write(TARGET_DOC_PATH/"Manpage.md", roff) + + roff, warnings = Converter::Roff.convert(root) + $stderr.puts(warnings) + File.write(TARGET_MAN_PATH/"brew.1", roff) end def self.build_man_page(quiet:) @@ -41,7 +53,7 @@ def self.build_man_page(quiet:) variables = Variables.new( commands: generate_cmd_manpages(Commands.internal_commands_paths), developer_commands: generate_cmd_manpages(Commands.internal_developer_commands_paths), - official_external_commands: generate_cmd_manpages(Commands.official_external_commands_paths(quiet: quiet)), + official_external_commands: generate_cmd_manpages(Commands.official_external_commands_paths(quiet:)), global_cask_options: global_cask_options_manpage, global_options: global_options_manpage, environment_variables: env_vars_manpage, @@ -65,59 +77,6 @@ def self.sort_key_for_path(path) path.basename.to_s.sub(/\.(rb|sh)$/, "").sub(/^--/, "~~") end - def self.convert_man_page(markup, target) - manual = target.basename(".1") - organisation = "Homebrew" - - # Set the manpage date to the existing one if we're updating. - # This avoids the only change being e.g. a new date. - date = if target.extname == ".1" && target.exist? - /"(\d{1,2})" "([A-Z][a-z]+) (\d{4})" "#{organisation}" "#{manual}"/ =~ target.read - Date.parse("#{Regexp.last_match(1)} #{Regexp.last_match(2)} #{Regexp.last_match(3)}") - else - Date.today - end - date = date.strftime("%Y-%m-%d") - - shared_args = %W[ - --pipe - --organization=#{organisation} - --manual=#{target.basename(".1")} - --date=#{date} - ] - - format_flag, format_desc = target_path_to_format(target) - - puts "Writing #{format_desc} to #{target}" - Utils.popen(["ronn", format_flag] + shared_args, "rb+") do |ronn| - ronn.write markup - ronn.close_write - ronn_output = ronn.read - odie "Got no output from ronn!" if ronn_output.blank? - ronn_output = case format_flag - when "--markdown" - ronn_output.gsub(%r{(.*?)}, "*`\\1`*") - .gsub(/\n\n\n+/, "\n\n") - .gsub(/^(- `[^`]+`):/, "\\1") # drop trailing colons from definition lists - .gsub(/(?<=\n\n)([\[`].+):\n/, "\\1\n
") # replace colons with
on subcommands - when "--roff" - ronn_output.gsub(%r{(.*?)}, "\\fB\\1\\fR") - .gsub(%r{(.*?)}, "\\fI\\1\\fR") - .gsub(/(^\[?\\fB.+): /, "\\1\n ") - end - target.atomic_write ronn_output - end - end - - def self.target_path_to_format(target) - case target.basename - when /\.md$/ then ["--markdown", "markdown"] - when /\.\d$/ then ["--roff", "man page"] - else - odie "Failed to infer output format from '#{target.basename}'." - end - end - def self.generate_cmd_manpages(cmd_paths) man_page_lines = [] @@ -129,8 +88,10 @@ def self.generate_cmd_manpages(cmd_paths) cmd_parser_manpage_lines(cmd_parser).join else - cmd_comment_manpage_lines(cmd_path) + cmd_comment_manpage_lines(cmd_path)&.join("\n") end + # Convert subcommands to definition lists + cmd_man_page_lines&.gsub!(/(?<=\n\n)([\\?\[`].+):\n/, "\\1\n\n: ") man_page_lines << cmd_man_page_lines end @@ -173,8 +134,10 @@ def self.cmd_comment_manpage_lines(cmd_path) next if line.match?(/--(debug|help|quiet|verbose) /) # Format one option or a comma-separated pair of short and long options. - lines << line.gsub(/^ +(-+[a-z-]+), (-+[a-z-]+) +/, "* `\\1`, `\\2`:\n ") - .gsub(/^ +(-+[a-z-]+) +/, "* `\\1`:\n ") + line.gsub!(/^ +(-+[a-z-]+), (-+[a-z-]+) +(.*)$/, "`\\1`, `\\2`\n\n: \\3\n") + line.gsub!(/^ +(-+[a-z-]+) +(.*)$/, "`\\1`\n\n: \\2\n") + + lines << line end lines.last << "\n" lines @@ -202,10 +165,10 @@ def self.global_options_manpage sig { returns(String) } def self.env_vars_manpage lines = Homebrew::EnvConfig::ENVS.flat_map do |env, hash| - entry = "- `#{env}`:\n
#{hash[:description]}\n" + entry = "`#{env}`\n\n: #{hash[:description]}\n" default = hash[:default_text] default ||= "`#{hash[:default]}`." if hash[:default] - entry += "\n\n *Default:* #{default}\n" if default + entry += "\n\n *Default:* #{default}\n" if default entry end @@ -219,13 +182,16 @@ def self.format_opt(opt) def self.generate_option_doc(short, long, desc) comma = (short && long) ? ", " : "" <<~EOS - * #{format_opt(short)}#{comma}#{format_opt(long)}: - #{desc} + #{format_opt(short)}#{comma}#{format_opt(long)} + + : #{desc} + EOS end def self.format_usage_banner(usage_banner) usage_banner&.sub(/^(#: *\* )?/, "### ") + &.gsub(/(? -`brew` [`--verbose`|`-v`] [] [] ... +`brew` \[`--verbose`\|`-v`\] \[\] \[\] ... ## DESCRIPTION @@ -30,29 +30,53 @@ Linux distribution without requiring `sudo`. ## TERMINOLOGY -**formula**: Homebrew package definition that builds from upstream sources +**formula** -**cask**: Homebrew package definition that installs macOS native applications +: Homebrew package definition that builds from upstream sources -**prefix**: path in which Homebrew is installed, e.g. `/usr/local` +**cask** -**keg**: installation destination directory of a given **formula** version, e.g. `/usr/local/Cellar/foo/0.1` +: Homebrew package definition that installs macOS native applications -**rack**: directory containing one or more versioned **kegs**, e.g. `/usr/local/Cellar/foo` +**prefix** -**keg-only**: a **formula** is *keg-only* if it is not symlinked into Homebrew's prefix +: path in which Homebrew is installed, e.g. `/usr/local` -**opt prefix**: a symlink to the active version of a **keg**, e.g. `/usr/local/opt/foo` +**keg** -**Cellar**: directory containing one or more named **racks**, e.g. `/usr/local/Cellar` +: installation destination directory of a given **formula** version, e.g. `/usr/local/Cellar/foo/0.1` -**Caskroom**: directory containing one or more named **casks**, e.g. `/usr/local/Caskroom` +**rack** -**external command**: `brew` subcommand defined outside of the Homebrew/brew GitHub repository +: directory containing one or more versioned **kegs**, e.g. `/usr/local/Cellar/foo` -**tap**: directory (and usually Git repository) of **formulae**, **casks** and/or **external commands** +**keg-only** -**bottle**: pre-built **keg** poured into a **rack** of the **Cellar** instead of building from upstream sources +: a **formula** is *keg-only* if it is not symlinked into Homebrew's prefix + +**opt prefix** + +: a symlink to the active version of a **keg**, e.g. `/usr/local/opt/foo` + +**Cellar** + +: directory containing one or more named **racks**, e.g. `/usr/local/Cellar` + +**Caskroom** + +: directory containing one or more named **casks**, e.g. `/usr/local/Caskroom` + +**external command** + +: `brew` subcommand defined outside of the Homebrew/brew GitHub repository + +**tap** + +: directory (and usually Git repository) of **formulae**, **casks** and/or **external commands** + +**bottle** + +: pre-built **keg** poured into a **rack** of the **Cellar** instead of building from upstream sources ## ESSENTIAL COMMANDS @@ -79,11 +103,11 @@ Uninstall . List all installed formulae. -### `search` [|`/``/`] +### `search` \[\|`/``/`\] Perform a substring search of cask tokens and formula names for . If - is flanked by slashes, it is interpreted as a regular expression. -The search for is extended online to `homebrew/core` and `homebrew/cask`. + is flanked by slashes, it is interpreted as a regular expression. The +search for is extended online to `homebrew/core` and `homebrew/cask`. If no search term is provided, all locally available formulae are listed. ## COMMANDS @@ -110,8 +134,8 @@ If no search term is provided, all locally available formulae are listed. Homebrew, like `git`(1), supports external commands. These are executable scripts that reside somewhere in the `PATH`, named `brew-` or -`brew-``.rb`, which can be invoked like `brew` . This allows -you to create your own commands without modifying Homebrew's internals. +`brew-``.rb`, which can be invoked like `brew` . This +allows you to create your own commands without modifying Homebrew's internals. Instructions for creating your own commands can be found in the docs: @@ -206,11 +230,14 @@ Homebrew API: See our issues on GitHub: - * **Homebrew/brew**: -
+**Homebrew/brew** + +: + +**Homebrew/homebrew-core** + +: - * **Homebrew/homebrew-core**: -
+**Homebrew/homebrew-cask** - * **Homebrew/homebrew-cask**: -
+: diff --git a/Library/Homebrew/manpages/converter/kramdown.rb b/Library/Homebrew/manpages/converter/kramdown.rb new file mode 100644 index 00000000000000..ebd407cf3de17f --- /dev/null +++ b/Library/Homebrew/manpages/converter/kramdown.rb @@ -0,0 +1,33 @@ +# typed: true +# frozen_string_literal: true + +require "kramdown/converter/kramdown" + +module Homebrew + module Manpages + module Converter + # Converts our Kramdown-like input to pure Kramdown. + # + # @api private + class Kramdown < ::Kramdown::Converter::Kramdown + def initialize(root, options) + super(root, options.merge(line_width: 80)) + end + + def convert_variable(element, _options) + "*`#{element.value}`*" + end + + def convert_a(element, options) + text = inner(element, options) + if element.attr["href"] == text + # Don't duplicate the URL if the link text is the same as the URL. + "<#{text}>" + else + super(element, options) + end + end + end + end + end +end diff --git a/Library/Homebrew/manpages/converter/roff.rb b/Library/Homebrew/manpages/converter/roff.rb new file mode 100644 index 00000000000000..3f59c7f617b3b4 --- /dev/null +++ b/Library/Homebrew/manpages/converter/roff.rb @@ -0,0 +1,56 @@ +# typed: true +# frozen_string_literal: true + +require "kramdown/converter/man" + +module Homebrew + module Manpages + module Converter + # Converts our Kramdown-like input to roff. + # + # @api private + class Roff < ::Kramdown::Converter::Man + # Override that adds Homebrew metadata for the top level header + # and doesn't escape the text inside subheaders. + def convert_header(element, options) + if element.options[:level] == 1 + element.attr["data-date"] = Date.today.strftime("%B %Y") + element.attr["data-extra"] = "Homebrew" + return super + end + + result = +"" + inner(element, options.merge(result:)) + result.gsub!(" [", ' \fR[') # make args not bold + + options[:result] << if element.options[:level] == 2 + macro("SH", quote(result)) + else + macro("SS", quote(result)) + end + end + + def convert_variable(element, options) + options[:result] << "\\fI#{escape(element.value)}\\fP" + end + + def convert_a(element, options) + if element.attr["href"].chr == "#" + # Hide internal links - just make them italicised + convert_em(element, options) + else + super + # Remove the space after links if the next character is not a space + if options[:result].end_with?(".UE\n") && + (next_element = options[:next]) && + next_element.type == :text && + next_element.value.chr.present? # i.e. not a space character + options[:result].chomp! + options[:result] << " " + end + end + end + end + end + end +end diff --git a/Library/Homebrew/manpages/parser/ronn.rb b/Library/Homebrew/manpages/parser/ronn.rb new file mode 100644 index 00000000000000..673347d5d6bd1b --- /dev/null +++ b/Library/Homebrew/manpages/parser/ronn.rb @@ -0,0 +1,43 @@ +# typed: true +# frozen_string_literal: true + +require "kramdown/parser/kramdown" + +module Homebrew + module Manpages + module Parser + # Kramdown parser with compatiblity for ronn variable syntax. + # + # @api private + class Ronn < ::Kramdown::Parser::Kramdown + def initialize(*) + super + # Disable HTML parsing and replace it with variable parsing. + # Also disable table parsing too because it depends on HTML parsing + # and existing command descriptions may get misinterpreted as tables. + # Typographic symbols is disabled as it detects `--` as en-dash. + @block_parsers.delete(:block_html) + @block_parsers.delete(:table) + @span_parsers.delete(:span_html) + @span_parsers.delete(:typographic_syms) + @span_parsers << :variable + end + + # HTML-like tags denote variables instead, except
. + VARIABLE_REGEX = /<([\w\-\|]+)>/ + def parse_variable + start_line_number = @src.current_line_number + @src.scan(VARIABLE_REGEX) + variable = @src[1] + if variable == "br" + @src.skip(/\n/) + @tree.children << Element.new(:br, nil, nil, location: start_line_number) + else + @tree.children << Element.new(:variable, variable, nil, location: start_line_number) + end + end + define_parser(:variable, VARIABLE_REGEX, "<") + end + end + end +end diff --git a/Library/Homebrew/messages.rb b/Library/Homebrew/messages.rb index b7f9a47a2fd92f..f032e17829ab7f 100644 --- a/Library/Homebrew/messages.rb +++ b/Library/Homebrew/messages.rb @@ -14,12 +14,12 @@ def initialize end def record_caveats(package, caveats) - @caveats.push(package: package, caveats: caveats) + @caveats.push(package:, caveats:) end def package_installed(package, elapsed_time) @package_count += 1 - @install_times.push(package: package, time: elapsed_time) + @install_times.push(package:, time: elapsed_time) end def display_messages(force_caveats: false, display_times: false) diff --git a/Library/Homebrew/migrator.rb b/Library/Homebrew/migrator.rb index 96054e080e77fd..0e08423bb4d29f 100644 --- a/Library/Homebrew/migrator.rb +++ b/Library/Homebrew/migrator.rb @@ -114,7 +114,7 @@ def self.migrate_if_needed(formula, force:, dry_run: false) next end - migrator = Migrator.new(formula, oldname, force: force) + migrator = Migrator.new(formula, oldname, force:) migrator.migrate end rescue => e diff --git a/Library/Homebrew/missing_formula.rb b/Library/Homebrew/missing_formula.rb index daa5a16f93bf7f..6bf851b1d858c7 100644 --- a/Library/Homebrew/missing_formula.rb +++ b/Library/Homebrew/missing_formula.rb @@ -10,8 +10,8 @@ module Homebrew module MissingFormula class << self def reason(name, silent: false, show_info: false) - cask_reason(name, silent: silent, show_info: show_info) || disallowed_reason(name) || - tap_migration_reason(name) || deleted_reason(name, silent: silent) + cask_reason(name, silent:, show_info:) || disallowed_reason(name) || + tap_migration_reason(name) || deleted_reason(name, silent:) end def disallowed_reason(name) diff --git a/Library/Homebrew/official_taps.rb b/Library/Homebrew/official_taps.rb index b6a36c26633f89..d01342105123b7 100644 --- a/Library/Homebrew/official_taps.rb +++ b/Library/Homebrew/official_taps.rb @@ -9,7 +9,6 @@ OFFICIAL_CMD_TAPS = { "homebrew/aliases" => ["alias", "unalias"], - "homebrew/autoupdate" => ["autoupdate"], "homebrew/bundle" => ["bundle"], "homebrew/command-not-found" => ["command-not-found-init", "which-formula", "which-update"], "homebrew/test-bot" => ["test-bot"], diff --git a/Library/Homebrew/os/mac/mach.rb b/Library/Homebrew/os/mac/mach.rb index 5bf2d8fd9335dc..b1ecd686ed6643 100644 --- a/Library/Homebrew/os/mac/mach.rb +++ b/Library/Homebrew/os/mac/mach.rb @@ -40,7 +40,7 @@ def mach_data else :dunno end - mach_data << { arch: arch, type: type } + mach_data << { arch:, type: } end mach_data diff --git a/Library/Homebrew/os/mac/xcode.rb b/Library/Homebrew/os/mac/xcode.rb old mode 100755 new mode 100644 index cdb2d5b90fcda0..aa159b69f90669 --- a/Library/Homebrew/os/mac/xcode.rb +++ b/Library/Homebrew/os/mac/xcode.rb @@ -50,7 +50,7 @@ def self.minimum_version when "10.14" then "10.2" when "10.13" then "9.0" when "10.12" then "8.0" - else "2.0" + else "7.3" end end @@ -373,7 +373,7 @@ def self.minimum_version when "10.14" then "10.0.0" when "10.13" then "9.0.0" when "10.12" then "8.0.0" - else "1.0.0" + else "7.3.0" end end diff --git a/Library/Homebrew/readall.rb b/Library/Homebrew/readall.rb index ab1d24f508ea4f..86ad869d790267 100644 --- a/Library/Homebrew/readall.rb +++ b/Library/Homebrew/readall.rb @@ -62,7 +62,7 @@ def self.valid_formulae?(tap, bottle_tag: nil) readall_namespace = "ReadallNamespace" readall_formula_class = Formulary.load_formula(formula_name, file, formula_contents, readall_namespace, flags: [], ignore_errors: false) - readall_formula = readall_formula_class.new(formula_name, file, :stable, tap: tap) + readall_formula = readall_formula_class.new(formula_name, file, :stable, tap:) readall_formula.to_hash # TODO: Remove check for MACOS_MODULE_REGEX once the `MacOS` module is undefined on Linux cache[:valid_formulae][file] = if readall_formula.on_system_blocks_exist? || @@ -99,12 +99,12 @@ def self.valid_tap?(tap, aliases: false, no_simulate: false, success = false unless valid_casks?(tap) else os_arch_combinations.each do |os, arch| - bottle_tag = Utils::Bottles::Tag.new(system: os, arch: arch) + bottle_tag = Utils::Bottles::Tag.new(system: os, arch:) next unless bottle_tag.valid_combination? - Homebrew::SimulateSystem.with os: os, arch: arch do - success = false unless valid_formulae?(tap, bottle_tag: bottle_tag) - success = false unless valid_casks?(tap, os_name: os, arch: arch) + Homebrew::SimulateSystem.with(os:, arch:) do + success = false unless valid_formulae?(tap, bottle_tag:) + success = false unless valid_casks?(tap, os_name: os, arch:) end end end diff --git a/Library/Homebrew/reinstall.rb b/Library/Homebrew/reinstall.rb index 87bfb12004b5ce..82a79f1d5ca75a 100644 --- a/Library/Homebrew/reinstall.rb +++ b/Library/Homebrew/reinstall.rb @@ -39,21 +39,21 @@ def reinstall_formula( fi = FormulaInstaller.new( formula, **{ - options: options, + options:, link_keg: keg_had_linked_opt ? keg_was_linked : nil, installed_as_dependency: tab&.installed_as_dependency, installed_on_request: installed_on_request || tab&.installed_on_request, build_bottle: tab&.built_bottle?, - force_bottle: force_bottle, - build_from_source_formulae: build_from_source_formulae, - git: git, - interactive: interactive, - keep_tmp: keep_tmp, - debug_symbols: debug_symbols, - force: force, - debug: debug, - quiet: quiet, - verbose: verbose, + force_bottle:, + build_from_source_formulae:, + git:, + interactive:, + keep_tmp:, + debug_symbols:, + force:, + debug:, + quiet:, + verbose:, }.compact, ) fi.prelude @@ -66,7 +66,7 @@ def reinstall_formula( rescue FormulaInstallationAlreadyAttemptedError nil rescue Exception # rubocop:disable Lint/RescueException - ignore_interrupts { restore_backup(keg, keg_was_linked, verbose: verbose) } + ignore_interrupts { restore_backup(keg, keg_was_linked, verbose:) } raise else begin @@ -99,7 +99,7 @@ def restore_backup(keg, keg_was_linked, verbose:) Pathname.new(keg).rmtree if keg.exist? path.rename keg - keg.link(verbose: verbose) if keg_was_linked + keg.link(verbose:) if keg_was_linked end def backup_path(path) diff --git a/Library/Homebrew/requirement.rb b/Library/Homebrew/requirement.rb index d4d15b4f69ec7b..3e0c5ffff3a4c0 100644 --- a/Library/Homebrew/requirement.rb +++ b/Library/Homebrew/requirement.rb @@ -75,7 +75,7 @@ def satisfied?(env: nil, cc: nil, build_bottle: false, bottle_arch: nil) return true unless satisfy @satisfied_result = - satisfy.yielder(env: env, cc: cc, build_bottle: build_bottle, bottle_arch: bottle_arch) do |p| + satisfy.yielder(env:, cc:, build_bottle:, bottle_arch:) do |p| instance_eval(&p) end return false unless @satisfied_result @@ -109,7 +109,7 @@ def satisfied_result_parent ).void } def modify_build_environment(env: nil, cc: nil, build_bottle: false, bottle_arch: nil) - satisfied?(env: env, cc: cc, build_bottle: build_bottle, bottle_arch: bottle_arch) + satisfied?(env:, cc:, build_bottle:, bottle_arch:) instance_eval(&env_proc) if env_proc # XXX If the satisfy block returns a Pathname, then make sure that it @@ -219,7 +219,7 @@ def yielder(env: nil, cc: nil, build_bottle: false, bottle_arch: nil) elsif @options[:build_env] require "extend/ENV" ENV.with_build_environment( - env: env, cc: cc, build_bottle: build_bottle, bottle_arch: bottle_arch, + env:, cc:, build_bottle:, bottle_arch:, ) do yield @proc end diff --git a/Library/Homebrew/resource.rb b/Library/Homebrew/resource.rb index 07731fefbe02af..fc00c8dccc824a 100644 --- a/Library/Homebrew/resource.rb +++ b/Library/Homebrew/resource.rb @@ -95,7 +95,7 @@ def stage(target = nil, debug_symbols: false, &block) fetch_patches(skip_downloaded: true) fetch unless downloaded? - unpack(target, debug_symbols: debug_symbols, &block) + unpack(target, debug_symbols:, &block) end def prepare_patches @@ -121,7 +121,7 @@ def apply_patches # A target or a block must be given, but not both. def unpack(target = nil, debug_symbols: false) current_working_directory = Pathname.pwd - stage_resource(download_name, debug_symbols: debug_symbols) do |staging| + stage_resource(download_name, debug_symbols:) do |staging| downloader.stage do @source_modified_time = downloader.source_modified_time apply_patches @@ -145,7 +145,7 @@ def files(*files) def fetch(verify_download_integrity: true) fetch_patches - super(verify_download_integrity: verify_download_integrity) + super(verify_download_integrity:) end # @!attribute [w] livecheck diff --git a/Library/Homebrew/resource_auditor.rb b/Library/Homebrew/resource_auditor.rb index de861cec0ffe16..eb29bf3b546ecb 100644 --- a/Library/Homebrew/resource_auditor.rb +++ b/Library/Homebrew/resource_auditor.rb @@ -143,7 +143,7 @@ def audit_urls if (http_content_problem = curl_check_http_content( url, "source URL", - specs: specs, + specs:, use_homebrew_curl: @use_homebrew_curl, )) problem http_content_problem diff --git a/Library/Homebrew/rubocops/blank.rb b/Library/Homebrew/rubocops/blank.rb index 4affb4e59d2267..e6a22cb8901f72 100644 --- a/Library/Homebrew/rubocops/blank.rb +++ b/Library/Homebrew/rubocops/blank.rb @@ -50,7 +50,7 @@ def on_or(node) return if var1 != var2 message = format(MSG_NIL_OR_EMPTY, prefer: replacement(var1), current: node.source) - add_offense(node, message: message) do |corrector| + add_offense(node, message:) do |corrector| autocorrect(corrector, node) end end diff --git a/Library/Homebrew/rubocops/cask/homepage_url_trailing_slash.rb b/Library/Homebrew/rubocops/cask/homepage_url_trailing_slash.rb index c26c1848e76a51..cab96ee824d726 100644 --- a/Library/Homebrew/rubocops/cask/homepage_url_trailing_slash.rb +++ b/Library/Homebrew/rubocops/cask/homepage_url_trailing_slash.rb @@ -35,7 +35,7 @@ def on_homepage_stanza(stanza) # and 'https://example.org#path' into account. corrected_source = url_node.source.sub("://#{domain}", "://#{domain}/") - add_offense(url_node.loc.expression, message: format(MSG_NO_SLASH, url: url)) do |corrector| + add_offense(url_node.loc.expression, message: format(MSG_NO_SLASH, url:)) do |corrector| corrector.replace(url_node.source_range, corrected_source) end end diff --git a/Library/Homebrew/rubocops/cask/on_system_conditionals.rb b/Library/Homebrew/rubocops/cask/on_system_conditionals.rb index a5b791e81dfe2a..3039ea9304bb96 100644 --- a/Library/Homebrew/rubocops/cask/on_system_conditionals.rb +++ b/Library/Homebrew/rubocops/cask/on_system_conditionals.rb @@ -55,7 +55,7 @@ def simplify_sha256_stanzas nodes = {} sha256_on_arch_stanzas(cask_body) do |node, method, value| - nodes[method.to_s.delete_prefix("on_").to_sym] = { node: node, value: value } + nodes[method.to_s.delete_prefix("on_").to_sym] = { node:, value: } end return if !nodes.key?(:arm) || !nodes.key?(:intel) diff --git a/Library/Homebrew/rubocops/cask/shared_filelist_glob.rb b/Library/Homebrew/rubocops/cask/shared_filelist_glob.rb index 8f2e4abbace408..24c4b6c07c285f 100644 --- a/Library/Homebrew/rubocops/cask/shared_filelist_glob.rb +++ b/Library/Homebrew/rubocops/cask/shared_filelist_glob.rb @@ -24,7 +24,7 @@ def on_send(node) corrected_item = item.source.sub(/sfl\d"$/, "sfl*\"") add_offense(item, - message: message) do |corrector| + message:) do |corrector| corrector.replace(item, corrected_item) end end diff --git a/Library/Homebrew/rubocops/cask/stanza_grouping.rb b/Library/Homebrew/rubocops/cask/stanza_grouping.rb index 93fcaf39b82440..d5d3b90f765d87 100644 --- a/Library/Homebrew/rubocops/cask/stanza_grouping.rb +++ b/Library/Homebrew/rubocops/cask/stanza_grouping.rb @@ -91,7 +91,7 @@ def add_offense(line_index, message:) line_length = [processed_source[line_index].size, 1].max @range = source_range(processed_source.buffer, line_index + 1, 0, line_length) - super(@range, message: message) + super(@range, message:) end end end diff --git a/Library/Homebrew/rubocops/cask/url_legacy_comma_separators.rb b/Library/Homebrew/rubocops/cask/url_legacy_comma_separators.rb index 67e0babdd2fa03..6428b91eb8fb4f 100644 --- a/Library/Homebrew/rubocops/cask/url_legacy_comma_separators.rb +++ b/Library/Homebrew/rubocops/cask/url_legacy_comma_separators.rb @@ -25,7 +25,7 @@ def on_url_stanza(stanza) corrected_url = url.sub("before_comma", "csv.first")&.sub("after_comma", "csv.second") - add_offense(url_node.loc.expression, message: format(MSG_CSV, url: url)) do |corrector| + add_offense(url_node.loc.expression, message: format(MSG_CSV, url:)) do |corrector| corrector.replace(url_node.source_range, corrected_url) end end diff --git a/Library/Homebrew/rubocops/compact_blank.rb b/Library/Homebrew/rubocops/compact_blank.rb index 6539878f1f5a1e..0bdf44159e6365 100644 --- a/Library/Homebrew/rubocops/compact_blank.rb +++ b/Library/Homebrew/rubocops/compact_blank.rb @@ -64,7 +64,7 @@ def on_send(node) range = offense_range(node) preferred_method = preferred_method(node) - add_offense(range, message: format(MSG, preferred_method: preferred_method)) do |corrector| + add_offense(range, message: format(MSG, preferred_method:)) do |corrector| corrector.replace(range, preferred_method) end end diff --git a/Library/Homebrew/rubocops/presence.rb b/Library/Homebrew/rubocops/presence.rb index 0c74c572f891d2..97fb8497f97f2c 100644 --- a/Library/Homebrew/rubocops/presence.rb +++ b/Library/Homebrew/rubocops/presence.rb @@ -109,7 +109,7 @@ def ignore_other_node?(node) def message(node, receiver, other) prefer = replacement(receiver, other, node.left_sibling).gsub(/^\s*|\n/, "") current = current(node).gsub(/^\s*|\n/, "") - format(MSG, prefer: prefer, current: current) + format(MSG, prefer:, current:) end def current(node) diff --git a/Library/Homebrew/rubocops/present.rb b/Library/Homebrew/rubocops/present.rb index 99e8fe28988b43..fb83c69192c8b8 100644 --- a/Library/Homebrew/rubocops/present.rb +++ b/Library/Homebrew/rubocops/present.rb @@ -43,7 +43,7 @@ def on_and(node) message = format(MSG_EXISTS_AND_NOT_EMPTY, prefer: replacement(var1), current: node.source) - add_offense(node, message: message) do |corrector| + add_offense(node, message:) do |corrector| autocorrect(corrector, node) end end diff --git a/Library/Homebrew/rubocops/shared/desc_helper.rb b/Library/Homebrew/rubocops/shared/desc_helper.rb index 36c0c0a851958f..85a7c6dd43c7ce 100644 --- a/Library/Homebrew/rubocops/shared/desc_helper.rb +++ b/Library/Homebrew/rubocops/shared/desc_helper.rb @@ -86,7 +86,7 @@ def audit_desc(type, name, desc_call) # Auto correct desc problems. `regex_match_group` must be called before this to populate @offense_source_range. def desc_problem(message) - add_offense(@offensive_source_range, message: message) do |corrector| + add_offense(@offensive_source_range, message:) do |corrector| match_data = @offensive_node.source.match(/\A(?["'])(?.*)(?:\k)\Z/) correction = match_data[:correction] quote = match_data[:quote] diff --git a/Library/Homebrew/rubocops/shared/on_system_conditionals_helper.rb b/Library/Homebrew/rubocops/shared/on_system_conditionals_helper.rb index bee4847630a5ae..3441c15f32feb3 100644 --- a/Library/Homebrew/rubocops/shared/on_system_conditionals_helper.rb +++ b/Library/Homebrew/rubocops/shared/on_system_conditionals_helper.rb @@ -83,18 +83,18 @@ def audit_arch_conditionals(body_node, allowed_methods: [], allowed_blocks: []) ARCH_OPTIONS.each do |arch_option| else_method = (arch_option == :arm) ? :on_intel : :on_arm if_arch_node_search(body_node, arch: :"#{arch_option}?") do |if_node, else_node| - next if node_is_allowed?(if_node, allowed_methods: allowed_methods, allowed_blocks: allowed_blocks) + next if node_is_allowed?(if_node, allowed_methods:, allowed_blocks:) if_statement_problem(if_node, "if Hardware::CPU.#{arch_option}?", "on_#{arch_option}", - else_method: else_method, else_node: else_node) + else_method:, else_node:) end end [:arch, :arm?, :intel?].each do |method| - hardware_cpu_search(body_node, method: method) do |method_node| + hardware_cpu_search(body_node, method:) do |method_node| # These should already be caught by `if_arch_node_search` next if method_node.parent.source.start_with? "if #{method_node.source}" - next if node_is_allowed?(method_node, allowed_methods: allowed_methods, allowed_blocks: allowed_blocks) + next if node_is_allowed?(method_node, allowed_methods:, allowed_blocks:) offending_node(method_node) problem "Don't use `#{method_node.source}`, use `on_arm` and `on_intel` blocks instead." @@ -110,10 +110,10 @@ def audit_base_os_conditionals(body_node, allowed_methods: [], allowed_blocks: [ [:linux?, :on_macos] end if_base_os_node_search(body_node, base_os: os_method) do |if_node, else_node| - next if node_is_allowed?(if_node, allowed_methods: allowed_methods, allowed_blocks: allowed_blocks) + next if node_is_allowed?(if_node, allowed_methods:, allowed_blocks:) if_statement_problem(if_node, "if OS.#{os_method}", "on_#{base_os_option}", - else_method: else_method, else_node: else_node) + else_method:, else_node:) end end end @@ -122,7 +122,7 @@ def audit_macos_version_conditionals(body_node, allowed_methods: [], allowed_blo recommend_on_system: true) MACOS_VERSION_OPTIONS.each do |macos_version_option| if_macos_version_node_search(body_node, os_version: macos_version_option) do |if_node, operator, else_node| - next if node_is_allowed?(if_node, allowed_methods: allowed_methods, allowed_blocks: allowed_blocks) + next if node_is_allowed?(if_node, allowed_methods:, allowed_blocks:) autocorrect = else_node.blank? && MACOS_VERSION_CONDITIONALS.key?(operator.to_s) on_system_method_string = if recommend_on_system && operator == :< @@ -136,13 +136,13 @@ def audit_macos_version_conditionals(body_node, allowed_methods: [], allowed_blo end if_statement_problem(if_node, "if MacOS.version #{operator} :#{macos_version_option}", - on_system_method_string, autocorrect: autocorrect) + on_system_method_string, autocorrect:) end macos_version_comparison_search(body_node, os_version: macos_version_option) do |method_node| # These should already be caught by `if_macos_version_node_search` next if method_node.parent.source.start_with? "if #{method_node.source}" - next if node_is_allowed?(method_node, allowed_methods: allowed_methods, allowed_blocks: allowed_blocks) + next if node_is_allowed?(method_node, allowed_methods:, allowed_blocks:) offending_node(method_node) problem "Don't use `#{method_node.source}`, use `on_{macos_version}` blocks instead." @@ -153,7 +153,7 @@ def audit_macos_version_conditionals(body_node, allowed_methods: [], allowed_blo def audit_macos_references(body_node, allowed_methods: [], allowed_blocks: []) MACOS_MODULE_NAMES.each do |macos_module_name| find_const(body_node, macos_module_name) do |node| - next if node_is_allowed?(node, allowed_methods: allowed_methods, allowed_blocks: allowed_blocks) + next if node_is_allowed?(node, allowed_methods:, allowed_blocks:) offending_node(node) problem "Don't use `#{macos_module_name}` where it could be called on Linux." diff --git a/Library/Homebrew/rubocops/shell_commands.rb b/Library/Homebrew/rubocops/shell_commands.rb index 1672b414e5e033..505141ead5c614 100644 --- a/Library/Homebrew/rubocops/shell_commands.rb +++ b/Library/Homebrew/rubocops/shell_commands.rb @@ -101,7 +101,7 @@ def on_send(node) else target_method.to_s end - add_offense(first_arg, message: format(MSG, method: method_string, good_args: good_args)) do |corrector| + add_offense(first_arg, message: format(MSG, method: method_string, good_args:)) do |corrector| corrector.replace(first_arg.source_range, good_args) end end diff --git a/Library/Homebrew/rubocops/text.rb b/Library/Homebrew/rubocops/text.rb index 636a79c70122bd..c14a159655def3 100644 --- a/Library/Homebrew/rubocops/text.rb +++ b/Library/Homebrew/rubocops/text.rb @@ -18,7 +18,7 @@ def audit_formula(node, _class_node, _parent_class_node, body_node) if (match = full_source_content.match(/^require ['"]formula['"]$/)) range = source_range(source_buffer(node), match.pre_match.count("\n") + 1, 0, match[0].length) add_offense(range, message: "`#{match}` is now unnecessary") do |corrector| - corrector.remove(range_with_surrounding_space(range: range)) + corrector.remove(range_with_surrounding_space(range:)) end end diff --git a/Library/Homebrew/search.rb b/Library/Homebrew/search.rb index 6c9fa16d1172ef..ffd09da2129286 100644 --- a/Library/Homebrew/search.rb +++ b/Library/Homebrew/search.rb @@ -81,12 +81,14 @@ def self.search_casks(string_or_regex) end end - cask_tokens = Tap.flat_map(&:cask_tokens).filter_map do |c| - next if c.start_with?("homebrew/cask/") && !Homebrew::EnvConfig.no_install_from_api? - - c.sub(%r{^homebrew/cask.*/}, "") - end - cask_tokens |= Homebrew::API::Cask.all_casks.keys unless Homebrew::EnvConfig.no_install_from_api? + cask_tokens = Tap.each_with_object([]) do |tap, array| + # We can exclude the core cask tap because `CoreCaskTap#cask_tokens` returns short names by default. + if tap.official? && !tap.core_cask_tap? + tap.cask_tokens.each { |token| array << token.sub(%r{^homebrew/cask.*/}, "") } + else + tap.cask_tokens.each { |token| array << token } + end + end.uniq results = search(cask_tokens, string_or_regex) results += DidYouMean::SpellChecker.new(dictionary: cask_tokens) diff --git a/Library/Homebrew/service.rb b/Library/Homebrew/service.rb index ae9cf8a9d95e7f..4e95df752f2e71 100644 --- a/Library/Homebrew/service.rb +++ b/Library/Homebrew/service.rb @@ -77,10 +77,10 @@ def run(command = nil, macos: nil, linux: nil) if command @run_params = command elsif macos || linux - @run_params = { macos: macos, linux: linux }.compact + @run_params = { macos:, linux: }.compact end - command ||= on_system_conditional(macos: macos, linux: linux) + command ||= on_system_conditional(macos:, linux:) case command when nil @run @@ -214,7 +214,7 @@ def sockets(value = nil) raise TypeError, "Service#sockets expects a valid ipv4 or ipv6 host address" end - { host: host, port: port, type: type } + { host:, port:, type: } end end diff --git a/Library/Homebrew/settings.rb b/Library/Homebrew/settings.rb index 61491773d63e22..e880c5bdf46f58 100644 --- a/Library/Homebrew/settings.rb +++ b/Library/Homebrew/settings.rb @@ -23,7 +23,7 @@ def self.write(setting, value, repo: HOMEBREW_REPOSITORY) value = value.to_s - return if read(setting, repo: repo) == value + return if read(setting, repo:) == value Kernel.system("git", "-C", repo.to_s, "config", "--replace-all", "homebrew.#{setting}", value, exception: true) end @@ -31,7 +31,7 @@ def self.write(setting, value, repo: HOMEBREW_REPOSITORY) def self.delete(setting, repo: HOMEBREW_REPOSITORY) return unless (repo/".git/config").exist? - return if read(setting, repo: repo).nil? + return if read(setting, repo:).nil? Kernel.system("git", "-C", repo.to_s, "config", "--unset-all", "homebrew.#{setting}", exception: true) end diff --git a/Library/Homebrew/shims/super/cc b/Library/Homebrew/shims/super/cc index 2706649680f4e2..aa4b71bb842664 100755 --- a/Library/Homebrew/shims/super/cc +++ b/Library/Homebrew/shims/super/cc @@ -29,7 +29,7 @@ class Cmd CXX_REGEX = /(?:c|g|clang)\+\+/.freeze attr_reader :config, :prefix, :cellar, :opt, :cachedir, :tmpdir, :sysroot, :deps - attr_reader :archflags, :optflags, :keg_regex, :formula_prefix + attr_reader :archflags, :optflags, :keg_regex, :formula_prefix, :formula_buildpath def initialize(arg0, args) @arg0 = arg0 @@ -45,6 +45,7 @@ class Cmd @optflags = ENV.fetch("HOMEBREW_OPTFLAGS", "").split @deps = Set.new(ENV.fetch("HOMEBREW_DEPENDENCIES", "").split(",")) @formula_prefix = ENV["HOMEBREW_FORMULA_PREFIX"] + @formula_buildpath = ENV["HOMEBREW_FORMULA_BUILDPATH"] # matches opt or cellar prefix and formula name @keg_regex = %r{(#{Regexp.escape(opt)}|#{Regexp.escape(cellar)})/([\w+-.@]+)} end @@ -310,6 +311,9 @@ class Cmd args += path_flags("-isystem", isystem_paths) + path_flags("-I", include_paths) # Add -nostdinc when building against glibc@2.13 to avoid mixing system and brewed glibc headers. args << "-nostdinc" if @deps.include?("glibc@2.13") + # Ideally this would be -ffile-prefix-map, but that requires a minimum of GCC 8, LLVM Clang 10 or Apple Clang 12 + # and detecting the version dynamically based on what `HOMEBREW_CC` may have been rewritten to point to is awkward + args << "-fdebug-prefix-map=#{formula_buildpath}=." if formula_buildpath args end @@ -319,10 +323,12 @@ class Cmd args << "-headerpad_max_install_names" args << "-no_weak_imports" if no_weak_imports? args << "-no_fixup_chains" if no_fixup_chains? + args << "-oso_prefix" << formula_buildpath if oso_prefix? && formula_buildpath when :ccld, :cxxld args << "-Wl,-headerpad_max_install_names" args << "-Wl,-no_weak_imports" if no_weak_imports? args << "-Wl,-no_fixup_chains" if no_fixup_chains? + args << "-Wl,-oso_prefix,#{formula_buildpath}" if oso_prefix? && formula_buildpath end args end @@ -431,6 +437,10 @@ class Cmd @args.include?("-undefineddynamic_lookup") end + def oso_prefix? + config.include?("o") + end + def calls_ld? return true if mode == :ld return false unless [:ccld, :cxxld].include?(mode) diff --git a/Library/Homebrew/software_spec.rb b/Library/Homebrew/software_spec.rb index b21df2b0faf99a..978522a42d3395 100644 --- a/Library/Homebrew/software_spec.rb +++ b/Library/Homebrew/software_spec.rb @@ -203,7 +203,7 @@ def uses_from_macos(dep, bounds = {}) tags = [] end - depends_on UsesFromMacOSDependency.new(dep, tags, bounds: bounds) + depends_on UsesFromMacOSDependency.new(dep, tags, bounds:) end # @deprecated @@ -366,7 +366,7 @@ def initialize(formula, spec, tag = nil) end def fetch(verify_download_integrity: true) - @resource.fetch(verify_download_integrity: verify_download_integrity) + @resource.fetch(verify_download_integrity:) rescue DownloadError raise unless fallback_on_error @@ -587,7 +587,7 @@ def skip_relocation?(tag: Utils::Bottles.tag) sig { params(tag: T.any(Symbol, Utils::Bottles::Tag), no_older_versions: T::Boolean).returns(T::Boolean) } def tag?(tag, no_older_versions: false) - collector.tag?(tag, no_older_versions: no_older_versions) + collector.tag?(tag, no_older_versions:) end # Checksum methods in the DSL's bottle block take @@ -611,7 +611,7 @@ def sha256(hash) cellar ||= tag.default_cellar - collector.add(tag, checksum: Checksum.new(digest), cellar: cellar) + collector.add(tag, checksum: Checksum.new(digest), cellar:) end sig { @@ -619,7 +619,7 @@ def sha256(hash) .returns(T.nilable(Utils::Bottles::TagSpecification)) } def tag_specification_for(tag, no_older_versions: false) - collector.specification_for(tag, no_older_versions: no_older_versions) + collector.specification_for(tag, no_older_versions:) end def checksums diff --git a/Library/Homebrew/sorbet/parlour/attr.rb b/Library/Homebrew/sorbet/parlour/attr.rb index 1771e164da3d43..5fdc404d165770 100644 --- a/Library/Homebrew/sorbet/parlour/attr.rb +++ b/Library/Homebrew/sorbet/parlour/attr.rb @@ -152,7 +152,7 @@ def process_custom_attr(tree, namespace, sclass: false) Parlour::RbiGenerator::Parameter.new("**options"), Parlour::RbiGenerator::Parameter.new("&block"), ], - return_type: return_type, + return_type:, ) else raise "Malformed tree." diff --git a/Library/Homebrew/sorbet/rbi/dsl/homebrew/cli/args.rbi b/Library/Homebrew/sorbet/rbi/dsl/homebrew/cli/args.rbi new file mode 100644 index 00000000000000..c88f445543e472 --- /dev/null +++ b/Library/Homebrew/sorbet/rbi/dsl/homebrew/cli/args.rbi @@ -0,0 +1,898 @@ +# typed: true + +# DO NOT EDIT MANUALLY +# This is an autogenerated file for dynamic methods in `Homebrew::CLI::Args`. +# Please instead update this file by running `bin/tapioca dsl Homebrew::CLI::Args`. + +class Homebrew::CLI::Args + sig { returns(T::Boolean) } + def D?; end + + sig { returns(T::Boolean) } + def HEAD?; end + + sig { returns(T.nilable(T::Array[String])) } + def add_groups; end + + sig { returns(T::Boolean) } + def adopt?; end + + sig { returns(T::Boolean) } + def aliases?; end + + sig { returns(T::Boolean) } + def all_supported?; end + + sig { returns(T::Boolean) } + def analytics?; end + + sig { returns(T::Boolean) } + def annotate?; end + + sig { returns(T.nilable(String)) } + def appdir; end + + sig { returns(T.nilable(String)) } + def arch; end + + sig { returns(T::Boolean) } + def archlinux?; end + + sig { returns(T.nilable(String)) } + def artifact; end + + sig { returns(T.nilable(String)) } + def audio_unit_plugindir; end + + sig { returns(T::Boolean) } + def audit_debug?; end + + sig { returns(T::Boolean) } + def auto_update?; end + + sig { returns(T::Boolean) } + def autosquash?; end + + sig { returns(T::Boolean) } + def autotools?; end + + sig { returns(T.nilable(String)) } + def before; end + + sig { returns(T::Boolean) } + def binaries?; end + + sig { returns(T.nilable(String)) } + def bottle_arch; end + + sig { returns(T.nilable(String)) } + def bottle_tag; end + + sig { returns(T.nilable(String)) } + def branch; end + + sig { returns(T::Boolean) } + def branch_okay?; end + + sig { returns(T::Boolean) } + def build_bottle?; end + + sig { returns(T::Boolean) } + def build_from_source?; end + + sig { returns(T::Boolean) } + def byebug?; end + + sig { returns(T.nilable(String)) } + def c; end + + sig { returns(T::Boolean) } + def cached?; end + + sig { returns(T::Boolean) } + def cask?; end + + sig { returns(T::Boolean) } + def casks?; end + + sig { returns(T.nilable(String)) } + def category; end + + sig { returns(T.nilable(String)) } + def cc; end + + sig { returns(T::Boolean) } + def changed?; end + + sig { returns(T::Boolean) } + def clean?; end + + sig { returns(T::Boolean) } + def closed?; end + + sig { returns(T::Boolean) } + def cmake?; end + + sig { returns(T.nilable(String)) } + def cmd; end + + sig { returns(T.nilable(String)) } + def colorpickerdir; end + + sig { returns(T.nilable(String)) } + def command; end + + sig { returns(T.nilable(String)) } + def commit; end + + sig { returns(T::Boolean) } + def commit?; end + + sig { returns(T.nilable(String)) } + def committer; end + + sig { returns(T::Boolean) } + def compact?; end + + sig { returns(T::Boolean) } + def coverage?; end + + sig { returns(T::Boolean) } + def crystal?; end + + sig { returns(T::Boolean) } + def csv?; end + + sig { returns(T::Boolean) } + def custom_remote?; end + + sig { returns(T::Boolean) } + def d?; end + + sig { returns(T.nilable(String)) } + def days; end + + sig { returns(T::Boolean) } + def debian?; end + + sig { returns(T::Boolean) } + def debug?; end + + sig { returns(T::Boolean) } + def debug_symbols?; end + + sig { returns(T::Boolean) } + def declared?; end + + sig { returns(T::Boolean) } + def dependents?; end + + sig { returns(T::Boolean) } + def deps?; end + + sig { returns(T::Boolean) } + def desc?; end + + sig { returns(T::Boolean) } + def description?; end + + sig { returns(T.nilable(String)) } + def destdir; end + + sig { returns(T.nilable(String)) } + def dictionarydir; end + + sig { returns(T.nilable(String)) } + def dir; end + + sig { returns(T::Boolean) } + def direct?; end + + sig { returns(T::Boolean) } + def display_cop_names?; end + + sig { returns(T::Boolean) } + def display_filename?; end + + sig { returns(T::Boolean) } + def display_times?; end + + sig { returns(T::Boolean) } + def dot?; end + + sig { returns(T::Boolean) } + def dry_run?; end + + sig { returns(T.nilable(String)) } + def e; end + + sig { returns(T.nilable(String)) } + def env; end + + sig { returns(T::Boolean) } + def eval_all?; end + + sig { returns(T::Boolean) } + def examples?; end + + sig { returns(T.nilable(T::Array[String])) } + def except; end + + sig { returns(T.nilable(T::Array[String])) } + def except_cops; end + + sig { returns(T.nilable(T::Array[String])) } + def exclude_packages; end + + sig { returns(T.nilable(T::Array[String])) } + def extra_packages; end + + sig { returns(T::Boolean) } + def f?; end + + sig { returns(T::Boolean) } + def fail_fast?; end + + sig { returns(T::Boolean) } + def fedora?; end + + sig { returns(T::Boolean) } + def fetch_HEAD?; end + + sig { returns(T.nilable(String)) } + def file; end + + sig { returns(T::Boolean) } + def fink?; end + + sig { returns(T::Boolean) } + def fix?; end + + sig { returns(T.nilable(String)) } + def fontdir; end + + sig { returns(T::Boolean) } + def for_each?; end + + sig { returns(T::Boolean) } + def force?; end + + sig { returns(T.nilable(String)) } + def force_auto_update?; end + + sig { returns(T::Boolean) } + def force_bottle?; end + + sig { returns(T::Boolean) } + def force_core_tap?; end + + sig { returns(T.nilable(String)) } + def fork_org; end + + sig { returns(T::Boolean) } + def formula?; end + + sig { returns(T::Boolean) } + def formulae?; end + + sig { returns(T.nilable(String)) } + def from; end + + sig { returns(T::Boolean) } + def full_name?; end + + sig { returns(T::Boolean) } + def g?; end + + sig { returns(T::Boolean) } + def generic?; end + + sig { returns(T::Boolean) } + def git?; end + + sig { returns(T::Boolean) } + def github?; end + + sig { returns(T::Boolean) } + def github_packages?; end + + sig { returns(T::Boolean) } + def github_packages_downloads?; end + + sig { returns(T::Boolean) } + def go?; end + + sig { returns(T::Boolean) } + def graph?; end + + sig { returns(T::Boolean) } + def greedy?; end + + sig { returns(T::Boolean) } + def greedy_auto_updates?; end + + sig { returns(T::Boolean) } + def greedy_latest?; end + + sig { returns(T.nilable(T::Array[String])) } + def groups; end + + sig { returns(T::Boolean) } + def h?; end + + sig { returns(T::Boolean) } + def help?; end + + sig { returns(T.nilable(T::Array[String])) } + def hide; end + + sig { returns(T::Boolean) } + def i?; end + + sig { returns(T.nilable(String)) } + def ignore; end + + sig { returns(T::Boolean) } + def ignore_dependencies?; end + + sig { returns(T::Boolean) } + def ignore_failures?; end + + sig { returns(T.nilable(T::Array[String])) } + def ignore_missing_artifacts; end + + sig { returns(T::Boolean) } + def ignore_non_pypi_packages?; end + + sig { returns(T::Boolean) } + def ignore_pinned?; end + + sig { returns(T::Boolean) } + def include_aliases?; end + + sig { returns(T::Boolean) } + def include_build?; end + + sig { returns(T::Boolean) } + def include_optional?; end + + sig { returns(T::Boolean) } + def include_requirements?; end + + sig { returns(T::Boolean) } + def include_test?; end + + sig { returns(T.nilable(String)) } + def input_methoddir; end + + sig { returns(T::Boolean) } + def install_dependencies?; end + + sig { returns(T::Boolean) } + def installed?; end + + sig { returns(T::Boolean) } + def installed_as_dependency?; end + + sig { returns(T::Boolean) } + def installed_on_request?; end + + sig { returns(T::Boolean) } + def interactive?; end + + sig { returns(T.nilable(String)) } + def internet_plugindir; end + + sig { returns(T.nilable(String)) } + def issue; end + + sig { returns(T.nilable(String)) } + def json; end + + sig { returns(T::Boolean) } + def json?; end + + sig { returns(T::Boolean) } + def keep_old?; end + + sig { returns(T::Boolean) } + def keep_tmp?; end + + sig { returns(T.nilable(String)) } + def keyboard_layoutdir; end + + sig { returns(T::Boolean) } + def l?; end + + sig { returns(T.nilable(T::Array[String])) } + def language; end + + sig { returns(T::Boolean) } + def large_runner?; end + + sig { returns(T.nilable(String)) } + def limit; end + + sig { returns(T::Boolean) } + def linux?; end + + sig { returns(T::Boolean) } + def linux_self_hosted?; end + + sig { returns(T::Boolean) } + def linux_wheezy?; end + + sig { returns(T::Boolean) } + def list_checks?; end + + sig { returns(T::Boolean) } + def lost?; end + + sig { returns(T.nilable(T::Array[String])) } + def macos; end + + sig { returns(T::Boolean) } + def macports?; end + + sig { returns(T::Boolean) } + def major?; end + + sig { returns(T.nilable(String)) } + def max_count; end + + sig { returns(T.nilable(String)) } + def mdimporterdir; end + + sig { returns(T::Boolean) } + def merge?; end + + sig { returns(T::Boolean) } + def meson?; end + + sig { returns(T.nilable(String)) } + def message; end + + sig { returns(T::Boolean) } + def minor?; end + + sig { returns(T.nilable(T::Array[String])) } + def mirror; end + + sig { returns(T::Boolean) } + def missing?; end + + sig { returns(T::Boolean) } + def multiple?; end + + sig { returns(T.nilable(String)) } + def n; end + + sig { returns(T::Boolean) } + def n?; end + + sig { returns(T::Boolean) } + def name?; end + + sig { returns(T::Boolean) } + def new?; end + + sig { returns(T::Boolean) } + def new_cask?; end + + sig { returns(T::Boolean) } + def new_formula?; end + + sig { returns(T::Boolean) } + def new_issue?; end + + sig { returns(T::Boolean) } + def newer_only?; end + + sig { returns(T::Boolean) } + def no_all_checks?; end + + sig { returns(T::Boolean) } + def no_audit?; end + + sig { returns(T::Boolean) } + def no_browse?; end + + sig { returns(T::Boolean) } + def no_cherry_pick?; end + + sig { returns(T::Boolean) } + def no_commit?; end + + sig { returns(T::Boolean) } + def no_fetch?; end + + sig { returns(T::Boolean) } + def no_fork?; end + + sig { returns(T::Boolean) } + def no_git?; end + + sig { returns(T::Boolean) } + def no_pull_requests?; end + + sig { returns(T::Boolean) } + def no_rebuild?; end + + sig { returns(T::Boolean) } + def no_simulate?; end + + sig { returns(T::Boolean) } + def no_style?; end + + sig { returns(T::Boolean) } + def no_upload?; end + + sig { returns(T::Boolean) } + def node?; end + + sig { returns(T::Boolean) } + def non_bundler_gems?; end + + sig { returns(T::Boolean) } + def oneline?; end + + sig { returns(T::Boolean) } + def online?; end + + sig { returns(T.nilable(T::Array[String])) } + def only; end + + sig { returns(T.nilable(T::Array[String])) } + def only_cops; end + + sig { returns(T::Boolean) } + def only_dependencies?; end + + sig { returns(T::Boolean) } + def only_json_tab?; end + + sig { returns(T::Boolean) } + def open?; end + + sig { returns(T::Boolean) } + def open_pr?; end + + sig { returns(T::Boolean) } + def opensuse?; end + + sig { returns(T.nilable(String)) } + def os; end + + sig { returns(T::Boolean) } + def overwrite?; end + + sig { returns(T::Boolean) } + def p?; end + + sig { returns(T.nilable(String)) } + def package_name; end + + sig { returns(T::Boolean) } + def patch?; end + + sig { returns(T::Boolean) } + def perl?; end + + sig { returns(T::Boolean) } + def pinned?; end + + sig { returns(T::Boolean) } + def plain?; end + + sig { returns(T.nilable(String)) } + def prefpanedir; end + + sig { returns(T::Boolean) } + def preinstall?; end + + sig { returns(T::Boolean) } + def print_only?; end + + sig { returns(T::Boolean) } + def print_path?; end + + sig { returns(T::Boolean) } + def private?; end + + sig { returns(T.nilable(String)) } + def profile; end + + sig { returns(T.nilable(String)) } + def prune; end + + sig { returns(T::Boolean) } + def prune_prefix?; end + + sig { returns(T::Boolean) } + def pry?; end + + sig { returns(T::Boolean) } + def publish?; end + + sig { returns(T.nilable(String)) } + def pull_label; end + + sig { returns(T::Boolean) } + def pull_request?; end + + sig { returns(T::Boolean) } + def python?; end + + sig { returns(T.nilable(T::Array[String])) } + def python_exclude_packages; end + + sig { returns(T.nilable(T::Array[String])) } + def python_extra_packages; end + + sig { returns(T.nilable(String)) } + def python_package_name; end + + sig { returns(T::Boolean) } + def q?; end + + sig { returns(T.nilable(String)) } + def qlplugindir; end + + sig { returns(T::Boolean) } + def quarantine?; end + + sig { returns(T::Boolean) } + def quiet?; end + + sig { returns(T.nilable(String)) } + def r; end + + sig { returns(T::Boolean) } + def r?; end + + sig { returns(T::Boolean) } + def recursive?; end + + sig { returns(T::Boolean) } + def remove_bottle_block?; end + + sig { returns(T::Boolean) } + def repair?; end + + sig { returns(T::Boolean) } + def repology?; end + + sig { returns(T.nilable(T::Array[String])) } + def repositories; end + + sig { returns(T::Boolean) } + def require_sha?; end + + sig { returns(T::Boolean) } + def reset_cache?; end + + sig { returns(T::Boolean) } + def resolve?; end + + sig { returns(T::Boolean) } + def resources?; end + + sig { returns(T::Boolean) } + def retain_bottle_dir?; end + + sig { returns(T::Boolean) } + def retry?; end + + sig { returns(T::Boolean) } + def reverse?; end + + sig { returns(T.nilable(String)) } + def revision; end + + sig { returns(T.nilable(String)) } + def root_url; end + + sig { returns(T.nilable(String)) } + def root_url_using; end + + sig { returns(T::Boolean) } + def ruby?; end + + sig { returns(T::Boolean) } + def rust?; end + + sig { returns(T::Boolean) } + def s?; end + + sig { returns(T.nilable(String)) } + def screen_saverdir; end + + sig { returns(T::Boolean) } + def search?; end + + sig { returns(T.nilable(String)) } + def seed; end + + sig { returns(T.nilable(String)) } + def servicedir; end + + sig { returns(T.nilable(String)) } + def set_license; end + + sig { returns(T.nilable(String)) } + def set_name; end + + sig { returns(T.nilable(String)) } + def set_version; end + + sig { returns(T.nilable(String)) } + def sha256; end + + sig { returns(T.nilable(String)) } + def shell; end + + sig { returns(T.nilable(String)) } + def signing?; end + + sig { returns(T::Boolean) } + def silent?; end + + sig { returns(T::Boolean) } + def skip_cask_deps?; end + + sig { returns(T::Boolean) } + def skip_post_install?; end + + sig { returns(T::Boolean) } + def skip_recommended?; end + + sig { returns(T::Boolean) } + def skip_relocation?; end + + sig { returns(T::Boolean) } + def skip_style?; end + + sig { returns(T::Boolean) } + def stackprof?; end + + sig { returns(T.nilable(String)) } + def start_with; end + + sig { returns(T::Boolean) } + def stat?; end + + sig { returns(T.nilable(String)) } + def state_file; end + + sig { returns(T::Boolean) } + def strict?; end + + sig { returns(T::Boolean) } + def suggest_typed?; end + + sig { returns(T::Boolean) } + def syntax?; end + + sig { returns(T::Boolean) } + def t?; end + + sig { returns(T.nilable(String)) } + def tag; end + + sig { returns(T.nilable(String)) } + def tap; end + + sig { returns(T::Boolean) } + def test?; end + + sig { returns(T.nilable(String)) } + def timeout; end + + sig { returns(T.nilable(String)) } + def to; end + + sig { returns(T::Boolean) } + def to_tag?; end + + sig { returns(T::Boolean) } + def token_conflicts?; end + + sig { returns(T::Boolean) } + def topological?; end + + sig { returns(T::Boolean) } + def total?; end + + sig { returns(T::Boolean) } + def tree?; end + + sig { returns(T::Boolean) } + def u?; end + + sig { returns(T::Boolean) } + def ubuntu?; end + + sig { returns(T::Boolean) } + def unbrewed?; end + + sig { returns(T::Boolean) } + def union?; end + + sig { returns(T.nilable(T::Array[String])) } + def update; end + + sig { returns(T::Boolean) } + def update?; end + + sig { returns(T::Boolean) } + def update_all?; end + + sig { returns(T::Boolean) } + def upload?; end + + sig { returns(T::Boolean) } + def upload_only?; end + + sig { returns(T.nilable(String)) } + def url; end + + sig { returns(T.nilable(T::Array[String])) } + def user; end + + sig { returns(T::Boolean) } + def v?; end + + sig { returns(T::Boolean) } + def variations?; end + + sig { returns(T::Boolean) } + def verbose?; end + + sig { returns(T.nilable(String)) } + def version; end + + sig { returns(T.nilable(String)) } + def version_arm; end + + sig { returns(T.nilable(String)) } + def version_intel; end + + sig { returns(T::Boolean) } + def versions?; end + + sig { returns(T.nilable(String)) } + def vst3_plugindir; end + + sig { returns(T.nilable(String)) } + def vst_plugindir; end + + sig { returns(T::Boolean) } + def warn_on_upload_failure?; end + + sig { returns(T::Boolean) } + def with_hostname?; end + + sig { returns(T.nilable(String)) } + def with_label; end + + sig { returns(T::Boolean) } + def without_approval?; end + + sig { returns(T.nilable(T::Array[String])) } + def without_labels; end + + sig { returns(T.nilable(String)) } + def workflow; end + + sig { returns(T.nilable(T::Array[String])) } + def workflows; end + + sig { returns(T::Boolean) } + def write?; end + + sig { returns(T::Boolean) } + def write_only?; end + + sig { returns(T::Boolean) } + def zap?; end +end diff --git a/Library/Homebrew/sorbet/rbi/gems/kramdown@2.4.0.rbi b/Library/Homebrew/sorbet/rbi/gems/kramdown@2.4.0.rbi new file mode 100644 index 00000000000000..9b2edd5252cb9b --- /dev/null +++ b/Library/Homebrew/sorbet/rbi/gems/kramdown@2.4.0.rbi @@ -0,0 +1,3271 @@ +# typed: true + +# DO NOT EDIT MANUALLY +# This is an autogenerated file for types exported from the `kramdown` gem. +# Please instead update this file by running `bin/tapioca gem kramdown`. + +# source://kramdown//lib/kramdown/version.rb#10 +module Kramdown + class << self + # Return the data directory for kramdown. + # + # source://kramdown//lib/kramdown/document.rb#49 + def data_dir; end + end +end + +# This module contains all available converters, i.e. classes that take a root Element and convert +# it to a specific output format. The result is normally a string. For example, the +# Converter::Html module converts an element tree into valid HTML. +# +# Converters use the Base class for common functionality (like applying a template to the output) +# \- see its API documentation for how to create a custom converter class. +# +# source://kramdown//lib/kramdown/converter.rb#20 +module Kramdown::Converter + extend ::Kramdown::Utils::Configurable + + class << self + # source://kramdown//lib/kramdown/utils/configurable.rb#37 + def add_math_engine(data, *args, &block); end + + # source://kramdown//lib/kramdown/utils/configurable.rb#37 + def add_syntax_highlighter(data, *args, &block); end + + # source://kramdown//lib/kramdown/utils/configurable.rb#30 + def configurables; end + + # source://kramdown//lib/kramdown/utils/configurable.rb#34 + def math_engine(data); end + + # source://kramdown//lib/kramdown/utils/configurable.rb#34 + def syntax_highlighter(data); end + end +end + +# == \Base class for converters +# +# This class serves as base class for all converters. It provides methods that can/should be +# used by all converters (like #generate_id) as well as common functionality that is +# automatically applied to the result (for example, embedding the output into a template). +# +# A converter object is used as a throw-away object, i.e. it is only used for storing the needed +# state information during conversion. Therefore one can't instantiate a converter object +# directly but only use the Base::convert method. +# +# == Implementing a converter +# +# Implementing a new converter is rather easy: just derive a new class from this class and put +# it in the Kramdown::Converter module (the latter is only needed if auto-detection should work +# properly). Then you need to implement the #convert method which has to contain the conversion +# code for converting an element and has to return the conversion result. +# +# The actual transformation of the document tree can be done in any way. However, writing one +# method per element type is a straight forward way to do it - this is how the Html and Latex +# converters do the transformation. +# +# Have a look at the Base::convert method for additional information! +# +# source://kramdown//lib/kramdown/converter/base.rb#40 +class Kramdown::Converter::Base + # Initialize the converter with the given +root+ element and +options+ hash. + # + # @return [Base] a new instance of Base + # + # source://kramdown//lib/kramdown/converter/base.rb#55 + def initialize(root, options); end + + # Returns whether the template should be applied after the conversion of the tree. + # + # Defaults to true. + # + # @return [Boolean] + # + # source://kramdown//lib/kramdown/converter/base.rb#73 + def apply_template_after?; end + + # Returns whether the template should be applied before the conversion of the tree. + # + # Defaults to false. + # + # @return [Boolean] + # + # source://kramdown//lib/kramdown/converter/base.rb#66 + def apply_template_before?; end + + # The basic version of the ID generator, without any special provisions for empty or unique + # IDs. + # + # source://kramdown//lib/kramdown/converter/base.rb#237 + def basic_generate_id(str); end + + # Convert the element +el+ and return the resulting object. + # + # This is the only method that has to be implemented by sub-classes! + # + # @raise [NotImplementedError] + # + # source://kramdown//lib/kramdown/converter/base.rb#122 + def convert(_el); end + + # Can be used by a converter for storing arbitrary information during the conversion process. + # + # source://kramdown//lib/kramdown/converter/base.rb#43 + def data; end + + # Extract the code block/span language from the attributes. + # + # source://kramdown//lib/kramdown/converter/base.rb#174 + def extract_code_language(attr); end + + # See #extract_code_language + # + # *Warning*: This version will modify the given attributes if a language is present. + # + # source://kramdown//lib/kramdown/converter/base.rb#183 + def extract_code_language!(attr); end + + # Format the given math element with the math engine configured through the option + # 'math_engine'. + # + # source://kramdown//lib/kramdown/converter/base.rb#206 + def format_math(el, opts = T.unsafe(nil)); end + + # Generate an unique alpha-numeric ID from the the string +str+ for use as a header ID. + # + # Uses the option +auto_id_prefix+: the value of this option is prepended to every generated + # ID. + # + # source://kramdown//lib/kramdown/converter/base.rb#222 + def generate_id(str); end + + # Highlight the given +text+ in the language +lang+ with the syntax highlighter configured + # through the option 'syntax_highlighter'. + # + # source://kramdown//lib/kramdown/converter/base.rb#192 + def highlight_code(text, lang, type, opts = T.unsafe(nil)); end + + # Return +true+ if the header element +el+ should be used for the table of contents (as + # specified by the +toc_levels+ option). + # + # @return [Boolean] + # + # source://kramdown//lib/kramdown/converter/base.rb#162 + def in_toc?(el); end + + # The hash with the conversion options. + # + # source://kramdown//lib/kramdown/converter/base.rb#46 + def options; end + + # Return the output header level given a level. + # + # Uses the +header_offset+ option for adjusting the header level. + # + # source://kramdown//lib/kramdown/converter/base.rb#169 + def output_header_level(level); end + + # The root element that is converted. + # + # source://kramdown//lib/kramdown/converter/base.rb#49 + def root; end + + # Return the entity that represents the given smart_quote element. + # + # source://kramdown//lib/kramdown/converter/base.rb#248 + def smart_quote_entity(el); end + + # Add the given warning +text+ to the warning array. + # + # source://kramdown//lib/kramdown/converter/base.rb#156 + def warning(text); end + + # The warnings array. + # + # source://kramdown//lib/kramdown/converter/base.rb#52 + def warnings; end + + class << self + # Apply the +template+ using +body+ as the body string. + # + # The template is evaluated using ERB and the body is available in the @body instance variable + # and the converter object in the @converter instance variable. + # + # source://kramdown//lib/kramdown/converter/base.rb#130 + def apply_template(converter, body); end + + # Convert the element tree +tree+ and return the resulting conversion object (normally a + # string) and an array with warning messages. The parameter +options+ specifies the conversion + # options that should be used. + # + # Initializes a new instance of the calling class and then calls the #convert method with + # +tree+ as parameter. + # + # If the +template+ option is specified and non-empty, the template is evaluate with ERB + # before and/or after the tree conversion depending on the result of #apply_template_before? + # and #apply_template_after?. If the template is evaluated before, an empty string is used for + # the body; if evaluated after, the result is used as body. See ::apply_template. + # + # The template resolution is done in the following way (for the converter ConverterName): + # + # 1. Look in the current working directory for the template. + # + # 2. Append +.converter_name+ (e.g. +.html+) to the template name and look for the resulting + # file in the current working directory (the form +.convertername+ is deprecated). + # + # 3. Append +.converter_name+ to the template name and look for it in the kramdown data + # directory (the form +.convertername+ is deprecated). + # + # 4. Check if the template name starts with 'string://' and if so, strip this prefix away and + # use the rest as template. + # + # source://kramdown//lib/kramdown/converter/base.rb#101 + def convert(tree, options = T.unsafe(nil)); end + + # Return the template specified by +template+. + # + # source://kramdown//lib/kramdown/converter/base.rb#139 + def get_template(template); end + + private + + def allocate; end + def new(*_arg0); end + end +end + +# source://kramdown//lib/kramdown/converter/base.rb#245 +Kramdown::Converter::Base::SMART_QUOTE_INDICES = T.let(T.unsafe(nil), Hash) + +# Converts a Kramdown::Document to a nested hash for further processing or debug output. +# +# source://kramdown//lib/kramdown/converter/hash_ast.rb#19 +class Kramdown::Converter::HashAST < ::Kramdown::Converter::Base + # source://kramdown//lib/kramdown/converter/hash_ast.rb#21 + def convert(el); end +end + +# source://kramdown//lib/kramdown/converter/hash_ast.rb#35 +Kramdown::Converter::HashAst = Kramdown::Converter::HashAST + +# Converts a Kramdown::Document to HTML. +# +# You can customize the HTML converter by sub-classing it and overriding the +convert_NAME+ +# methods. Each such method takes the following parameters: +# +# [+el+] The element of type +NAME+ to be converted. +# +# [+indent+] A number representing the current amount of spaces for indent (only used for +# block-level elements). +# +# The return value of such a method has to be a string containing the element +el+ formatted as +# HTML element. +# +# source://kramdown//lib/kramdown/converter/html.rb#30 +class Kramdown::Converter::Html < ::Kramdown::Converter::Base + include ::Kramdown::Utils::Html + include ::Kramdown::Parser::Html::Constants + + # Initialize the HTML converter with the given Kramdown document +doc+. + # + # @return [Html] a new instance of Html + # + # source://kramdown//lib/kramdown/converter/html.rb#39 + def initialize(root, options); end + + # Add the syntax highlighter name to the 'class' attribute of the given attribute hash. And + # overwrites or add a "language-LANG" part using the +lang+ parameter if +lang+ is not nil. + # + # source://kramdown//lib/kramdown/converter/html.rb#409 + def add_syntax_highlighter_to_class_attr(attr, lang = T.unsafe(nil)); end + + # Dispatch the conversion of the element +el+ to a +convert_TYPE+ method using the +type+ of + # the element. + # + # source://kramdown//lib/kramdown/converter/html.rb#57 + def convert(el, indent = T.unsafe(nil)); end + + # source://kramdown//lib/kramdown/converter/html.rb#272 + def convert_a(el, indent); end + + # source://kramdown//lib/kramdown/converter/html.rb#365 + def convert_abbreviation(el, _indent); end + + # source://kramdown//lib/kramdown/converter/html.rb#77 + def convert_blank(_el, _indent); end + + # source://kramdown//lib/kramdown/converter/html.rb#141 + def convert_blockquote(el, indent); end + + # source://kramdown//lib/kramdown/converter/html.rb#268 + def convert_br(_el, _indent); end + + # source://kramdown//lib/kramdown/converter/html.rb#111 + def convert_codeblock(el, indent); end + + # source://kramdown//lib/kramdown/converter/html.rb#280 + def convert_codespan(el, _indent); end + + # source://kramdown//lib/kramdown/converter/html.rb#260 + def convert_comment(el, indent); end + + # source://kramdown//lib/kramdown/converter/html.rb#178 + def convert_dd(el, indent); end + + # source://kramdown//lib/kramdown/converter/html.rb#174 + def convert_dl(el, indent); end + + # source://kramdown//lib/kramdown/converter/html.rb#190 + def convert_dt(el, indent); end + + # source://kramdown//lib/kramdown/converter/html.rb#319 + def convert_em(el, indent); end + + # source://kramdown//lib/kramdown/converter/html.rb#324 + def convert_entity(el, _indent); end + + # source://kramdown//lib/kramdown/converter/html.rb#294 + def convert_footnote(el, _indent); end + + # source://kramdown//lib/kramdown/converter/html.rb#145 + def convert_header(el, indent); end + + # source://kramdown//lib/kramdown/converter/html.rb#155 + def convert_hr(el, indent); end + + # source://kramdown//lib/kramdown/converter/html.rb#201 + def convert_html_element(el, indent); end + + # source://kramdown//lib/kramdown/converter/html.rb#276 + def convert_img(el, _indent); end + + # source://kramdown//lib/kramdown/converter/html.rb#178 + def convert_li(el, indent); end + + # source://kramdown//lib/kramdown/converter/html.rb#351 + def convert_math(el, indent); end + + # source://kramdown//lib/kramdown/converter/html.rb#162 + def convert_ol(el, indent); end + + # source://kramdown//lib/kramdown/converter/html.rb#86 + def convert_p(el, indent); end + + # source://kramdown//lib/kramdown/converter/html.rb#311 + def convert_raw(el, _indent); end + + # source://kramdown//lib/kramdown/converter/html.rb#372 + def convert_root(el, indent); end + + # source://kramdown//lib/kramdown/converter/html.rb#347 + def convert_smart_quote(el, _indent); end + + # Helper method used by +convert_p+ to convert a paragraph that only contains a single :img + # element. + # + # source://kramdown//lib/kramdown/converter/html.rb#99 + def convert_standalone_image(el, indent); end + + # source://kramdown//lib/kramdown/converter/html.rb#319 + def convert_strong(el, indent); end + + # source://kramdown//lib/kramdown/converter/html.rb#238 + def convert_table(el, indent); end + + # source://kramdown//lib/kramdown/converter/html.rb#238 + def convert_tbody(el, indent); end + + # source://kramdown//lib/kramdown/converter/html.rb#248 + def convert_td(el, indent); end + + # source://kramdown//lib/kramdown/converter/html.rb#81 + def convert_text(el, _indent); end + + # source://kramdown//lib/kramdown/converter/html.rb#238 + def convert_tfoot(el, indent); end + + # source://kramdown//lib/kramdown/converter/html.rb#238 + def convert_thead(el, indent); end + + # source://kramdown//lib/kramdown/converter/html.rb#238 + def convert_tr(el, indent); end + + # source://kramdown//lib/kramdown/converter/html.rb#339 + def convert_typographic_sym(el, _indent); end + + # source://kramdown//lib/kramdown/converter/html.rb#162 + def convert_ul(el, indent); end + + # source://kramdown//lib/kramdown/converter/html.rb#228 + def convert_xml_comment(el, indent); end + + # source://kramdown//lib/kramdown/converter/html.rb#228 + def convert_xml_pi(el, indent); end + + # Fixes the elements for use in a TOC entry. + # + # source://kramdown//lib/kramdown/converter/html.rb#453 + def fix_for_toc_entry(elements); end + + # Return an HTML ordered list with the footnote content for the used footnotes. + # + # source://kramdown//lib/kramdown/converter/html.rb#488 + def footnote_content; end + + # Format the given element as block HTML. + # + # source://kramdown//lib/kramdown/converter/html.rb#397 + def format_as_block_html(name, attr, body, indent); end + + # Format the given element as block HTML with a newline after the start tag and indentation + # before the end tag. + # + # source://kramdown//lib/kramdown/converter/html.rb#403 + def format_as_indented_block_html(name, attr, body, indent); end + + # Format the given element as span HTML. + # + # source://kramdown//lib/kramdown/converter/html.rb#392 + def format_as_span_html(name, attr, body); end + + # Generate and return an element tree for the table of contents. + # + # source://kramdown//lib/kramdown/converter/html.rb#415 + def generate_toc_tree(toc, type, attr); end + + # The amount of indentation used when nesting HTML tags. + # + # source://kramdown//lib/kramdown/converter/html.rb#36 + def indent; end + + # The amount of indentation used when nesting HTML tags. + # + # source://kramdown//lib/kramdown/converter/html.rb#36 + def indent=(_arg0); end + + # Return the converted content of the children of +el+ as a string. The parameter +indent+ has + # to be the amount of indentation used for the element +el+. + # + # Pushes +el+ onto the @stack before converting the child elements and pops it from the stack + # afterwards. + # + # source://kramdown//lib/kramdown/converter/html.rb#66 + def inner(el, indent); end + + # Obfuscate the +text+ by using HTML entities. + # + # source://kramdown//lib/kramdown/converter/html.rb#476 + def obfuscate(text); end + + # Remove all footnotes from the given elements. + # + # source://kramdown//lib/kramdown/converter/html.rb#468 + def remove_footnotes(elements); end + + # Remove all link elements by unwrapping them. + # + # source://kramdown//lib/kramdown/converter/html.rb#460 + def unwrap_links(elements); end +end + +# source://kramdown//lib/kramdown/converter/html.rb#246 +Kramdown::Converter::Html::ENTITY_NBSP = T.let(T.unsafe(nil), Kramdown::Utils::Entities::Entity) + +# source://kramdown//lib/kramdown/converter/html.rb#485 +Kramdown::Converter::Html::FOOTNOTE_BACKLINK_FMT = T.let(T.unsafe(nil), String) + +# source://kramdown//lib/kramdown/converter/html.rb#328 +Kramdown::Converter::Html::TYPOGRAPHIC_SYMS = T.let(T.unsafe(nil), Hash) + +# source://kramdown//lib/kramdown/converter/html.rb#159 +Kramdown::Converter::Html::ZERO_TO_ONETWENTYEIGHT = T.let(T.unsafe(nil), Array) + +# Converts an element tree to the kramdown format. +# +# source://kramdown//lib/kramdown/converter/kramdown.rb#18 +class Kramdown::Converter::Kramdown < ::Kramdown::Converter::Base + include ::Kramdown::Utils::Html + + # @return [Kramdown] a new instance of Kramdown + # + # source://kramdown//lib/kramdown/converter/kramdown.rb#24 + def initialize(root, options); end + + # source://kramdown//lib/kramdown/converter/kramdown.rb#34 + def convert(el, opts = T.unsafe(nil)); end + + # source://kramdown//lib/kramdown/converter/kramdown.rb#291 + def convert_a(el, opts); end + + # source://kramdown//lib/kramdown/converter/kramdown.rb#377 + def convert_abbreviation(el, _opts); end + + # source://kramdown//lib/kramdown/converter/kramdown.rb#70 + def convert_blank(_el, _opts); end + + # source://kramdown//lib/kramdown/converter/kramdown.rb#107 + def convert_blockquote(el, opts); end + + # source://kramdown//lib/kramdown/converter/kramdown.rb#287 + def convert_br(_el, _opts); end + + # source://kramdown//lib/kramdown/converter/kramdown.rb#103 + def convert_codeblock(el, _opts); end + + # source://kramdown//lib/kramdown/converter/kramdown.rb#324 + def convert_codespan(el, _opts); end + + # source://kramdown//lib/kramdown/converter/kramdown.rb#279 + def convert_comment(el, _opts); end + + # source://kramdown//lib/kramdown/converter/kramdown.rb#158 + def convert_dd(el, opts); end + + # source://kramdown//lib/kramdown/converter/kramdown.rb#124 + def convert_dl(el, opts); end + + # source://kramdown//lib/kramdown/converter/kramdown.rb#182 + def convert_dt(el, opts); end + + # source://kramdown//lib/kramdown/converter/kramdown.rb#346 + def convert_em(el, opts); end + + # source://kramdown//lib/kramdown/converter/kramdown.rb#356 + def convert_entity(el, _opts); end + + # source://kramdown//lib/kramdown/converter/kramdown.rb#329 + def convert_footnote(el, _opts); end + + # source://kramdown//lib/kramdown/converter/kramdown.rb#112 + def convert_header(el, opts); end + + # source://kramdown//lib/kramdown/converter/kramdown.rb#120 + def convert_hr(_el, _opts); end + + # source://kramdown//lib/kramdown/converter/kramdown.rb#195 + def convert_html_element(el, opts); end + + # source://kramdown//lib/kramdown/converter/kramdown.rb#308 + def convert_img(el, _opts); end + + # source://kramdown//lib/kramdown/converter/kramdown.rb#130 + def convert_li(el, opts); end + + # source://kramdown//lib/kramdown/converter/kramdown.rb#373 + def convert_math(el, _opts); end + + # source://kramdown//lib/kramdown/converter/kramdown.rb#124 + def convert_ol(el, opts); end + + # source://kramdown//lib/kramdown/converter/kramdown.rb#88 + def convert_p(el, opts); end + + # source://kramdown//lib/kramdown/converter/kramdown.rb#334 + def convert_raw(el, _opts); end + + # source://kramdown//lib/kramdown/converter/kramdown.rb#381 + def convert_root(el, opts); end + + # source://kramdown//lib/kramdown/converter/kramdown.rb#369 + def convert_smart_quote(el, _opts); end + + # source://kramdown//lib/kramdown/converter/kramdown.rb#351 + def convert_strong(el, opts); end + + # source://kramdown//lib/kramdown/converter/kramdown.rb#239 + def convert_table(el, opts); end + + # source://kramdown//lib/kramdown/converter/kramdown.rb#260 + def convert_tbody(el, opts); end + + # source://kramdown//lib/kramdown/converter/kramdown.rb#275 + def convert_td(el, opts); end + + # source://kramdown//lib/kramdown/converter/kramdown.rb#76 + def convert_text(el, opts); end + + # source://kramdown//lib/kramdown/converter/kramdown.rb#267 + def convert_tfoot(el, opts); end + + # source://kramdown//lib/kramdown/converter/kramdown.rb#244 + def convert_thead(el, opts); end + + # source://kramdown//lib/kramdown/converter/kramdown.rb#271 + def convert_tr(el, opts); end + + # source://kramdown//lib/kramdown/converter/kramdown.rb#365 + def convert_typographic_sym(el, _opts); end + + # source://kramdown//lib/kramdown/converter/kramdown.rb#124 + def convert_ul(el, opts); end + + # source://kramdown//lib/kramdown/converter/kramdown.rb#229 + def convert_xml_comment(el, _opts); end + + # source://kramdown//lib/kramdown/converter/kramdown.rb#229 + def convert_xml_pi(el, _opts); end + + # source://kramdown//lib/kramdown/converter/kramdown.rb#408 + def create_abbrev_defs; end + + # source://kramdown//lib/kramdown/converter/kramdown.rb#399 + def create_footnote_defs; end + + # source://kramdown//lib/kramdown/converter/kramdown.rb#389 + def create_link_defs; end + + # Return the IAL containing the attributes of the element +el+. + # + # source://kramdown//lib/kramdown/converter/kramdown.rb#419 + def ial_for_element(el); end + + # source://kramdown//lib/kramdown/converter/kramdown.rb#54 + def inner(el, opts = T.unsafe(nil)); end + + # source://kramdown//lib/kramdown/converter/kramdown.rb#444 + def parse_title(attr); end +end + +# source://kramdown//lib/kramdown/converter/kramdown.rb#74 +Kramdown::Converter::Kramdown::ESCAPED_CHAR_RE = T.let(T.unsafe(nil), Regexp) + +# source://kramdown//lib/kramdown/converter/kramdown.rb#192 +Kramdown::Converter::Kramdown::HTML_ELEMENT_TYPES = T.let(T.unsafe(nil), Array) + +# source://kramdown//lib/kramdown/converter/kramdown.rb#190 +Kramdown::Converter::Kramdown::HTML_TAGS_WITH_BODY = T.let(T.unsafe(nil), Array) + +# source://kramdown//lib/kramdown/converter/kramdown.rb#360 +Kramdown::Converter::Kramdown::TYPOGRAPHIC_SYMS = T.let(T.unsafe(nil), Hash) + +# Converts an element tree to LaTeX. +# +# This converter uses ideas from other Markdown-to-LaTeX converters like Pandoc and Maruku. +# +# You can customize this converter by sub-classing it and overriding the +convert_NAME+ methods. +# Each such method takes the following parameters: +# +# [+el+] The element of type +NAME+ to be converted. +# +# [+opts+] A hash containing processing options that are passed down from parent elements. The +# key :parent is always set and contains the parent element as value. +# +# The return value of such a method has to be a string containing the element +el+ formatted +# correctly as LaTeX markup. +# +# source://kramdown//lib/kramdown/converter/latex.rb#31 +class Kramdown::Converter::Latex < ::Kramdown::Converter::Base + # Initialize the LaTeX converter with the +root+ element and the conversion +options+. + # + # @return [Latex] a new instance of Latex + # + # source://kramdown//lib/kramdown/converter/latex.rb#34 + def initialize(root, options); end + + # Return a LaTeX comment containing all attributes as 'key="value"' pairs. + # + # source://kramdown//lib/kramdown/converter/latex.rb#599 + def attribute_list(el); end + + # Dispatch the conversion of the element +el+ to a +convert_TYPE+ method using the +type+ of + # the element. + # + # source://kramdown//lib/kramdown/converter/latex.rb#41 + def convert(el, opts = T.unsafe(nil)); end + + # source://kramdown//lib/kramdown/converter/latex.rb#216 + def convert_a(el, opts); end + + # source://kramdown//lib/kramdown/converter/latex.rb#569 + def convert_abbreviation(el, _opts); end + + # source://kramdown//lib/kramdown/converter/latex.rb#61 + def convert_blank(_el, opts); end + + # source://kramdown//lib/kramdown/converter/latex.rb#110 + def convert_blockquote(el, opts); end + + # source://kramdown//lib/kramdown/converter/latex.rb#209 + def convert_br(_el, opts); end + + # source://kramdown//lib/kramdown/converter/latex.rb#87 + def convert_codeblock(el, _opts); end + + # source://kramdown//lib/kramdown/converter/latex.rb#239 + def convert_codespan(el, _opts); end + + # source://kramdown//lib/kramdown/converter/latex.rb#205 + def convert_comment(el, _opts); end + + # source://kramdown//lib/kramdown/converter/latex.rb#151 + def convert_dd(el, opts); end + + # source://kramdown//lib/kramdown/converter/latex.rb#139 + def convert_dl(el, opts); end + + # source://kramdown//lib/kramdown/converter/latex.rb#147 + def convert_dt(el, opts); end + + # source://kramdown//lib/kramdown/converter/latex.rb#263 + def convert_em(el, opts); end + + # source://kramdown//lib/kramdown/converter/latex.rb#533 + def convert_entity(el, _opts); end + + # source://kramdown//lib/kramdown/converter/latex.rb#250 + def convert_footnote(el, opts); end + + # source://kramdown//lib/kramdown/converter/latex.rb#114 + def convert_header(el, opts); end + + # source://kramdown//lib/kramdown/converter/latex.rb#124 + def convert_hr(el, _opts); end + + # source://kramdown//lib/kramdown/converter/latex.rb#155 + def convert_html_element(el, opts); end + + # source://kramdown//lib/kramdown/converter/latex.rb#225 + def convert_img(el, _opts); end + + # source://kramdown//lib/kramdown/converter/latex.rb#143 + def convert_li(el, opts); end + + # source://kramdown//lib/kramdown/converter/latex.rb#556 + def convert_math(el, _opts); end + + # source://kramdown//lib/kramdown/converter/latex.rb#129 + def convert_ol(el, opts); end + + # source://kramdown//lib/kramdown/converter/latex.rb#69 + def convert_p(el, opts); end + + # source://kramdown//lib/kramdown/converter/latex.rb#255 + def convert_raw(el, _opts); end + + # source://kramdown//lib/kramdown/converter/latex.rb#57 + def convert_root(el, opts); end + + # source://kramdown//lib/kramdown/converter/latex.rb#550 + def convert_smart_quote(el, opts); end + + # Helper method used by +convert_p+ to convert a paragraph that only contains a single :img + # element. + # + # source://kramdown//lib/kramdown/converter/latex.rb#80 + def convert_standalone_image(el, _opts, img); end + + # source://kramdown//lib/kramdown/converter/latex.rb#267 + def convert_strong(el, opts); end + + # source://kramdown//lib/kramdown/converter/latex.rb#177 + def convert_table(el, opts); end + + # source://kramdown//lib/kramdown/converter/latex.rb#189 + def convert_tbody(el, opts); end + + # source://kramdown//lib/kramdown/converter/latex.rb#201 + def convert_td(el, opts); end + + # source://kramdown//lib/kramdown/converter/latex.rb#65 + def convert_text(el, _opts); end + + # source://kramdown//lib/kramdown/converter/latex.rb#193 + def convert_tfoot(el, opts); end + + # source://kramdown//lib/kramdown/converter/latex.rb#185 + def convert_thead(el, opts); end + + # source://kramdown//lib/kramdown/converter/latex.rb#197 + def convert_tr(el, opts); end + + # source://kramdown//lib/kramdown/converter/latex.rb#542 + def convert_typographic_sym(el, _opts); end + + # source://kramdown//lib/kramdown/converter/latex.rb#129 + def convert_ul(el, opts); end + + # source://kramdown//lib/kramdown/converter/latex.rb#166 + def convert_xml_comment(el, _opts); end + + # source://kramdown//lib/kramdown/converter/latex.rb#170 + def convert_xml_pi(_el, _opts); end + + # source://kramdown//lib/kramdown/converter/latex.rb#522 + def entity_to_latex(entity); end + + # Escape the special LaTeX characters in the string +str+. + # + # source://kramdown//lib/kramdown/converter/latex.rb#618 + def escape(str); end + + # Return the converted content of the children of +el+ as a string. + # + # source://kramdown//lib/kramdown/converter/latex.rb#46 + def inner(el, opts); end + + # Wrap the +text+ inside a LaTeX environment of type +type+. The element +el+ is passed on to + # the method #attribute_list -- the resulting string is appended to both the \\begin and the + # \\end lines of the LaTeX environment for easier post-processing of LaTeX environments. + # + # source://kramdown//lib/kramdown/converter/latex.rb#582 + def latex_environment(type, el, text); end + + # Return a string containing a valid \hypertarget command if the element has an ID defined, or + # +nil+ otherwise. If the parameter +add_label+ is +true+, a \label command will also be used + # additionally to the \hypertarget command. + # + # source://kramdown//lib/kramdown/converter/latex.rb#590 + def latex_link_target(el, add_label = T.unsafe(nil)); end + + # Normalize the abbreviation key so that it only contains allowed ASCII character + # + # source://kramdown//lib/kramdown/converter/latex.rb#575 + def normalize_abbreviation_key(key); end +end + +# Inspired by Maruku: entity conversion table based on the one from htmltolatex +# (http://sourceforge.net/projects/htmltolatex/), with some small adjustments/additions +# +# source://kramdown//lib/kramdown/converter/latex.rb#273 +Kramdown::Converter::Latex::ENTITY_CONV_TABLE = T.let(T.unsafe(nil), Hash) + +# source://kramdown//lib/kramdown/converter/latex.rb#605 +Kramdown::Converter::Latex::ESCAPE_MAP = T.let(T.unsafe(nil), Hash) + +# source://kramdown//lib/kramdown/converter/latex.rb#615 +Kramdown::Converter::Latex::ESCAPE_RE = T.let(T.unsafe(nil), Regexp) + +# source://kramdown//lib/kramdown/converter/latex.rb#175 +Kramdown::Converter::Latex::TABLE_ALIGNMENT_CHAR = T.let(T.unsafe(nil), Hash) + +# source://kramdown//lib/kramdown/converter/latex.rb#537 +Kramdown::Converter::Latex::TYPOGRAPHIC_SYMS = T.let(T.unsafe(nil), Hash) + +# Converts a Kramdown::Document to a manpage in groff format. See man(7), groff_man(7) and +# man-pages(7) for information regarding the output. +# +# source://kramdown//lib/kramdown/converter/man.rb#18 +class Kramdown::Converter::Man < ::Kramdown::Converter::Base + # source://kramdown//lib/kramdown/converter/man.rb#20 + def convert(el, opts = T.unsafe(nil)); end + + private + + # source://kramdown//lib/kramdown/converter/man.rb#191 + def convert_a(el, opts); end + + # source://kramdown//lib/kramdown/converter/man.rb#229 + def convert_abbreviation(el, opts); end + + # source://kramdown//lib/kramdown/converter/man.rb#47 + def convert_blank(*_arg0); end + + # source://kramdown//lib/kramdown/converter/man.rb#95 + def convert_blockquote(el, opts); end + + # source://kramdown//lib/kramdown/converter/man.rb#225 + def convert_br(_el, opts); end + + # source://kramdown//lib/kramdown/converter/man.rb#89 + def convert_codeblock(el, opts); end + + # source://kramdown//lib/kramdown/converter/man.rb#221 + def convert_codespan(el, opts); end + + # source://kramdown//lib/kramdown/converter/man.rb#186 + def convert_comment(el, opts); end + + # source://kramdown//lib/kramdown/converter/man.rb#127 + def convert_dd(el, opts); end + + # source://kramdown//lib/kramdown/converter/man.rb#101 + def convert_dl(el, opts); end + + # source://kramdown//lib/kramdown/converter/man.rb#121 + def convert_dt(el, opts); end + + # source://kramdown//lib/kramdown/converter/man.rb#209 + def convert_em(el, opts); end + + # source://kramdown//lib/kramdown/converter/man.rb#255 + def convert_entity(el, opts); end + + # source://kramdown//lib/kramdown/converter/man.rb#241 + def convert_footnote(*_arg0); end + + # source://kramdown//lib/kramdown/converter/man.rb#61 + def convert_header(el, opts); end + + # source://kramdown//lib/kramdown/converter/man.rb#47 + def convert_hr(*_arg0); end + + # source://kramdown//lib/kramdown/converter/man.rb#182 + def convert_html_element(*_arg0); end + + # source://kramdown//lib/kramdown/converter/man.rb#205 + def convert_img(_el, _opts); end + + # source://kramdown//lib/kramdown/converter/man.rb#110 + def convert_li(el, opts); end + + # source://kramdown//lib/kramdown/converter/man.rb#233 + def convert_math(el, opts); end + + # source://kramdown//lib/kramdown/converter/man.rb#101 + def convert_ol(el, opts); end + + # source://kramdown//lib/kramdown/converter/man.rb#52 + def convert_p(el, opts); end + + # source://kramdown//lib/kramdown/converter/man.rb#245 + def convert_raw(*_arg0); end + + # source://kramdown//lib/kramdown/converter/man.rb#40 + def convert_root(el, opts); end + + # source://kramdown//lib/kramdown/converter/man.rb#259 + def convert_smart_quote(el, opts); end + + # source://kramdown//lib/kramdown/converter/man.rb#215 + def convert_strong(el, opts); end + + # source://kramdown//lib/kramdown/converter/man.rb#139 + def convert_table(el, opts); end + + # source://kramdown//lib/kramdown/converter/man.rb#154 + def convert_tbody(el, opts); end + + # source://kramdown//lib/kramdown/converter/man.rb#170 + def convert_td(el, opts); end + + # source://kramdown//lib/kramdown/converter/man.rb#249 + def convert_text(el, opts); end + + # source://kramdown//lib/kramdown/converter/man.rb#161 + def convert_tfoot(el, opts); end + + # source://kramdown//lib/kramdown/converter/man.rb#148 + def convert_thead(el, opts); end + + # source://kramdown//lib/kramdown/converter/man.rb#165 + def convert_tr(el, opts); end + + # source://kramdown//lib/kramdown/converter/man.rb#268 + def convert_typographic_sym(el, opts); end + + # source://kramdown//lib/kramdown/converter/man.rb#101 + def convert_ul(el, opts); end + + # source://kramdown//lib/kramdown/converter/man.rb#186 + def convert_xml_comment(el, opts); end + + # source://kramdown//lib/kramdown/converter/man.rb#47 + def convert_xml_pi(*_arg0); end + + # source://kramdown//lib/kramdown/converter/man.rb#285 + def escape(text, preserve_whitespace = T.unsafe(nil)); end + + # source://kramdown//lib/kramdown/converter/man.rb#26 + def inner(el, opts, use = T.unsafe(nil)); end + + # source://kramdown//lib/kramdown/converter/man.rb#272 + def macro(name, *args); end + + # source://kramdown//lib/kramdown/converter/man.rb#276 + def newline(text); end + + # source://kramdown//lib/kramdown/converter/man.rb#281 + def quote(text); end + + # source://kramdown//lib/kramdown/converter/man.rb#293 + def unicode_char(codepoint); end +end + +# source://kramdown//lib/kramdown/converter/man.rb#137 +Kramdown::Converter::Man::TABLE_CELL_ALIGNMENT = T.let(T.unsafe(nil), Hash) + +# source://kramdown//lib/kramdown/converter/man.rb#263 +Kramdown::Converter::Man::TYPOGRAPHIC_SYMS_MAP = T.let(T.unsafe(nil), Hash) + +# Removes all block (and optionally span) level HTML tags from the element tree. +# +# This converter can be used on parsed HTML documents to get an element tree that will only +# contain native kramdown elements. +# +# *Note* that the returned element tree may not be fully conformant (i.e. the content models of +# *some elements may be violated)! +# +# This converter modifies the given tree in-place and returns it. +# +# source://kramdown//lib/kramdown/converter/remove_html_tags.rb#25 +class Kramdown::Converter::RemoveHtmlTags < ::Kramdown::Converter::Base + # @return [RemoveHtmlTags] a new instance of RemoveHtmlTags + # + # source://kramdown//lib/kramdown/converter/remove_html_tags.rb#27 + def initialize(root, options); end + + # source://kramdown//lib/kramdown/converter/remove_html_tags.rb#32 + def convert(el); end +end + +# Converts a Kramdown::Document to an element tree that represents the table of contents. +# +# The returned tree consists of Element objects of type :toc where the root element is just used +# as container object. Each :toc element contains as value the wrapped :header element and under +# the attribute key :id the header ID that should be used (note that this ID may not exist in +# the wrapped element). +# +# Since the TOC tree consists of special :toc elements, one cannot directly feed this tree to +# other converters! +# +# source://kramdown//lib/kramdown/converter/toc.rb#25 +class Kramdown::Converter::Toc < ::Kramdown::Converter::Base + # @return [Toc] a new instance of Toc + # + # source://kramdown//lib/kramdown/converter/toc.rb#27 + def initialize(root, options); end + + # source://kramdown//lib/kramdown/converter/toc.rb#34 + def convert(el); end + + private + + # source://kramdown//lib/kramdown/converter/toc.rb#47 + def add_to_toc(el, id); end +end + +# The main interface to kramdown. +# +# This class provides a one-stop-shop for using kramdown to convert text into various output +# formats. Use it like this: +# +# require 'kramdown' +# doc = Kramdown::Document.new('This *is* some kramdown text') +# puts doc.to_html +# +# The #to_html method is a shortcut for using the Converter::Html class. See #method_missing for +# more information. +# +# The second argument to the ::new method is an options hash for customizing the behaviour of the +# used parser and the converter. See ::new for more information! +# +# source://kramdown//lib/kramdown/document.rb#73 +class Kramdown::Document + # Create a new Kramdown document from the string +source+ and use the provided +options+. The + # options that can be used are defined in the Options module. + # + # The special options key :input can be used to select the parser that should parse the + # +source+. It has to be the name of a class in the Kramdown::Parser module. For example, to + # select the kramdown parser, one would set the :input key to +Kramdown+. If this key is not + # set, it defaults to +Kramdown+. + # + # The +source+ is immediately parsed by the selected parser so that the root element is + # immediately available and the output can be generated. + # + # @return [Document] a new instance of Document + # + # source://kramdown//lib/kramdown/document.rb#96 + def initialize(source, options = T.unsafe(nil)); end + + # source://kramdown//lib/kramdown/document.rb#124 + def inspect; end + + # Check if a method is invoked that begins with +to_+ and if so, try to instantiate a converter + # class (i.e. a class in the Kramdown::Converter module) and use it for converting the document. + # + # For example, +to_html+ would instantiate the Kramdown::Converter::Html class. + # + # source://kramdown//lib/kramdown/document.rb#113 + def method_missing(id, *attr, &block); end + + # The options hash which holds the options for parsing/converting the Kramdown document. + # + # source://kramdown//lib/kramdown/document.rb#80 + def options; end + + # The root Element of the element tree. It is immediately available after the ::new method has + # been called. + # + # source://kramdown//lib/kramdown/document.rb#77 + def root; end + + # The root Element of the element tree. It is immediately available after the ::new method has + # been called. + # + # source://kramdown//lib/kramdown/document.rb#77 + def root=(_arg0); end + + # An array of warning messages. It is filled with warnings during the parsing phase (i.e. in + # ::new) and the conversion phase. + # + # source://kramdown//lib/kramdown/document.rb#84 + def warnings; end + + protected + + # Try requiring a parser or converter class and don't raise an error if the file is not found. + # + # source://kramdown//lib/kramdown/document.rb#129 + def try_require(type, name); end +end + +# Represents all elements in the element tree. +# +# kramdown only uses this one class for representing all available elements in an element tree +# (paragraphs, headers, emphasis, ...). The type of element can be set via the #type accessor. +# +# The root of a kramdown element tree has to be an element of type :root. It needs to have certain +# option keys set so that conversions work correctly. If only a part of a tree should be +# converted, duplicate the root node and assign the #children appropriately, e.g: +# +# root = doc.root +# new_root = root.dup +# new_root.children = [root.children[0]] # assign new array with elements to convert +# +# Following is a description of all supported element types. +# +# Note that the option :location may contain the start line number of an element in the source +# document. +# +# == Structural Elements +# +# === :root +# +# [Category] None +# [Usage context] As the root element of a document +# [Content model] Block-level elements +# +# Represents the root of a kramdown document. +# +# The root element contains the following option keys: +# +# parts of the kramdown document. +# +# :abbrev_defs:: This key may be used to store the mapping of abbreviation to abbreviation +# definition. +# +# :abbrev_attr:: This key may be used to store the mapping of abbreviation to abbreviation +# attributes. +# +# :options:: This key may be used to store options that were set during parsing of the document. +# +# :footnote_count:: This key stores the number of actually referenced footnotes of the document. +# +# === :blank +# +# [Category] Block-level element +# [Usage context] Where block-level elements are expected +# [Content model] Empty +# +# Represents one or more blank lines. It is not allowed to have two or more consecutive blank +# elements. +# +# The +value+ field may contain the original content of the blank lines. +# +# +# === :p +# +# [Category] Block-level element +# [Usage context] Where block-level elements are expected +# [Content model] Span-level elements +# +# Represents a paragraph. +# +# If the option :transparent is +true+, this element just represents a block of text. I.e. this +# element just functions as a container for span-level elements. +# +# +# === :header +# +# [Category] Block-level element +# [Usage context] Where block-level elements are expected +# [Content model] Span-level elements +# +# Represents a header. +# +# The option :level specifies the header level and has to contain a number between 1 and \6. The +# option :raw_text has to contain the raw header text. +# +# +# === :blockquote +# +# [Category] Block-level element +# [Usage context] Where block-level elements are expected +# [Content model] Block-level elements +# +# Represents a blockquote. +# +# +# === :codeblock +# +# [Category] Block-level element +# [Usage context] Where block-level elements are expected +# [Content model] Empty +# +# Represents a code block, i.e. a block of text that should be used as-is. +# +# The +value+ field has to contain the content of the code block. +# +# The option :lang specifies a highlighting language with possible HTML style options (e.g. +# php?start_inline=1) and should be used instead of a possibly also available language embedded in +# a class name of the form 'language-LANG'. +# +# +# === :ul +# +# [Category] Block-level element +# [Usage context] Where block-level elements are expected +# [Content model] One or more :li elements +# +# Represents an unordered list. +# +# +# === :ol +# +# [Category] Block-level element +# [Usage context] Where block-level elements are expected +# [Content model] One or more :li elements +# +# Represents an ordered list. +# +# +# === :li +# +# [Category] Block-level element +# [Usage context] Inside :ol and :ul elements +# [Content model] Block-level elements +# +# Represents a list item of an ordered or unordered list. +# +# Note that the first child of a list item must not be a :blank element! +# +# +# === :dl +# +# [Category] Block-level element +# [Usage context] Where block-level elements are expected +# [Content model] One or more groups each consisting of one or more :dt elements followed by one +# or more :dd elements. +# +# Represents a definition list which contains groups consisting of terms and definitions for them. +# +# +# === :dt +# +# [Category] Block-level element +# [Usage context] Before :dt or :dd elements inside a :dl elment +# [Content model] Span-level elements +# +# Represents the term part of a term-definition group in a definition list. +# +# +# === :dd +# +# [Category] Block-level element +# [Usage context] After :dt or :dd elements inside a :dl elment +# [Content model] Block-level elements +# +# Represents the definition part of a term-definition group in a definition list. +# +# +# === :hr +# +# [Category] Block-level element +# [Usage context] Where block-level elements are expected +# [Content model] None +# +# Represents a horizontal line. +# +# +# === :table +# +# [Category] Block-level element +# [Usage context] Where block-level elements are expected +# [Content model] Zero or one :thead elements, one or more :tbody elements, zero or one :tfoot +# elements +# +# Represents a table. Each table row (i.e. :tr element) of the table has to contain the same +# number of :td elements. +# +# The option :alignment has to be an array containing the alignment values, exactly one for each +# column of the table. The possible alignment values are :left, :center, :right and :default. +# +# +# === :thead +# +# [Category] None +# [Usage context] As first element inside a :table element +# [Content model] One or more :tr elements +# +# Represents the table header. +# +# +# === :tbody +# +# [Category] None +# [Usage context] After a :thead element but before a :tfoot element inside a :table element +# [Content model] One or more :tr elements +# +# Represents a table body. +# +# +# === :tfoot +# +# [Category] None +# [Usage context] As last element inside a :table element +# [Content model] One or more :tr elements +# +# Represents the table footer. +# +# +# === :tr +# +# [Category] None +# [Usage context] Inside :thead, :tbody and :tfoot elements +# [Content model] One or more :td elements +# +# Represents a table row. +# +# +# === :td +# +# [Category] Block-level element +# [Usage context] Inside :tr elements +# [Content model] As child of :thead/:tr span-level elements, as child of :tbody/:tr and +# :tfoot/:tr block-level elements +# +# Represents a table cell. +# +# +# === :math +# +# [Category] Block/span-level element +# [Usage context] Where block/span-level elements are expected +# [Content model] None +# +# Represents mathematical text that is written in LaTeX. +# +# The +value+ field has to contain the actual mathematical text. +# +# The option :category has to be set to either :span or :block depending on the context where the +# element is used. +# +# +# == Text Markup Elements +# +# === :text +# +# [Category] Span-level element +# [Usage context] Where span-level elements are expected +# [Content model] None +# +# Represents text. +# +# The +value+ field has to contain the text itself. +# +# +# === :br +# +# [Category] Span-level element +# [Usage context] Where span-level elements are expected +# [Content model] None +# +# Represents a hard line break. +# +# +# === :a +# +# [Category] Span-level element +# [Usage context] Where span-level elements are expected +# [Content model] Span-level elements +# +# Represents a link to an URL. +# +# The attribute +href+ has to be set to the URL to which the link points. The attribute +title+ +# optionally contains the title of the link. +# +# +# === :img +# +# [Category] Span-level element +# [Usage context] Where span-level elements are expected +# [Content model] None +# +# Represents an image. +# +# The attribute +src+ has to be set to the URL of the image. The attribute +alt+ has to contain a +# text description of the image. The attribute +title+ optionally contains the title of the image. +# +# +# === :codespan +# +# [Category] Span-level element +# [Usage context] Where span-level elements are expected +# [Content model] None +# +# Represents verbatim text. +# +# The +value+ field has to contain the content of the code span. +# +# +# === :footnote +# +# [Category] Span-level element +# [Usage context] Where span-level elements are expected +# [Content model] None +# +# Represents a footnote marker. +# +# The +value+ field has to contain an element whose children are the content of the footnote. The +# option :name has to contain a valid and unique footnote name. A valid footnote name consists of +# a word character or a digit and then optionally followed by other word characters, digits or +# dashes. +# +# +# === :em +# +# [Category] Span-level element +# [Usage context] Where span-level elements are expected +# [Content model] Span-level elements +# +# Represents emphasis of its contents. +# +# +# === :strong +# +# [Category] Span-level element +# [Usage context] Where span-level elements are expected +# [Content model] Span-level elements +# +# Represents strong importance for its contents. +# +# +# === :entity +# +# [Category] Span-level element +# [Usage context] Where span-level elements are expected +# [Content model] None +# +# Represents an HTML entity. +# +# The +value+ field has to contain an instance of Kramdown::Utils::Entities::Entity. The option +# :original can be used to store the original representation of the entity. +# +# +# === :typographic_sym +# +# [Category] Span-level element +# [Usage context] Where span-level elements are expected +# [Content model] None +# +# Represents a typographic symbol. +# +# The +value+ field needs to contain a Symbol representing the specific typographic symbol from +# the following list: +# +# :mdash:: An mdash character (---) +# :ndash:: An ndash character (--) +# :hellip:: An ellipsis (...) +# :laquo:: A left guillemet (<<) +# :raquo:: A right guillemet (>>) +# :laquo_space:: A left guillemet with a space (<< ) +# :raquo_space:: A right guillemet with a space ( >>) +# +# +# === :smart_quote +# +# [Category] Span-level element +# [Usage context] Where span-level elements are expected +# [Content model] None +# +# Represents a quotation character. +# +# The +value+ field needs to contain a Symbol representing the specific quotation character: +# +# :lsquo:: Left single quote +# :rsquo:: Right single quote +# :ldquo:: Left double quote +# :rdquo:: Right double quote +# +# +# === :abbreviation +# +# [Category] Span-level element +# [Usage context] Where span-level elements are expected +# [Content model] None +# +# Represents a text part that is an abbreviation. +# +# The +value+ field has to contain the text part that is the abbreviation. The definition of the +# abbreviation is stored in the :root element of the document. +# +# +# == Other Elements +# +# === :html_element +# +# [Category] Block/span-level element +# [Usage context] Where block/span-level elements or raw HTML elements are expected +# [Content model] Depends on the element +# +# Represents an HTML element. +# +# The +value+ field has to contain the name of the HTML element the element is representing. +# +# The option :category has to be set to either :span or :block depending on the whether the +# element is a block-level or a span-level element. The option :content_model has to be set to the +# content model for the element (either :block if it contains block-level elements, :span if it +# contains span-level elements or :raw if it contains raw content). +# +# +# === :xml_comment +# +# [Category] Block/span-level element +# [Usage context] Where block/span-level elements are expected or in raw HTML elements +# [Content model] None +# +# Represents an XML/HTML comment. +# +# The +value+ field has to contain the whole XML/HTML comment including the delimiters. +# +# The option :category has to be set to either :span or :block depending on the context where the +# element is used. +# +# +# === :xml_pi +# +# [Category] Block/span-level element +# [Usage context] Where block/span-level elements are expected or in raw HTML elements +# [Content model] None +# +# Represents an XML/HTML processing instruction. +# +# The +value+ field has to contain the whole XML/HTML processing instruction including the +# delimiters. +# +# The option :category has to be set to either :span or :block depending on the context where the +# element is used. +# +# +# === :comment +# +# [Category] Block/span-level element +# [Usage context] Where block/span-level elements are expected +# [Content model] None +# +# Represents a comment. +# +# The +value+ field has to contain the comment. +# +# The option :category has to be set to either :span or :block depending on the context where the +# element is used. If it is set to :span, then no blank lines are allowed in the comment. +# +# +# === :raw +# +# [Category] Block/span-level element +# [Usage context] Where block/span-level elements are expected +# [Content model] None +# +# Represents a raw string that should not be modified. For example, the element could contain some +# HTML code that should be output as-is without modification and escaping. +# +# The +value+ field has to contain the actual raw text. +# +# The option :category has to be set to either :span or :block depending on the context where the +# element is used. If it is set to :span, then no blank lines are allowed in the raw text. +# +# The option :type can be set to an array of strings to define for which converters the raw string +# is valid. +# +# source://kramdown//lib/kramdown/element.rb#482 +class Kramdown::Element + # Create a new Element object of type +type+. The optional parameters +value+, +attr+ and + # +options+ can also be set in this constructor for convenience. + # + # @return [Element] a new instance of Element + # + # source://kramdown//lib/kramdown/element.rb#496 + def initialize(type, value = T.unsafe(nil), attr = T.unsafe(nil), options = T.unsafe(nil)); end + + # The attributes of the element. + # + # source://kramdown//lib/kramdown/element.rb#502 + def attr; end + + # syntactic sugar to simplify calls such as +Kramdown::Element.category(el) == :block+ with + # +el.block?+. + # + # Returns boolean true or false. + # + # @return [Boolean] + # + # source://kramdown//lib/kramdown/element.rb#537 + def block?; end + + # The child elements of this element. + # + # source://kramdown//lib/kramdown/element.rb#492 + def children; end + + # The child elements of this element. + # + # source://kramdown//lib/kramdown/element.rb#492 + def children=(_arg0); end + + # source://kramdown//lib/kramdown/element.rb#511 + def inspect; end + + # The options hash for the element. It is used for storing arbitray options. + # + # source://kramdown//lib/kramdown/element.rb#507 + def options; end + + # syntactic sugar to simplify calls such as +Kramdown::Element.category(el) == :span+ with + # +el.span?+. + # + # Returns boolean true or false. + # + # @return [Boolean] + # + # source://kramdown//lib/kramdown/element.rb#545 + def span?; end + + # A symbol representing the element type. For example, :p or :blockquote. + # + # source://kramdown//lib/kramdown/element.rb#485 + def type; end + + # A symbol representing the element type. For example, :p or :blockquote. + # + # source://kramdown//lib/kramdown/element.rb#485 + def type=(_arg0); end + + # The value of the element. The interpretation of this field depends on the type of the element. + # Many elements don't use this field. + # + # source://kramdown//lib/kramdown/element.rb#489 + def value; end + + # The value of the element. The interpretation of this field depends on the type of the element. + # Many elements don't use this field. + # + # source://kramdown//lib/kramdown/element.rb#489 + def value=(_arg0); end + + class << self + # Return the category of +el+ which can be :block, :span or +nil+. + # + # Most elements have a fixed category, however, some elements can either appear in a block-level + # or a span-level context. These elements need to have the option :category correctly set. + # + # source://kramdown//lib/kramdown/element.rb#529 + def category(el); end + end +end + +# source://kramdown//lib/kramdown/element.rb#519 +Kramdown::Element::CATEGORY = T.let(T.unsafe(nil), Hash) + +# This error is raised when an error condition is encountered. +# +# *Note* that this error is only raised by the support framework for the parsers and converters. +# +# source://kramdown//lib/kramdown/error.rb#15 +class Kramdown::Error < ::RuntimeError; end + +# This module defines all options that are used by parsers and/or converters as well as providing +# methods to deal with the options. +# +# source://kramdown//lib/kramdown/options.rb#16 +module Kramdown::Options + class << self + # Return a Hash with the default values for all options. + # + # source://kramdown//lib/kramdown/options.rb#72 + def defaults; end + + # Define a new option called +name+ (a Symbol) with the given +type+ (String, Integer, Float, + # Symbol, Boolean, Object), default value +default+ and the description +desc+. If a block is + # specified, it should validate the value and either raise an error or return a valid value. + # + # The type 'Object' should only be used for complex types for which none of the other types + # suffices. A block needs to be specified when using type 'Object' and it has to cope with + # a value given as string and as the opaque type. + # + # @raise [ArgumentError] + # + # source://kramdown//lib/kramdown/options.rb#51 + def define(name, type, default, desc, &block); end + + # Return +true+ if an option called +name+ is defined. + # + # @return [Boolean] + # + # source://kramdown//lib/kramdown/options.rb#67 + def defined?(name); end + + # Return all option definitions. + # + # source://kramdown//lib/kramdown/options.rb#62 + def definitions; end + + # Merge the #defaults Hash with the *parsed* options from the given Hash, i.e. only valid option + # names are considered and their value is run through the #parse method. + # + # source://kramdown//lib/kramdown/options.rb#82 + def merge(hash); end + + # Parse the given value +data+ as if it was a value for the option +name+ and return the parsed + # value with the correct type. + # + # If +data+ already has the correct type, it is just returned. Otherwise it is converted to a + # String and then to the correct type. + # + # @raise [ArgumentError] + # + # source://kramdown//lib/kramdown/options.rb#96 + def parse(name, data); end + + # Ensures that the option value +val+ for the option called +name+ is a valid array. The + # parameter +val+ can be + # + # - a comma separated string which is split into an array of values + # - or an array. + # + # Optionally, the array is checked for the correct size. + # + # source://kramdown//lib/kramdown/options.rb#141 + def simple_array_validator(val, name, size = T.unsafe(nil)); end + + # Ensures that the option value +val+ for the option called +name+ is a valid hash. The + # parameter +val+ can be + # + # - a hash in YAML format + # - or a Ruby Hash object. + # + # @raise [Kramdown::Error] + # + # source://kramdown//lib/kramdown/options.rb#158 + def simple_hash_validator(val, name); end + + # Converts the given String +data+ into a Symbol or +nil+ with the + # following provisions: + # + # - A leading colon is stripped from the string. + # - An empty value or a value equal to "nil" results in +nil+. + # + # source://kramdown//lib/kramdown/options.rb#122 + def str_to_sym(data); end + end +end + +# Allowed option types. +# +# source://kramdown//lib/kramdown/options.rb#39 +Kramdown::Options::ALLOWED_TYPES = T.let(T.unsafe(nil), Array) + +# Helper class introducing a boolean type for specifying boolean values (+true+ and +false+) as +# option types. +# +# source://kramdown//lib/kramdown/options.rb#20 +class Kramdown::Options::Boolean + class << self + # Return +true+ if +other+ is either +true+ or +false+ + # + # source://kramdown//lib/kramdown/options.rb#23 + def ===(other); end + end +end + +# Struct class for storing the definition of an option. +# +# source://kramdown//lib/kramdown/options.rb#36 +class Kramdown::Options::Definition < ::Struct + # Returns the value of attribute default + # + # @return [Object] the current value of default + def default; end + + # Sets the attribute default + # + # @param value [Object] the value to set the attribute default to. + # @return [Object] the newly set value + def default=(_); end + + # Returns the value of attribute desc + # + # @return [Object] the current value of desc + def desc; end + + # Sets the attribute desc + # + # @param value [Object] the value to set the attribute desc to. + # @return [Object] the newly set value + def desc=(_); end + + # Returns the value of attribute name + # + # @return [Object] the current value of name + def name; end + + # Sets the attribute name + # + # @param value [Object] the value to set the attribute name to. + # @return [Object] the newly set value + def name=(_); end + + # Returns the value of attribute type + # + # @return [Object] the current value of type + def type; end + + # Sets the attribute type + # + # @param value [Object] the value to set the attribute type to. + # @return [Object] the newly set value + def type=(_); end + + # Returns the value of attribute validator + # + # @return [Object] the current value of validator + def validator; end + + # Sets the attribute validator + # + # @param value [Object] the value to set the attribute validator to. + # @return [Object] the newly set value + def validator=(_); end + + class << self + def [](*_arg0); end + def inspect; end + def keyword_init?; end + def members; end + def new(*_arg0); end + end +end + +# source://kramdown//lib/kramdown/options.rb#396 +Kramdown::Options::SMART_QUOTES_ENTITIES = T.let(T.unsafe(nil), Array) + +# source://kramdown//lib/kramdown/options.rb#397 +Kramdown::Options::SMART_QUOTES_STR = T.let(T.unsafe(nil), String) + +# source://kramdown//lib/kramdown/options.rb#336 +Kramdown::Options::TOC_LEVELS_ARRAY = T.let(T.unsafe(nil), Array) + +# source://kramdown//lib/kramdown/options.rb#335 +Kramdown::Options::TOC_LEVELS_RANGE = T.let(T.unsafe(nil), Range) + +# This module contains all available parsers. A parser takes an input string and converts the +# string to an element tree. +# +# New parsers should be derived from the Base class which provides common functionality - see its +# API documentation for how to create a custom converter class. +# +# source://kramdown//lib/kramdown/parser.rb#17 +module Kramdown::Parser; end + +# == \Base class for parsers +# +# This class serves as base class for parsers. It provides common methods that can/should be +# used by all parsers, especially by those using StringScanner(Kramdown) for parsing. +# +# A parser object is used as a throw-away object, i.e. it is only used for storing the needed +# state information during parsing. Therefore one can't instantiate a parser object directly but +# only use the Base::parse method. +# +# == Implementing a parser +# +# Implementing a new parser is rather easy: just derive a new class from this class and put it +# in the Kramdown::Parser module -- the latter is needed so that the auto-detection of the new +# parser works correctly. Then you need to implement the +#parse+ method which has to contain +# the parsing code. +# +# Have a look at the Base::parse, Base::new and Base#parse methods for additional information! +# +# source://kramdown//lib/kramdown/parser/base.rb#34 +class Kramdown::Parser::Base + # Initialize the parser object with the +source+ string and the parsing +options+. + # + # The @root element, the @warnings array and @text_type (specifies the default type for newly + # created text nodes) are automatically initialized. + # + # @return [Base] a new instance of Base + # + # source://kramdown//lib/kramdown/parser/base.rb#52 + def initialize(source, options); end + + # Modify the string +source+ to be usable by the parser (unifies line ending characters to + # +\n+ and makes sure +source+ ends with a new line character). + # + # source://kramdown//lib/kramdown/parser/base.rb#91 + def adapt_source(source); end + + # This helper method adds the given +text+ either to the last element in the +tree+ if it is a + # +type+ element or creates a new text element with the given +type+. + # + # source://kramdown//lib/kramdown/parser/base.rb#103 + def add_text(text, tree = T.unsafe(nil), type = T.unsafe(nil)); end + + # Extract the part of the StringScanner +strscan+ backed string specified by the +range+. This + # method works correctly under Ruby 1.8 and Ruby 1.9. + # + # source://kramdown//lib/kramdown/parser/base.rb#115 + def extract_string(range, strscan); end + + # The hash with the parsing options. + # + # source://kramdown//lib/kramdown/parser/base.rb#37 + def options; end + + # Parse the source string into an element tree. + # + # The parsing code should parse the source provided in @source and build an element tree the + # root of which should be @root. + # + # This is the only method that has to be implemented by sub-classes! + # + # @raise [NotImplementedError] + # + # source://kramdown//lib/kramdown/parser/base.rb#79 + def parse; end + + # The root element of element tree that is created from the source string. + # + # source://kramdown//lib/kramdown/parser/base.rb#46 + def root; end + + # The original source string. + # + # source://kramdown//lib/kramdown/parser/base.rb#43 + def source; end + + # Add the given warning +text+ to the warning array. + # + # source://kramdown//lib/kramdown/parser/base.rb#84 + def warning(text); end + + # The array with the parser warnings. + # + # source://kramdown//lib/kramdown/parser/base.rb#40 + def warnings; end + + class << self + # Parse the +source+ string into an element tree, possibly using the parsing +options+, and + # return the root element of the element tree and an array with warning messages. + # + # Initializes a new instance of the calling class and then calls the +#parse+ method that must + # be implemented by each subclass. + # + # source://kramdown//lib/kramdown/parser/base.rb#67 + def parse(source, options = T.unsafe(nil)); end + + private + + def allocate; end + def new(*_arg0); end + end +end + +# Used for parsing an HTML document. +# +# The parsing code is in the Parser module that can also be used by other parsers. +# +# source://kramdown//lib/kramdown/parser/html.rb#22 +class Kramdown::Parser::Html < ::Kramdown::Parser::Base + include ::Kramdown::Parser::Html::Constants + include ::Kramdown::Parser::Html::Parser + + # Parse the source string provided on initialization as HTML document. + # + # source://kramdown//lib/kramdown/parser/html.rb#586 + def parse; end +end + +# Contains all constants that are used when parsing. +# +# source://kramdown//lib/kramdown/parser/html.rb#25 +module Kramdown::Parser::Html::Constants; end + +# source://kramdown//lib/kramdown/parser/html.rb#32 +Kramdown::Parser::Html::Constants::HTML_ATTRIBUTE_RE = T.let(T.unsafe(nil), Regexp) + +# source://kramdown//lib/kramdown/parser/html.rb#59 +Kramdown::Parser::Html::Constants::HTML_BLOCK_ELEMENTS = T.let(T.unsafe(nil), Array) + +# source://kramdown//lib/kramdown/parser/html.rb#30 +Kramdown::Parser::Html::Constants::HTML_COMMENT_RE = T.let(T.unsafe(nil), Regexp) + +# The following elements are also parsed as raw since they need child elements that cannot +# be expressed using kramdown syntax: colgroup table tbody thead tfoot tr ul ol +# +# source://kramdown//lib/kramdown/parser/html.rb#48 +Kramdown::Parser::Html::Constants::HTML_CONTENT_MODEL = T.let(T.unsafe(nil), Hash) + +# source://kramdown//lib/kramdown/parser/html.rb#37 +Kramdown::Parser::Html::Constants::HTML_CONTENT_MODEL_BLOCK = T.let(T.unsafe(nil), Array) + +# source://kramdown//lib/kramdown/parser/html.rb#44 +Kramdown::Parser::Html::Constants::HTML_CONTENT_MODEL_RAW = T.let(T.unsafe(nil), Array) + +# source://kramdown//lib/kramdown/parser/html.rb#41 +Kramdown::Parser::Html::Constants::HTML_CONTENT_MODEL_SPAN = T.let(T.unsafe(nil), Array) + +# :stopdoc: +# The following regexps are based on the ones used by REXML, with some slight modifications. +# +# source://kramdown//lib/kramdown/parser/html.rb#29 +Kramdown::Parser::Html::Constants::HTML_DOCTYPE_RE = T.let(T.unsafe(nil), Regexp) + +# source://kramdown//lib/kramdown/parser/html.rb#66 +Kramdown::Parser::Html::Constants::HTML_ELEMENT = T.let(T.unsafe(nil), Hash) + +# source://kramdown//lib/kramdown/parser/html.rb#63 +Kramdown::Parser::Html::Constants::HTML_ELEMENTS_WITHOUT_BODY = T.let(T.unsafe(nil), Array) + +# source://kramdown//lib/kramdown/parser/html.rb#35 +Kramdown::Parser::Html::Constants::HTML_ENTITY_RE = T.let(T.unsafe(nil), Regexp) + +# source://kramdown//lib/kramdown/parser/html.rb#31 +Kramdown::Parser::Html::Constants::HTML_INSTRUCTION_RE = T.let(T.unsafe(nil), Regexp) + +# Some HTML elements like script belong to both categories (i.e. are valid in block and +# span HTML) and don't appear therefore! +# script, textarea +# +# source://kramdown//lib/kramdown/parser/html.rb#56 +Kramdown::Parser::Html::Constants::HTML_SPAN_ELEMENTS = T.let(T.unsafe(nil), Array) + +# source://kramdown//lib/kramdown/parser/html.rb#34 +Kramdown::Parser::Html::Constants::HTML_TAG_CLOSE_RE = T.let(T.unsafe(nil), Regexp) + +# source://kramdown//lib/kramdown/parser/html.rb#33 +Kramdown::Parser::Html::Constants::HTML_TAG_RE = T.let(T.unsafe(nil), Regexp) + +# Converts HTML elements to native elements if possible. +# +# source://kramdown//lib/kramdown/parser/html.rb#197 +class Kramdown::Parser::Html::ElementConverter + include ::Kramdown::Parser::Html::Constants + include ::Kramdown::Utils::Entities + + # @return [ElementConverter] a new instance of ElementConverter + # + # source://kramdown//lib/kramdown/parser/html.rb#216 + def initialize(root); end + + # source://kramdown//lib/kramdown/parser/html.rb#384 + def convert_a(el); end + + # source://kramdown//lib/kramdown/parser/html.rb#394 + def convert_b(el); end + + # source://kramdown//lib/kramdown/parser/html.rb#417 + def convert_code(el); end + + # source://kramdown//lib/kramdown/parser/html.rb#394 + def convert_em(el); end + + # source://kramdown//lib/kramdown/parser/html.rb#408 + def convert_h1(el); end + + # source://kramdown//lib/kramdown/parser/html.rb#408 + def convert_h2(el); end + + # source://kramdown//lib/kramdown/parser/html.rb#408 + def convert_h3(el); end + + # source://kramdown//lib/kramdown/parser/html.rb#408 + def convert_h4(el); end + + # source://kramdown//lib/kramdown/parser/html.rb#408 + def convert_h5(el); end + + # source://kramdown//lib/kramdown/parser/html.rb#408 + def convert_h6(el); end + + # source://kramdown//lib/kramdown/parser/html.rb#394 + def convert_i(el); end + + # source://kramdown//lib/kramdown/parser/html.rb#417 + def convert_pre(el); end + + # source://kramdown//lib/kramdown/parser/html.rb#563 + def convert_script(el); end + + # source://kramdown//lib/kramdown/parser/html.rb#394 + def convert_strong(el); end + + # source://kramdown//lib/kramdown/parser/html.rb#460 + def convert_table(el); end + + # source://kramdown//lib/kramdown/parser/html.rb#380 + def convert_textarea(el); end + + # source://kramdown//lib/kramdown/parser/html.rb#375 + def extract_text(el, raw); end + + # source://kramdown//lib/kramdown/parser/html.rb#575 + def handle_math_tag(el); end + + # @return [Boolean] + # + # source://kramdown//lib/kramdown/parser/html.rb#571 + def is_math_tag?(el); end + + # @return [Boolean] + # + # source://kramdown//lib/kramdown/parser/html.rb#503 + def is_simple_table?(el); end + + # Convert the element +el+ and its children. + # + # source://kramdown//lib/kramdown/parser/html.rb#225 + def process(el, do_conversion = T.unsafe(nil), preserve_text = T.unsafe(nil), parent = T.unsafe(nil)); end + + # source://kramdown//lib/kramdown/parser/html.rb#278 + def process_children(el, do_conversion = T.unsafe(nil), preserve_text = T.unsafe(nil)); end + + # source://kramdown//lib/kramdown/parser/html.rb#320 + def process_html_element(el, do_conversion = T.unsafe(nil), preserve_text = T.unsafe(nil)); end + + # Process the HTML text +raw+: compress whitespace (if +preserve+ is +false+) and convert + # entities in entity elements. + # + # source://kramdown//lib/kramdown/parser/html.rb#291 + def process_text(raw, preserve = T.unsafe(nil)); end + + # source://kramdown//lib/kramdown/parser/html.rb#326 + def remove_text_children(el); end + + # source://kramdown//lib/kramdown/parser/html.rb#359 + def remove_whitespace_children(el); end + + # source://kramdown//lib/kramdown/parser/html.rb#369 + def set_basics(el, type, opts = T.unsafe(nil)); end + + # source://kramdown//lib/kramdown/parser/html.rb#349 + def strip_whitespace(el); end + + # source://kramdown//lib/kramdown/parser/html.rb#330 + def wrap_text_children(el); end + + class << self + # source://kramdown//lib/kramdown/parser/html.rb#220 + def convert(root, el = T.unsafe(nil)); end + end +end + +# source://kramdown//lib/kramdown/parser/html.rb#393 +Kramdown::Parser::Html::ElementConverter::EMPHASIS_TYPE_MAP = T.let(T.unsafe(nil), Hash) + +# source://kramdown//lib/kramdown/parser/html.rb#204 +Kramdown::Parser::Html::ElementConverter::REMOVE_TEXT_CHILDREN = T.let(T.unsafe(nil), Array) + +# source://kramdown//lib/kramdown/parser/html.rb#208 +Kramdown::Parser::Html::ElementConverter::REMOVE_WHITESPACE_CHILDREN = T.let(T.unsafe(nil), Array) + +# source://kramdown//lib/kramdown/parser/html.rb#213 +Kramdown::Parser::Html::ElementConverter::SIMPLE_ELEMENTS = T.let(T.unsafe(nil), Array) + +# source://kramdown//lib/kramdown/parser/html.rb#210 +Kramdown::Parser::Html::ElementConverter::STRIP_WHITESPACE = T.let(T.unsafe(nil), Array) + +# source://kramdown//lib/kramdown/parser/html.rb#206 +Kramdown::Parser::Html::ElementConverter::WRAP_TEXT_CHILDREN = T.let(T.unsafe(nil), Array) + +# Contains the parsing methods. This module can be mixed into any parser to get HTML parsing +# functionality. The only thing that must be provided by the class are instance variable +# parsing. +# +# source://kramdown//lib/kramdown/parser/html.rb#77 +module Kramdown::Parser::Html::Parser + include ::Kramdown::Parser::Html::Constants + + # Process the HTML start tag that has already be scanned/checked via @src. + # + # Does the common processing steps and then yields to the caller for further processing + # (first parameter is the created element; the second parameter is +true+ if the HTML + # element is already closed, ie. contains no body; the third parameter specifies whether the + # body - and the end tag - need to be handled in case closed=false). + # + # source://kramdown//lib/kramdown/parser/html.rb#87 + def handle_html_start_tag(line = T.unsafe(nil)); end + + # Handle the raw HTML tag at the current position. + # + # source://kramdown//lib/kramdown/parser/html.rb#127 + def handle_raw_html_tag(name); end + + # Parses the given string for HTML attributes and returns the resulting hash. + # + # If the optional +line+ parameter is supplied, it is used in warning messages. + # + # If the optional +in_html_tag+ parameter is set to +false+, attributes are not modified to + # contain only lowercase letters. + # + # source://kramdown//lib/kramdown/parser/html.rb#114 + def parse_html_attributes(str, line = T.unsafe(nil), in_html_tag = T.unsafe(nil)); end + + # Parse raw HTML from the current source position, storing the found elements in +el+. + # Parsing continues until one of the following criteria are fulfilled: + # + # - The end of the document is reached. + # - The matching end tag for the element +el+ is found (only used if +el+ is an HTML + # element). + # + # When an HTML start tag is found, processing is deferred to #handle_html_start_tag, + # providing the block given to this method. + # + # source://kramdown//lib/kramdown/parser/html.rb#150 + def parse_raw_html(el, &block); end +end + +# source://kramdown//lib/kramdown/parser/html.rb#139 +Kramdown::Parser::Html::Parser::HTML_RAW_START = T.let(T.unsafe(nil), Regexp) + +# Used for parsing a document in kramdown format. +# +# If you want to extend the functionality of the parser, you need to do the following: +# +# * Create a new subclass +# * add the needed parser methods +# * modify the @block_parsers and @span_parsers variables and add the names of your parser +# methods +# +# Here is a small example for an extended parser class that parses ERB style tags as raw text if +# they are used as span-level elements (an equivalent block-level parser should probably also be +# made to handle the block case): +# +# require 'kramdown/parser/kramdown' +# +# class Kramdown::Parser::ERBKramdown < Kramdown::Parser::Kramdown +# +# def initialize(source, options) +# super +# @span_parsers.unshift(:erb_tags) +# end +# +# ERB_TAGS_START = /<%.*?%>/ +# +# def parse_erb_tags +# @src.pos += @src.matched_size +# @tree.children << Element.new(:raw, @src.matched) +# end +# define_parser(:erb_tags, ERB_TAGS_START, '<%') +# +# end +# +# The new parser can be used like this: +# +# require 'kramdown/document' +# # require the file with the above parser class +# +# Kramdown::Document.new(input_text, :input => 'ERBKramdown').to_html +# +# source://kramdown//lib/kramdown/parser/kramdown.rb#60 +class Kramdown::Parser::Kramdown < ::Kramdown::Parser::Base + include ::Kramdown + include ::Kramdown::Parser::Html::Constants + include ::Kramdown::Parser::Html::Parser + + # Create a new Kramdown parser object with the given +options+. + # + # @return [Kramdown] a new instance of Kramdown + # + # source://kramdown//lib/kramdown/parser/kramdown.rb#65 + def initialize(source, options); end + + # This helper methods adds the approriate attributes to the element +el+ of type +a+ or +img+ + # and the element itself to the @tree. + # + # source://kramdown//lib/kramdown/parser/kramdown/link.rb#39 + def add_link(el, href, title, alt_text = T.unsafe(nil), ial = T.unsafe(nil)); end + + # Return +true+ if we are after a block boundary. + # + # @return [Boolean] + # + # source://kramdown//lib/kramdown/parser/kramdown/block_boundary.rb#21 + def after_block_boundary?; end + + # Return +true+ if we are before a block boundary. + # + # @return [Boolean] + # + # source://kramdown//lib/kramdown/parser/kramdown/block_boundary.rb#28 + def before_block_boundary?; end + + # Correct abbreviation attributes. + # + # source://kramdown//lib/kramdown/parser/kramdown/abbreviation.rb#34 + def correct_abbreviations_attributes; end + + # source://kramdown//lib/kramdown/parser/kramdown/extensions.rb#96 + def handle_extension(name, opts, body, type, line_no = T.unsafe(nil)); end + + # source://kramdown//lib/kramdown/parser/kramdown/html.rb#25 + def handle_kramdown_html_tag(el, closed, handle_body); end + + # Normalize the link identifier. + # + # source://kramdown//lib/kramdown/parser/kramdown/link.rb#17 + def normalize_link_id(id); end + + # source://kramdown//lib/kramdown/parser/kramdown/paragraph.rb#56 + def paragraph_end; end + + # The source string provided on initialization is parsed into the @root element. + # + # source://kramdown//lib/kramdown/parser/kramdown.rb#88 + def parse; end + + # Parse the link definition at the current location. + # + # source://kramdown//lib/kramdown/parser/kramdown/abbreviation.rb#17 + def parse_abbrev_definition; end + + # Parse the string +str+ and extract all attributes and add all found attributes to the hash + # +opts+. + # + # source://kramdown//lib/kramdown/parser/kramdown/extensions.rb#18 + def parse_attribute_list(str, opts); end + + # Parse the Atx header at the current location. + # + # source://kramdown//lib/kramdown/parser/kramdown/header.rb#32 + def parse_atx_header; end + + # Parse the autolink at the current location. + # + # source://kramdown//lib/kramdown/parser/kramdown/autolink.rb#19 + def parse_autolink; end + + # Parse the blank line at the current postition. + # + # source://kramdown//lib/kramdown/parser/kramdown/blank_line.rb#17 + def parse_blank_line; end + + # Parse one of the block extensions (ALD, block IAL or generic extension) at the current + # location. + # + # source://kramdown//lib/kramdown/parser/kramdown/extensions.rb#164 + def parse_block_extensions; end + + # Parse the HTML at the current position as block-level HTML. + # + # source://kramdown//lib/kramdown/parser/kramdown/html.rb#71 + def parse_block_html; end + + # Parse the math block at the current location. + # + # source://kramdown//lib/kramdown/parser/kramdown/math.rb#19 + def parse_block_math; end + + # Parse the blockquote at the current location. + # + # source://kramdown//lib/kramdown/parser/kramdown/blockquote.rb#21 + def parse_blockquote; end + + # Parse the indented codeblock at the current location. + # + # source://kramdown//lib/kramdown/parser/kramdown/codeblock.rb#23 + def parse_codeblock; end + + # Parse the fenced codeblock at the current location. + # + # source://kramdown//lib/kramdown/parser/kramdown/codeblock.rb#37 + def parse_codeblock_fenced; end + + # Parse the codespan at the current scanner location. + # + # source://kramdown//lib/kramdown/parser/kramdown/codespan.rb#17 + def parse_codespan; end + + # Parse the ordered or unordered list at the current location. + # + # source://kramdown//lib/kramdown/parser/kramdown/list.rb#153 + def parse_definition_list; end + + # Parse the emphasis at the current location. + # + # source://kramdown//lib/kramdown/parser/kramdown/emphasis.rb#17 + def parse_emphasis; end + + # Parse the EOB marker at the current location. + # + # source://kramdown//lib/kramdown/parser/kramdown/eob.rb#17 + def parse_eob_marker; end + + # Parse the backslash-escaped character at the current location. + # + # source://kramdown//lib/kramdown/parser/kramdown/escaped_chars.rb#17 + def parse_escaped_chars; end + + # Parse the generic extension at the current point. The parameter +type+ can either be :block + # or :span depending whether we parse a block or span extension tag. + # + # source://kramdown//lib/kramdown/parser/kramdown/extensions.rb#54 + def parse_extension_start_tag(type); end + + # Used for parsing the first line of a list item or a definition, i.e. the line with list item + # marker or the definition marker. + # + # source://kramdown//lib/kramdown/parser/kramdown/list.rb#32 + def parse_first_list_line(indentation, content); end + + # Parse the foot note definition at the current location. + # + # source://kramdown//lib/kramdown/parser/kramdown/footnote.rb#21 + def parse_footnote_definition; end + + # Parse the footnote marker at the current location. + # + # source://kramdown//lib/kramdown/parser/kramdown/footnote.rb#40 + def parse_footnote_marker; end + + # Parse the horizontal rule at the current location. + # + # source://kramdown//lib/kramdown/parser/kramdown/horizontal_rule.rb#17 + def parse_horizontal_rule; end + + # Parse the HTML entity at the current location. + # + # source://kramdown//lib/kramdown/parser/kramdown/html_entity.rb#17 + def parse_html_entity; end + + # Parse the inline math at the current location. + # + # source://kramdown//lib/kramdown/parser/kramdown/math.rb#44 + def parse_inline_math; end + + # Parse the line break at the current location. + # + # source://kramdown//lib/kramdown/parser/kramdown/line_break.rb#17 + def parse_line_break; end + + # Parse the link at the current scanner position. This method is used to parse normal links as + # well as image links. + # + # source://kramdown//lib/kramdown/parser/kramdown/link.rb#61 + def parse_link; end + + # Parse the link definition at the current location. + # + # source://kramdown//lib/kramdown/parser/kramdown/link.rb#24 + def parse_link_definition; end + + # Parse the ordered or unordered list at the current location. + # + # source://kramdown//lib/kramdown/parser/kramdown/list.rb#54 + def parse_list; end + + # Parse the paragraph at the current location. + # + # source://kramdown//lib/kramdown/parser/kramdown/paragraph.rb#31 + def parse_paragraph; end + + # Parse the Setext header at the current location. + # + # source://kramdown//lib/kramdown/parser/kramdown/header.rb#20 + def parse_setext_header; end + + # Parse the smart quotes at current location. + # + # source://kramdown//lib/kramdown/parser/kramdown/smart_quotes.rb#158 + def parse_smart_quotes; end + + # Parse the extension span at the current location. + # + # source://kramdown//lib/kramdown/parser/kramdown/extensions.rb#192 + def parse_span_extensions; end + + # Parse the HTML at the current position as span-level HTML. + # + # source://kramdown//lib/kramdown/parser/kramdown/html.rb#102 + def parse_span_html; end + + # Parse the table at the current location. + # + # source://kramdown//lib/kramdown/parser/kramdown/table.rb#25 + def parse_table; end + + # Parse the typographic symbols at the current location. + # + # source://kramdown//lib/kramdown/parser/kramdown/typographic_symbol.rb#22 + def parse_typographic_syms; end + + # Replace the abbreviation text with elements. + # + # source://kramdown//lib/kramdown/parser/kramdown/abbreviation.rb#41 + def replace_abbreviations(el, regexps = T.unsafe(nil)); end + + # Update the +ial+ with the information from the inline attribute list +opts+. + # + # source://kramdown//lib/kramdown/parser/kramdown/extensions.rb#41 + def update_ial_with_ial(ial, opts); end + + protected + + # source://kramdown//lib/kramdown/parser/kramdown/header.rb#59 + def add_header(level, text, id); end + + # Adapt the object to allow parsing like specified in the options. + # + # source://kramdown//lib/kramdown/parser/kramdown.rb#121 + def configure_parser; end + + # Create a new block-level element, taking care of applying a preceding block IAL if it + # exists. This method should always be used for creating a block-level element! + # + # source://kramdown//lib/kramdown/parser/kramdown.rb#305 + def new_block_el(*args); end + + # Parse all block-level elements in +text+ into the element +el+. + # + # source://kramdown//lib/kramdown/parser/kramdown.rb#140 + def parse_blocks(el, text = T.unsafe(nil)); end + + # Returns header text and optional ID. + # + # source://kramdown//lib/kramdown/parser/kramdown/header.rb#47 + def parse_header_contents; end + + # Parse all span-level elements in the source string of @src into +el+. + # + # If the parameter +stop_re+ (a regexp) is used, parsing is immediately stopped if the regexp + # matches and if no block is given or if a block is given and it returns +true+. + # + # The parameter +parsers+ can be used to specify the (span-level) parsing methods that should + # be used for parsing. + # + # The parameter +text_type+ specifies the type which should be used for created text nodes. + # + # source://kramdown//lib/kramdown/parser/kramdown.rb#214 + def parse_spans(el, stop_re = T.unsafe(nil), parsers = T.unsafe(nil), text_type = T.unsafe(nil)); end + + # Reset the current parsing environment. The parameter +env+ can be used to set initial + # values for one or more environment variables. + # + # source://kramdown//lib/kramdown/parser/kramdown.rb#253 + def reset_env(opts = T.unsafe(nil)); end + + # Restore the current parsing environment. + # + # source://kramdown//lib/kramdown/parser/kramdown.rb#268 + def restore_env(env); end + + # Return the current parsing environment. + # + # source://kramdown//lib/kramdown/parser/kramdown.rb#263 + def save_env; end + + # Create the needed span parser regexps. + # + # source://kramdown//lib/kramdown/parser/kramdown.rb#134 + def span_parser_regexps(parsers = T.unsafe(nil)); end + + # Update the given attributes hash +attr+ with the information from the inline attribute list + # +ial+ and all referenced ALDs. + # + # source://kramdown//lib/kramdown/parser/kramdown.rb#274 + def update_attr_with_ial(attr, ial); end + + # + # Update the parser specific link definitions with the data from +link_defs+ (the value of the + # :link_defs option). + # + # The parameter +link_defs+ is a hash where the keys are possibly unnormalized link IDs and + # the values are two element arrays consisting of the link target and a title (can be +nil+). + # + # source://kramdown//lib/kramdown/parser/kramdown.rb#116 + def update_link_definitions(link_defs); end + + # Update the raw text for automatic ID generation. + # + # source://kramdown//lib/kramdown/parser/kramdown.rb#288 + def update_raw_text(item); end + + # Update the tree by parsing all :+raw_text+ elements with the span-level parser (resets the + # environment) and by updating the attributes from the IALs. + # + # source://kramdown//lib/kramdown/parser/kramdown.rb#166 + def update_tree(element); end + + private + + # precomputed patterns for indentations 1..4 and fallback expression + # to compute pattern when indentation is outside the 1..4 range. + # + # source://kramdown//lib/kramdown/parser/kramdown/list.rb#258 + def fetch_pattern(type, indentation); end + + # source://kramdown//lib/kramdown/parser/kramdown.rb#200 + def span_pattern_cache(stop_re, span_start); end + + class << self + # Add a parser method + # + # * with the given +name+, + # * using +start_re+ as start regexp + # * and, for span parsers, +span_start+ as a String that can be used in a regexp and + # which identifies the starting character(s) + # + # to the registry. The method name is automatically derived from the +name+ or can explicitly + # be set by using the +meth_name+ parameter. + # + # source://kramdown//lib/kramdown/parser/kramdown.rb#328 + def define_parser(name, start_re, span_start = T.unsafe(nil), meth_name = T.unsafe(nil)); end + + # Return +true+ if there is a parser called +name+. + # + # @return [Boolean] + # + # source://kramdown//lib/kramdown/parser/kramdown.rb#339 + def has_parser?(name); end + + # Return the Data structure for the parser +name+. + # + # source://kramdown//lib/kramdown/parser/kramdown.rb#334 + def parser(name = T.unsafe(nil)); end + end +end + +# source://kramdown//lib/kramdown/parser/kramdown/abbreviation.rb#14 +Kramdown::Parser::Kramdown::ABBREV_DEFINITION_START = T.let(T.unsafe(nil), Regexp) + +# source://kramdown//lib/kramdown/parser/kramdown/autolink.rb#14 +Kramdown::Parser::Kramdown::ACHARS = T.let(T.unsafe(nil), String) + +# source://kramdown//lib/kramdown/parser/kramdown/extensions.rb#140 +Kramdown::Parser::Kramdown::ALD_ANY_CHARS = T.let(T.unsafe(nil), Regexp) + +# source://kramdown//lib/kramdown/parser/kramdown/extensions.rb#142 +Kramdown::Parser::Kramdown::ALD_CLASS_NAME = T.let(T.unsafe(nil), Regexp) + +# source://kramdown//lib/kramdown/parser/kramdown/extensions.rb#139 +Kramdown::Parser::Kramdown::ALD_ID_CHARS = T.let(T.unsafe(nil), Regexp) + +# source://kramdown//lib/kramdown/parser/kramdown/extensions.rb#141 +Kramdown::Parser::Kramdown::ALD_ID_NAME = T.let(T.unsafe(nil), Regexp) + +# source://kramdown//lib/kramdown/parser/kramdown/extensions.rb#150 +Kramdown::Parser::Kramdown::ALD_START = T.let(T.unsafe(nil), Regexp) + +# source://kramdown//lib/kramdown/parser/kramdown/extensions.rb#149 +Kramdown::Parser::Kramdown::ALD_TYPE_ANY = T.let(T.unsafe(nil), Regexp) + +# source://kramdown//lib/kramdown/parser/kramdown/extensions.rb#144 +Kramdown::Parser::Kramdown::ALD_TYPE_CLASS_NAME = T.let(T.unsafe(nil), Regexp) + +# source://kramdown//lib/kramdown/parser/kramdown/extensions.rb#145 +Kramdown::Parser::Kramdown::ALD_TYPE_ID_NAME = T.let(T.unsafe(nil), Regexp) + +# source://kramdown//lib/kramdown/parser/kramdown/extensions.rb#146 +Kramdown::Parser::Kramdown::ALD_TYPE_ID_OR_CLASS = T.let(T.unsafe(nil), Regexp) + +# source://kramdown//lib/kramdown/parser/kramdown/extensions.rb#147 +Kramdown::Parser::Kramdown::ALD_TYPE_ID_OR_CLASS_MULTI = T.let(T.unsafe(nil), Regexp) + +# source://kramdown//lib/kramdown/parser/kramdown/extensions.rb#143 +Kramdown::Parser::Kramdown::ALD_TYPE_KEY_VALUE_PAIR = T.let(T.unsafe(nil), Regexp) + +# source://kramdown//lib/kramdown/parser/kramdown/extensions.rb#148 +Kramdown::Parser::Kramdown::ALD_TYPE_REF = T.let(T.unsafe(nil), Regexp) + +# source://kramdown//lib/kramdown/parser/kramdown/header.rb#29 +Kramdown::Parser::Kramdown::ATX_HEADER_START = T.let(T.unsafe(nil), Regexp) + +# source://kramdown//lib/kramdown/parser/kramdown/autolink.rb#16 +Kramdown::Parser::Kramdown::AUTOLINK_START = T.let(T.unsafe(nil), Regexp) + +# source://kramdown//lib/kramdown/parser/kramdown/autolink.rb#15 +Kramdown::Parser::Kramdown::AUTOLINK_START_STR = T.let(T.unsafe(nil), String) + +# source://kramdown//lib/kramdown/parser/kramdown/blank_line.rb#14 +Kramdown::Parser::Kramdown::BLANK_LINE = T.let(T.unsafe(nil), Regexp) + +# source://kramdown//lib/kramdown/parser/kramdown/blockquote.rb#18 +Kramdown::Parser::Kramdown::BLOCKQUOTE_START = T.let(T.unsafe(nil), Regexp) + +# source://kramdown//lib/kramdown/parser/kramdown/block_boundary.rb#18 +Kramdown::Parser::Kramdown::BLOCK_BOUNDARY = T.let(T.unsafe(nil), Regexp) + +# source://kramdown//lib/kramdown/parser/kramdown/extensions.rb#160 +Kramdown::Parser::Kramdown::BLOCK_EXTENSIONS_START = T.let(T.unsafe(nil), Regexp) + +# source://kramdown//lib/kramdown/parser/kramdown/math.rb#16 +Kramdown::Parser::Kramdown::BLOCK_MATH_START = T.let(T.unsafe(nil), Regexp) + +# source://kramdown//lib/kramdown/parser/kramdown/codeblock.rb#20 +Kramdown::Parser::Kramdown::CODEBLOCK_MATCH = T.let(T.unsafe(nil), Regexp) + +# source://kramdown//lib/kramdown/parser/kramdown/codeblock.rb#19 +Kramdown::Parser::Kramdown::CODEBLOCK_START = T.let(T.unsafe(nil), Regexp) + +# source://kramdown//lib/kramdown/parser/kramdown/codespan.rb#14 +Kramdown::Parser::Kramdown::CODESPAN_DELIMITER = T.let(T.unsafe(nil), Regexp) + +# source://kramdown//lib/kramdown/parser/kramdown/list.rb#150 +Kramdown::Parser::Kramdown::DEFINITION_LIST_START = T.let(T.unsafe(nil), Regexp) + +# Struct class holding all the needed data for one block/span-level parser method. +# +# source://kramdown//lib/kramdown/parser/kramdown.rb#317 +class Kramdown::Parser::Kramdown::Data < ::Struct + # Returns the value of attribute method + # + # @return [Object] the current value of method + def method; end + + # Sets the attribute method + # + # @param value [Object] the value to set the attribute method to. + # @return [Object] the newly set value + def method=(_); end + + # Returns the value of attribute name + # + # @return [Object] the current value of name + def name; end + + # Sets the attribute name + # + # @param value [Object] the value to set the attribute name to. + # @return [Object] the newly set value + def name=(_); end + + # Returns the value of attribute span_start + # + # @return [Object] the current value of span_start + def span_start; end + + # Sets the attribute span_start + # + # @param value [Object] the value to set the attribute span_start to. + # @return [Object] the newly set value + def span_start=(_); end + + # Returns the value of attribute start_re + # + # @return [Object] the current value of start_re + def start_re; end + + # Sets the attribute start_re + # + # @param value [Object] the value to set the attribute start_re to. + # @return [Object] the newly set value + def start_re=(_); end + + class << self + def [](*_arg0); end + def inspect; end + def keyword_init?; end + def members; end + def new(*_arg0); end + end +end + +# source://kramdown//lib/kramdown/parser/kramdown/emphasis.rb#14 +Kramdown::Parser::Kramdown::EMPHASIS_START = T.let(T.unsafe(nil), Regexp) + +# source://kramdown//lib/kramdown/parser/kramdown/eob.rb#14 +Kramdown::Parser::Kramdown::EOB_MARKER = T.let(T.unsafe(nil), Regexp) + +# source://kramdown//lib/kramdown/parser/kramdown/escaped_chars.rb#14 +Kramdown::Parser::Kramdown::ESCAPED_CHARS = T.let(T.unsafe(nil), Regexp) + +# source://kramdown//lib/kramdown/parser/kramdown/extensions.rb#154 +Kramdown::Parser::Kramdown::EXT_BLOCK_START = T.let(T.unsafe(nil), Regexp) + +# source://kramdown//lib/kramdown/parser/kramdown/extensions.rb#155 +Kramdown::Parser::Kramdown::EXT_BLOCK_STOP_STR = T.let(T.unsafe(nil), String) + +# source://kramdown//lib/kramdown/parser/kramdown/extensions.rb#187 +Kramdown::Parser::Kramdown::EXT_SPAN_START = T.let(T.unsafe(nil), Regexp) + +# source://kramdown//lib/kramdown/parser/kramdown/extensions.rb#153 +Kramdown::Parser::Kramdown::EXT_START_STR = T.let(T.unsafe(nil), String) + +# source://kramdown//lib/kramdown/parser/kramdown/extensions.rb#152 +Kramdown::Parser::Kramdown::EXT_STOP_STR = T.let(T.unsafe(nil), String) + +# source://kramdown//lib/kramdown/parser/kramdown/codeblock.rb#34 +Kramdown::Parser::Kramdown::FENCED_CODEBLOCK_MATCH = T.let(T.unsafe(nil), Regexp) + +# source://kramdown//lib/kramdown/parser/kramdown/codeblock.rb#33 +Kramdown::Parser::Kramdown::FENCED_CODEBLOCK_START = T.let(T.unsafe(nil), Regexp) + +# source://kramdown//lib/kramdown/parser/kramdown/footnote.rb#18 +Kramdown::Parser::Kramdown::FOOTNOTE_DEFINITION_START = T.let(T.unsafe(nil), Regexp) + +# source://kramdown//lib/kramdown/parser/kramdown/footnote.rb#37 +Kramdown::Parser::Kramdown::FOOTNOTE_MARKER_START = T.let(T.unsafe(nil), Regexp) + +# source://kramdown//lib/kramdown/parser/kramdown/header.rb#44 +Kramdown::Parser::Kramdown::HEADER_ID = T.let(T.unsafe(nil), Regexp) + +# source://kramdown//lib/kramdown/parser/kramdown/horizontal_rule.rb#14 +Kramdown::Parser::Kramdown::HR_START = T.let(T.unsafe(nil), Regexp) + +# source://kramdown//lib/kramdown/parser/kramdown/html.rb#68 +Kramdown::Parser::Kramdown::HTML_BLOCK_START = T.let(T.unsafe(nil), Regexp) + +# Mapping of markdown attribute value to content model. I.e. :raw when "0", :default when "1" +# (use default content model for the HTML element), :span when "span", :block when block and +# for everything else +nil+ is returned. +# +# source://kramdown//lib/kramdown/parser/kramdown/html.rb#21 +Kramdown::Parser::Kramdown::HTML_MARKDOWN_ATTR_MAP = T.let(T.unsafe(nil), Hash) + +# source://kramdown//lib/kramdown/parser/kramdown/html.rb#99 +Kramdown::Parser::Kramdown::HTML_SPAN_START = T.let(T.unsafe(nil), Regexp) + +# source://kramdown//lib/kramdown/parser/kramdown/extensions.rb#157 +Kramdown::Parser::Kramdown::IAL_BLOCK = T.let(T.unsafe(nil), Regexp) + +# source://kramdown//lib/kramdown/parser/kramdown/extensions.rb#158 +Kramdown::Parser::Kramdown::IAL_BLOCK_START = T.let(T.unsafe(nil), Regexp) + +# source://kramdown//lib/kramdown/parser/kramdown/extensions.rb#14 +Kramdown::Parser::Kramdown::IAL_CLASS_ATTR = T.let(T.unsafe(nil), String) + +# source://kramdown//lib/kramdown/parser/kramdown/extensions.rb#188 +Kramdown::Parser::Kramdown::IAL_SPAN_START = T.let(T.unsafe(nil), Regexp) + +# Regexp for matching indentation (one tab or four spaces) +# +# source://kramdown//lib/kramdown/parser/kramdown.rb#344 +Kramdown::Parser::Kramdown::INDENT = T.let(T.unsafe(nil), Regexp) + +# source://kramdown//lib/kramdown/parser/kramdown/math.rb#41 +Kramdown::Parser::Kramdown::INLINE_MATH_START = T.let(T.unsafe(nil), Regexp) + +# source://kramdown//lib/kramdown/parser/kramdown/paragraph.rb#24 +Kramdown::Parser::Kramdown::LAZY_END = T.let(T.unsafe(nil), Regexp) + +# source://kramdown//lib/kramdown/parser/kramdown/paragraph.rb#20 +Kramdown::Parser::Kramdown::LAZY_END_HTML_SPAN_ELEMENTS = T.let(T.unsafe(nil), Array) + +# source://kramdown//lib/kramdown/parser/kramdown/paragraph.rb#21 +Kramdown::Parser::Kramdown::LAZY_END_HTML_START = T.let(T.unsafe(nil), Regexp) + +# source://kramdown//lib/kramdown/parser/kramdown/paragraph.rb#22 +Kramdown::Parser::Kramdown::LAZY_END_HTML_STOP = T.let(T.unsafe(nil), Regexp) + +# source://kramdown//lib/kramdown/parser/kramdown/line_break.rb#14 +Kramdown::Parser::Kramdown::LINE_BREAK = T.let(T.unsafe(nil), Regexp) + +# source://kramdown//lib/kramdown/parser/kramdown/link.rb#53 +Kramdown::Parser::Kramdown::LINK_BRACKET_STOP_RE = T.let(T.unsafe(nil), Regexp) + +# source://kramdown//lib/kramdown/parser/kramdown/link.rb#21 +Kramdown::Parser::Kramdown::LINK_DEFINITION_START = T.let(T.unsafe(nil), Regexp) + +# source://kramdown//lib/kramdown/parser/kramdown/link.rb#55 +Kramdown::Parser::Kramdown::LINK_INLINE_ID_RE = T.let(T.unsafe(nil), Regexp) + +# source://kramdown//lib/kramdown/parser/kramdown/link.rb#56 +Kramdown::Parser::Kramdown::LINK_INLINE_TITLE_RE = T.let(T.unsafe(nil), Regexp) + +# source://kramdown//lib/kramdown/parser/kramdown/link.rb#54 +Kramdown::Parser::Kramdown::LINK_PAREN_STOP_RE = T.let(T.unsafe(nil), Regexp) + +# source://kramdown//lib/kramdown/parser/kramdown/link.rb#57 +Kramdown::Parser::Kramdown::LINK_START = T.let(T.unsafe(nil), Regexp) + +# source://kramdown//lib/kramdown/parser/kramdown/list.rb#19 +Kramdown::Parser::Kramdown::LIST_ITEM_IAL = T.let(T.unsafe(nil), Regexp) + +# source://kramdown//lib/kramdown/parser/kramdown/list.rb#20 +Kramdown::Parser::Kramdown::LIST_ITEM_IAL_CHECK = T.let(T.unsafe(nil), Regexp) + +# source://kramdown//lib/kramdown/parser/kramdown/list.rb#51 +Kramdown::Parser::Kramdown::LIST_START = T.let(T.unsafe(nil), Regexp) + +# source://kramdown//lib/kramdown/parser/kramdown/list.rb#50 +Kramdown::Parser::Kramdown::LIST_START_OL = T.let(T.unsafe(nil), Regexp) + +# source://kramdown//lib/kramdown/parser/kramdown/list.rb#49 +Kramdown::Parser::Kramdown::LIST_START_UL = T.let(T.unsafe(nil), Regexp) + +# Regexp for matching the optional space (zero or up to three spaces) +# +# source://kramdown//lib/kramdown/parser/kramdown.rb#346 +Kramdown::Parser::Kramdown::OPT_SPACE = T.let(T.unsafe(nil), Regexp) + +# source://kramdown//lib/kramdown/parser/kramdown/paragraph.rb#28 +Kramdown::Parser::Kramdown::PARAGRAPH_END = T.let(T.unsafe(nil), Regexp) + +# source://kramdown//lib/kramdown/parser/kramdown/paragraph.rb#27 +Kramdown::Parser::Kramdown::PARAGRAPH_MATCH = T.let(T.unsafe(nil), Regexp) + +# source://kramdown//lib/kramdown/parser/kramdown/paragraph.rb#26 +Kramdown::Parser::Kramdown::PARAGRAPH_START = T.let(T.unsafe(nil), Regexp) + +# source://kramdown//lib/kramdown/parser/kramdown/list.rb#22 +Kramdown::Parser::Kramdown::PARSE_FIRST_LIST_LINE_REGEXP_CACHE = T.let(T.unsafe(nil), Hash) + +# source://kramdown//lib/kramdown/parser/kramdown/list.rb#47 +Kramdown::Parser::Kramdown::PATTERN_TAIL = T.let(T.unsafe(nil), Regexp) + +# source://kramdown//lib/kramdown/parser/kramdown/header.rb#17 +Kramdown::Parser::Kramdown::SETEXT_HEADER_START = T.let(T.unsafe(nil), Regexp) + +# source://kramdown//lib/kramdown/parser/kramdown/smart_quotes.rb#155 +Kramdown::Parser::Kramdown::SMART_QUOTES_RE = T.let(T.unsafe(nil), Regexp) + +# source://kramdown//lib/kramdown/parser/kramdown/extensions.rb#189 +Kramdown::Parser::Kramdown::SPAN_EXTENSIONS_START = T.let(T.unsafe(nil), Regexp) + +# source://kramdown//lib/kramdown/parser/kramdown/smart_quotes.rb#122 +Kramdown::Parser::Kramdown::SQ_CLOSE = T.let(T.unsafe(nil), String) + +# source://kramdown//lib/kramdown/parser/kramdown/smart_quotes.rb#121 +Kramdown::Parser::Kramdown::SQ_PUNCT = T.let(T.unsafe(nil), String) + +# source://kramdown//lib/kramdown/parser/kramdown/smart_quotes.rb#124 +Kramdown::Parser::Kramdown::SQ_RULES = T.let(T.unsafe(nil), Array) + +# '" +# +# source://kramdown//lib/kramdown/parser/kramdown/smart_quotes.rb#145 +Kramdown::Parser::Kramdown::SQ_SUBSTS = T.let(T.unsafe(nil), Hash) + +# source://kramdown//lib/kramdown/parser/kramdown/table.rb#18 +Kramdown::Parser::Kramdown::TABLE_FSEP_LINE = T.let(T.unsafe(nil), Regexp) + +# source://kramdown//lib/kramdown/parser/kramdown/table.rb#17 +Kramdown::Parser::Kramdown::TABLE_HSEP_ALIGN = T.let(T.unsafe(nil), Regexp) + +# source://kramdown//lib/kramdown/parser/kramdown/table.rb#21 +Kramdown::Parser::Kramdown::TABLE_LINE = T.let(T.unsafe(nil), Regexp) + +# source://kramdown//lib/kramdown/parser/kramdown/table.rb#20 +Kramdown::Parser::Kramdown::TABLE_PIPE_CHECK = T.let(T.unsafe(nil), Regexp) + +# source://kramdown//lib/kramdown/parser/kramdown/table.rb#19 +Kramdown::Parser::Kramdown::TABLE_ROW_LINE = T.let(T.unsafe(nil), Regexp) + +# source://kramdown//lib/kramdown/parser/kramdown/table.rb#16 +Kramdown::Parser::Kramdown::TABLE_SEP_LINE = T.let(T.unsafe(nil), Regexp) + +# source://kramdown//lib/kramdown/parser/kramdown/table.rb#22 +Kramdown::Parser::Kramdown::TABLE_START = T.let(T.unsafe(nil), Regexp) + +# source://kramdown//lib/kramdown/parser/kramdown/html.rb#23 +Kramdown::Parser::Kramdown::TRAILING_WHITESPACE = T.let(T.unsafe(nil), Regexp) + +# source://kramdown//lib/kramdown/parser/kramdown/typographic_symbol.rb#14 +Kramdown::Parser::Kramdown::TYPOGRAPHIC_SYMS = T.let(T.unsafe(nil), Array) + +# source://kramdown//lib/kramdown/parser/kramdown/typographic_symbol.rb#19 +Kramdown::Parser::Kramdown::TYPOGRAPHIC_SYMS_RE = T.let(T.unsafe(nil), Regexp) + +# source://kramdown//lib/kramdown/parser/kramdown/typographic_symbol.rb#18 +Kramdown::Parser::Kramdown::TYPOGRAPHIC_SYMS_SUBST = T.let(T.unsafe(nil), Hash) + +# Used for parsing a document in Markdown format. +# +# This parser is based on the kramdown parser and removes the parser methods for the additional +# non-Markdown features. However, since some things are handled differently by the kramdown +# parser methods (like deciding when a list item contains just text), this parser differs from +# real Markdown parsers in some respects. +# +# Note, though, that the parser basically fails just one of the Markdown test cases (some others +# also fail but those failures are negligible). +# +# source://kramdown//lib/kramdown/parser/markdown.rb#25 +class Kramdown::Parser::Markdown < ::Kramdown::Parser::Kramdown + # @return [Markdown] a new instance of Markdown + # + # source://kramdown//lib/kramdown/parser/markdown.rb#32 + def initialize(source, options); end +end + +# :stopdoc: +# +# source://kramdown//lib/kramdown/parser/markdown.rb#40 +Kramdown::Parser::Markdown::BLOCK_BOUNDARY = T.let(T.unsafe(nil), Regexp) + +# source://kramdown//lib/kramdown/parser/markdown.rb#43 +Kramdown::Parser::Markdown::CODEBLOCK_MATCH = T.let(T.unsafe(nil), Regexp) + +# Array with all the parsing methods that should be removed from the standard kramdown parser. +# +# source://kramdown//lib/kramdown/parser/markdown.rb#28 +Kramdown::Parser::Markdown::EXTENDED = T.let(T.unsafe(nil), Array) + +# source://kramdown//lib/kramdown/parser/markdown.rb#46 +Kramdown::Parser::Markdown::IAL_RAND_CHARS = T.let(T.unsafe(nil), Array) + +# source://kramdown//lib/kramdown/parser/markdown.rb#47 +Kramdown::Parser::Markdown::IAL_RAND_STRING = T.let(T.unsafe(nil), String) + +# source://kramdown//lib/kramdown/parser/markdown.rb#49 +Kramdown::Parser::Markdown::IAL_SPAN_START = T.let(T.unsafe(nil), Regexp) + +# source://kramdown//lib/kramdown/parser/markdown.rb#41 +Kramdown::Parser::Markdown::LAZY_END = T.let(T.unsafe(nil), Regexp) + +# source://kramdown//lib/kramdown/parser/markdown.rb#48 +Kramdown::Parser::Markdown::LIST_ITEM_IAL = T.let(T.unsafe(nil), Regexp) + +# source://kramdown//lib/kramdown/parser/markdown.rb#44 +Kramdown::Parser::Markdown::PARAGRAPH_END = T.let(T.unsafe(nil), Regexp) + +# == \Utils Module +# +# This module contains utility class/modules/methods that can be used by both parsers and +# converters. +# +# source://kramdown//lib/kramdown/utils.rb#16 +module Kramdown::Utils + class << self + # Treat +name+ as if it were snake cased (e.g. snake_case) and camelize it (e.g. SnakeCase). + # + # source://kramdown//lib/kramdown/utils.rb#26 + def camelize(name); end + + # source://kramdown//lib/kramdown/utils.rb#39 + def deep_const_get(str); end + + # Treat +name+ as if it were camelized (e.g. CamelizedName) and snake-case it (e.g. camelized_name). + # + # source://kramdown//lib/kramdown/utils.rb#31 + def snake_case(name); end + end +end + +# Methods for registering configurable extensions. +# +# source://kramdown//lib/kramdown/utils/configurable.rb#14 +module Kramdown::Utils::Configurable + # Create a new configurable extension called +name+. + # + # Three methods will be defined on the calling object which allow to use this configurable + # extension: + # + # configurables:: Returns a hash of hashes that is used to store all configurables of the + # object. + # + # (ext_name):: Return the configured extension +ext_name+. + # + # add_(ext_name, data=nil, &block):: Define an extension +ext_name+ by specifying either + # the data as argument or by using a block. + # + # source://kramdown//lib/kramdown/utils/configurable.rb#28 + def configurable(name); end +end + +# Provides convenience methods for handling named and numeric entities. +# +# source://kramdown//lib/kramdown/utils/entities.rb#15 +module Kramdown::Utils::Entities + private + + # Return the entity for the given code point or name +point_or_name+. + # + # source://kramdown//lib/kramdown/utils/entities.rb#334 + def entity(point_or_name); end + + class << self + # Return the entity for the given code point or name +point_or_name+. + # + # source://kramdown//lib/kramdown/utils/entities.rb#334 + def entity(point_or_name); end + end +end + +# Contains the mapping of code point (or name) to the actual Entity object. +# +# source://kramdown//lib/kramdown/utils/entities.rb#317 +Kramdown::Utils::Entities::ENTITY_MAP = T.let(T.unsafe(nil), Hash) + +# Array of arrays. Each sub-array specifies a code point and the associated name. +# +# This table is not used directly -- Entity objects are automatically created from it and put +# into a Hash map when this file is loaded. +# +# source://kramdown//lib/kramdown/utils/entities.rb#29 +Kramdown::Utils::Entities::ENTITY_TABLE = T.let(T.unsafe(nil), Array) + +# Represents an entity that has a +code_point+ and +name+. +# +# source://kramdown//lib/kramdown/utils/entities.rb#18 +class Kramdown::Utils::Entities::Entity < ::Struct + # Return the UTF8 representation of the entity. + # + # source://kramdown//lib/kramdown/utils/entities.rb#20 + def char; end + + # Returns the value of attribute code_point + # + # @return [Object] the current value of code_point + def code_point; end + + # Sets the attribute code_point + # + # @param value [Object] the value to set the attribute code_point to. + # @return [Object] the newly set value + def code_point=(_); end + + # Returns the value of attribute name + # + # @return [Object] the current value of name + def name; end + + # Sets the attribute name + # + # @param value [Object] the value to set the attribute name to. + # @return [Object] the newly set value + def name=(_); end + + class << self + def [](*_arg0); end + def inspect; end + def keyword_init?; end + def members; end + def new(*_arg0); end + end +end + +# Provides convenience methods for HTML related tasks. +# +# *Note* that this module has to be mixed into a class that has a @root (containing an element +# of type :root) and an @options (containing an options hash) instance variable so that some of +# the methods can work correctly. +# +# source://kramdown//lib/kramdown/utils/html.rb#21 +module Kramdown::Utils::Html + # Convert the entity +e+ to a string. The optional parameter +original+ may contain the + # original representation of the entity. + # + # This method uses the option +entity_output+ to determine the output form for the entity. + # + # source://kramdown//lib/kramdown/utils/html.rb#27 + def entity_to_str(e, original = T.unsafe(nil)); end + + # Escape the special HTML characters in the string +str+. The parameter +type+ specifies what + # is escaped: :all - all special HTML characters except the quotation mark as well as + # entities, :text - all special HTML characters except the quotation mark but no entities and + # :attribute - all special HTML characters including the quotation mark but no entities. + # + # source://kramdown//lib/kramdown/utils/html.rb#69 + def escape_html(str, type = T.unsafe(nil)); end + + # source://kramdown//lib/kramdown/utils/html.rb#74 + def fix_cjk_line_break(str); end + + # Return the HTML representation of the attributes +attr+. + # + # source://kramdown//lib/kramdown/utils/html.rb#44 + def html_attributes(attr); end +end + +# source://kramdown//lib/kramdown/utils/html.rb#59 +Kramdown::Utils::Html::ESCAPE_ALL_RE = T.let(T.unsafe(nil), Regexp) + +# source://kramdown//lib/kramdown/utils/html.rb#61 +Kramdown::Utils::Html::ESCAPE_ATTRIBUTE_RE = T.let(T.unsafe(nil), Regexp) + +# :stopdoc: +# +# source://kramdown//lib/kramdown/utils/html.rb#53 +Kramdown::Utils::Html::ESCAPE_MAP = T.let(T.unsafe(nil), Hash) + +# source://kramdown//lib/kramdown/utils/html.rb#62 +Kramdown::Utils::Html::ESCAPE_RE_FROM_TYPE = T.let(T.unsafe(nil), Hash) + +# source://kramdown//lib/kramdown/utils/html.rb#60 +Kramdown::Utils::Html::ESCAPE_TEXT_RE = T.let(T.unsafe(nil), Regexp) + +# source://kramdown//lib/kramdown/utils/html.rb#73 +Kramdown::Utils::Html::REDUNDANT_LINE_BREAK_REGEX = T.let(T.unsafe(nil), Regexp) + +# A simple least recently used (LRU) cache. +# +# The cache relies on the fact that Ruby's Hash class maintains insertion order. So deleting +# and re-inserting a key-value pair on access moves the key to the last position. When an +# entry is added and the cache is full, the first entry is removed. +# +# source://kramdown//lib/kramdown/utils/lru_cache.rb#18 +class Kramdown::Utils::LRUCache + # Creates a new LRUCache that can hold +size+ entries. + # + # @return [LRUCache] a new instance of LRUCache + # + # source://kramdown//lib/kramdown/utils/lru_cache.rb#21 + def initialize(size); end + + # Returns the stored value for +key+ or +nil+ if no value was stored under the key. + # + # source://kramdown//lib/kramdown/utils/lru_cache.rb#27 + def [](key); end + + # Stores the +value+ under the +key+. + # + # source://kramdown//lib/kramdown/utils/lru_cache.rb#32 + def []=(key, value); end +end + +# This patched StringScanner adds line number information for current scan position and a +# start_line_number override for nested StringScanners. +# +# source://kramdown//lib/kramdown/utils/string_scanner.rb#17 +class Kramdown::Utils::StringScanner < ::StringScanner + # Takes the start line number as optional second argument. + # + # Note: The original second argument is no longer used so this should be safe. + # + # @return [StringScanner] a new instance of StringScanner + # + # source://kramdown//lib/kramdown/utils/string_scanner.rb#26 + def initialize(string, start_line_number = T.unsafe(nil)); end + + # Returns the line number for current charpos. + # + # NOTE: Requires that all line endings are normalized to '\n' + # + # NOTE: Normally we'd have to add one to the count of newlines to get the correct line number. + # However we add the one indirectly by using a one-based start_line_number. + # + # source://kramdown//lib/kramdown/utils/string_scanner.rb#67 + def current_line_number; end + + # Sets the byte position of the scan pointer. + # + # Note: This also resets some internal variables, so always use pos= when setting the position + # and don't use any other method for that! + # + # source://kramdown//lib/kramdown/utils/string_scanner.rb#37 + def pos=(pos); end + + # Revert the position to one saved by #save_pos. + # + # source://kramdown//lib/kramdown/utils/string_scanner.rb#56 + def revert_pos(data); end + + # Return information needed to revert the byte position of the string scanner in a performant + # way. + # + # The returned data can be fed to #revert_pos to revert the position to the saved one. + # + # Note: Just saving #pos won't be enough. + # + # source://kramdown//lib/kramdown/utils/string_scanner.rb#51 + def save_pos; end + + # The start line number. Used for nested StringScanners that scan a sub-string of the source + # document. The kramdown parser uses this, e.g., for span level parsers. + # + # source://kramdown//lib/kramdown/utils/string_scanner.rb#21 + def start_line_number; end +end + +# The kramdown version. +# +# source://kramdown//lib/kramdown/version.rb#13 +Kramdown::VERSION = T.let(T.unsafe(nil), String) diff --git a/Library/Homebrew/sorbet/rbi/gems/minitest@5.22.2.rbi b/Library/Homebrew/sorbet/rbi/gems/minitest@5.22.3.rbi similarity index 97% rename from Library/Homebrew/sorbet/rbi/gems/minitest@5.22.2.rbi rename to Library/Homebrew/sorbet/rbi/gems/minitest@5.22.3.rbi index 600ba58a7eaddd..7075d25b63e1fb 100644 --- a/Library/Homebrew/sorbet/rbi/gems/minitest@5.22.2.rbi +++ b/Library/Homebrew/sorbet/rbi/gems/minitest@5.22.3.rbi @@ -1340,27 +1340,27 @@ class Minitest::Test < ::Minitest::Runnable # LifecycleHooks # - # source://minitest//lib/minitest/test.rb#190 + # source://minitest//lib/minitest/test.rb#191 def capture_exceptions; end # source://minitest//lib/minitest/test.rb#15 def class_name; end - # source://minitest//lib/minitest/test.rb#207 + # source://minitest//lib/minitest/test.rb#208 def neuter_exception(e); end - # source://minitest//lib/minitest/test.rb#218 + # source://minitest//lib/minitest/test.rb#219 def new_exception(klass, msg, bt, kill = T.unsafe(nil)); end # Runs a single test with setup/teardown hooks. # - # source://minitest//lib/minitest/test.rb#86 + # source://minitest//lib/minitest/test.rb#87 def run; end - # source://minitest//lib/minitest/test.rb#200 + # source://minitest//lib/minitest/test.rb#201 def sanitize_exception(e); end - # source://minitest//lib/minitest/test.rb#232 + # source://minitest//lib/minitest/test.rb#233 def with_info_handler(&block); end class << self @@ -1391,18 +1391,19 @@ class Minitest::Test < ::Minitest::Runnable # source://minitest//lib/minitest/test.rb#48 def make_my_diffs_pretty!; end - # Call this at the top of your tests when you want to run your - # tests in parallel. In doing so, you're admitting that you rule - # and your tests are awesome. + # Call this at the top of your tests (inside the +Minitest::Test+ + # subclass or +describe+ block) when you want to run your tests in + # parallel. In doing so, you're admitting that you rule and your + # tests are awesome. # - # source://minitest//lib/minitest/test.rb#59 + # source://minitest//lib/minitest/test.rb#60 def parallelize_me!; end # Returns all instance methods starting with "test_". Based on # #test_order, the methods are either sorted, randomized # (default), or run in parallel. # - # source://minitest//lib/minitest/test.rb#69 + # source://minitest//lib/minitest/test.rb#70 def runnable_methods; end end end @@ -1411,7 +1412,7 @@ end # meant for library writers, NOT for regular test authors. See # #before_setup for an example. # -# source://minitest//lib/minitest/test.rb#113 +# source://minitest//lib/minitest/test.rb#114 module Minitest::Test::LifecycleHooks # Runs before every test, after setup. This hook is meant for # libraries to extend minitest. It is not meant to be used by @@ -1419,7 +1420,7 @@ module Minitest::Test::LifecycleHooks # # See #before_setup for an example. # - # source://minitest//lib/minitest/test.rb#163 + # source://minitest//lib/minitest/test.rb#164 def after_setup; end # Runs after every test, after teardown. This hook is meant for @@ -1428,7 +1429,7 @@ module Minitest::Test::LifecycleHooks # # See #before_setup for an example. # - # source://minitest//lib/minitest/test.rb#187 + # source://minitest//lib/minitest/test.rb#188 def after_teardown; end # Runs before every test, before setup. This hook is meant for @@ -1463,7 +1464,7 @@ module Minitest::Test::LifecycleHooks # include MyMinitestPlugin # end # - # source://minitest//lib/minitest/test.rb#148 + # source://minitest//lib/minitest/test.rb#149 def before_setup; end # Runs after every test, before teardown. This hook is meant for @@ -1472,19 +1473,19 @@ module Minitest::Test::LifecycleHooks # # See #before_setup for an example. # - # source://minitest//lib/minitest/test.rb#172 + # source://minitest//lib/minitest/test.rb#173 def before_teardown; end # Runs before every test. Use this to set up before each test # run. # - # source://minitest//lib/minitest/test.rb#154 + # source://minitest//lib/minitest/test.rb#155 def setup; end # Runs after every test. Use this to clean up after each test # run. # - # source://minitest//lib/minitest/test.rb#178 + # source://minitest//lib/minitest/test.rb#179 def teardown; end end diff --git a/Library/Homebrew/sorbet/rbi/gems/parallel_tests@4.5.1.rbi b/Library/Homebrew/sorbet/rbi/gems/parallel_tests@4.5.2.rbi similarity index 94% rename from Library/Homebrew/sorbet/rbi/gems/parallel_tests@4.5.1.rbi rename to Library/Homebrew/sorbet/rbi/gems/parallel_tests@4.5.2.rbi index 4fee77dca8850b..2c370c5a1137c9 100644 --- a/Library/Homebrew/sorbet/rbi/gems/parallel_tests@4.5.1.rbi +++ b/Library/Homebrew/sorbet/rbi/gems/parallel_tests@4.5.2.rbi @@ -13,10 +13,10 @@ module ParallelTests # # @return [Boolean] # - # source://parallel_tests//lib/parallel_tests.rb#50 + # source://parallel_tests//lib/parallel_tests.rb#52 def bundler_enabled?; end - # source://parallel_tests//lib/parallel_tests.rb#95 + # source://parallel_tests//lib/parallel_tests.rb#97 def delta; end # source://parallel_tests//lib/parallel_tests.rb#16 @@ -24,18 +24,18 @@ module ParallelTests # @return [Boolean] # - # source://parallel_tests//lib/parallel_tests.rb#66 + # source://parallel_tests//lib/parallel_tests.rb#68 def first_process?; end # @return [Boolean] # - # source://parallel_tests//lib/parallel_tests.rb#70 + # source://parallel_tests//lib/parallel_tests.rb#72 def last_process?; end - # source://parallel_tests//lib/parallel_tests.rb#91 + # source://parallel_tests//lib/parallel_tests.rb#93 def now; end - # source://parallel_tests//lib/parallel_tests.rb#87 + # source://parallel_tests//lib/parallel_tests.rb#89 def number_of_running_processes; end # source://parallel_tests//lib/parallel_tests.rb#41 @@ -47,13 +47,13 @@ module ParallelTests # source://parallel_tests//lib/parallel_tests.rb#45 def stop_all_processes; end - # source://parallel_tests//lib/parallel_tests.rb#82 + # source://parallel_tests//lib/parallel_tests.rb#84 def wait_for_other_processes_to_finish; end # source://parallel_tests//lib/parallel_tests.rb#24 def with_pid_file; end - # source://parallel_tests//lib/parallel_tests.rb#78 + # source://parallel_tests//lib/parallel_tests.rb#80 def with_ruby_binary(command); end end end diff --git a/Library/Homebrew/sorbet/rbi/gems/rubocop-ast@1.31.1.rbi b/Library/Homebrew/sorbet/rbi/gems/rubocop-ast@1.31.2.rbi similarity index 98% rename from Library/Homebrew/sorbet/rbi/gems/rubocop-ast@1.31.1.rbi rename to Library/Homebrew/sorbet/rbi/gems/rubocop-ast@1.31.2.rbi index 6f23dfb3bb315e..90a4d9c5341606 100644 --- a/Library/Homebrew/sorbet/rbi/gems/rubocop-ast@1.31.1.rbi +++ b/Library/Homebrew/sorbet/rbi/gems/rubocop-ast@1.31.2.rbi @@ -4841,116 +4841,116 @@ class RuboCop::AST::NodePattern::Parser < ::Racc::Parser # source://rubocop-ast//lib/rubocop/ast/node_pattern/parser.rb#19 def initialize(builder = T.unsafe(nil)); end - # source://rubocop-ast//lib/rubocop/ast/node_pattern/parser.racc.rb#333 + # source://rubocop-ast//lib/rubocop/ast/node_pattern/parser.racc.rb#335 def _reduce_10(val, _values); end - # source://rubocop-ast//lib/rubocop/ast/node_pattern/parser.racc.rb#337 + # source://rubocop-ast//lib/rubocop/ast/node_pattern/parser.racc.rb#339 def _reduce_11(val, _values); end # reduce 12 omitted # - # source://rubocop-ast//lib/rubocop/ast/node_pattern/parser.racc.rb#343 + # source://rubocop-ast//lib/rubocop/ast/node_pattern/parser.racc.rb#345 def _reduce_13(val, _values); end - # source://rubocop-ast//lib/rubocop/ast/node_pattern/parser.racc.rb#347 + # source://rubocop-ast//lib/rubocop/ast/node_pattern/parser.racc.rb#349 def _reduce_14(val, _values); end - # source://rubocop-ast//lib/rubocop/ast/node_pattern/parser.racc.rb#351 + # source://rubocop-ast//lib/rubocop/ast/node_pattern/parser.racc.rb#353 def _reduce_15(val, _values); end - # source://rubocop-ast//lib/rubocop/ast/node_pattern/parser.racc.rb#355 + # source://rubocop-ast//lib/rubocop/ast/node_pattern/parser.racc.rb#357 def _reduce_16(val, _values); end - # source://rubocop-ast//lib/rubocop/ast/node_pattern/parser.racc.rb#359 + # source://rubocop-ast//lib/rubocop/ast/node_pattern/parser.racc.rb#361 def _reduce_17(val, _values); end - # source://rubocop-ast//lib/rubocop/ast/node_pattern/parser.racc.rb#363 + # source://rubocop-ast//lib/rubocop/ast/node_pattern/parser.racc.rb#365 def _reduce_18(val, _values); end - # source://rubocop-ast//lib/rubocop/ast/node_pattern/parser.racc.rb#367 + # source://rubocop-ast//lib/rubocop/ast/node_pattern/parser.racc.rb#369 def _reduce_19(val, _values); end # reduce 1 omitted # - # source://rubocop-ast//lib/rubocop/ast/node_pattern/parser.racc.rb#301 + # source://rubocop-ast//lib/rubocop/ast/node_pattern/parser.racc.rb#303 def _reduce_2(val, _values); end - # source://rubocop-ast//lib/rubocop/ast/node_pattern/parser.racc.rb#371 + # source://rubocop-ast//lib/rubocop/ast/node_pattern/parser.racc.rb#373 def _reduce_20(val, _values); end - # source://rubocop-ast//lib/rubocop/ast/node_pattern/parser.racc.rb#375 + # source://rubocop-ast//lib/rubocop/ast/node_pattern/parser.racc.rb#377 def _reduce_21(val, _values); end - # source://rubocop-ast//lib/rubocop/ast/node_pattern/parser.racc.rb#379 + # source://rubocop-ast//lib/rubocop/ast/node_pattern/parser.racc.rb#381 def _reduce_22(val, _values); end # reduce 24 omitted # - # source://rubocop-ast//lib/rubocop/ast/node_pattern/parser.racc.rb#387 + # source://rubocop-ast//lib/rubocop/ast/node_pattern/parser.racc.rb#389 def _reduce_25(val, _values); end - # source://rubocop-ast//lib/rubocop/ast/node_pattern/parser.racc.rb#393 + # source://rubocop-ast//lib/rubocop/ast/node_pattern/parser.racc.rb#395 def _reduce_26(val, _values); end - # source://rubocop-ast//lib/rubocop/ast/node_pattern/parser.racc.rb#305 + # source://rubocop-ast//lib/rubocop/ast/node_pattern/parser.racc.rb#307 def _reduce_3(val, _values); end # reduce 32 omitted # - # source://rubocop-ast//lib/rubocop/ast/node_pattern/parser.racc.rb#413 + # source://rubocop-ast//lib/rubocop/ast/node_pattern/parser.racc.rb#415 def _reduce_33(val, _values); end # reduce 36 omitted # - # source://rubocop-ast//lib/rubocop/ast/node_pattern/parser.racc.rb#423 + # source://rubocop-ast//lib/rubocop/ast/node_pattern/parser.racc.rb#425 def _reduce_37(val, _values); end - # source://rubocop-ast//lib/rubocop/ast/node_pattern/parser.racc.rb#427 + # source://rubocop-ast//lib/rubocop/ast/node_pattern/parser.racc.rb#429 def _reduce_38(val, _values); end - # source://rubocop-ast//lib/rubocop/ast/node_pattern/parser.racc.rb#431 + # source://rubocop-ast//lib/rubocop/ast/node_pattern/parser.racc.rb#433 def _reduce_39(val, _values); end - # source://rubocop-ast//lib/rubocop/ast/node_pattern/parser.racc.rb#309 + # source://rubocop-ast//lib/rubocop/ast/node_pattern/parser.racc.rb#311 def _reduce_4(val, _values); end - # source://rubocop-ast//lib/rubocop/ast/node_pattern/parser.racc.rb#435 + # source://rubocop-ast//lib/rubocop/ast/node_pattern/parser.racc.rb#437 def _reduce_40(val, _values); end - # source://rubocop-ast//lib/rubocop/ast/node_pattern/parser.racc.rb#439 + # source://rubocop-ast//lib/rubocop/ast/node_pattern/parser.racc.rb#441 def _reduce_41(val, _values); end - # source://rubocop-ast//lib/rubocop/ast/node_pattern/parser.racc.rb#443 + # source://rubocop-ast//lib/rubocop/ast/node_pattern/parser.racc.rb#445 def _reduce_42(val, _values); end - # source://rubocop-ast//lib/rubocop/ast/node_pattern/parser.racc.rb#447 + # source://rubocop-ast//lib/rubocop/ast/node_pattern/parser.racc.rb#449 def _reduce_43(val, _values); end - # source://rubocop-ast//lib/rubocop/ast/node_pattern/parser.racc.rb#451 + # source://rubocop-ast//lib/rubocop/ast/node_pattern/parser.racc.rb#453 def _reduce_44(val, _values); end - # source://rubocop-ast//lib/rubocop/ast/node_pattern/parser.racc.rb#455 + # source://rubocop-ast//lib/rubocop/ast/node_pattern/parser.racc.rb#457 def _reduce_45(val, _values); end - # source://rubocop-ast//lib/rubocop/ast/node_pattern/parser.racc.rb#459 + # source://rubocop-ast//lib/rubocop/ast/node_pattern/parser.racc.rb#461 def _reduce_46(val, _values); end - # source://rubocop-ast//lib/rubocop/ast/node_pattern/parser.racc.rb#313 + # source://rubocop-ast//lib/rubocop/ast/node_pattern/parser.racc.rb#315 def _reduce_5(val, _values); end - # source://rubocop-ast//lib/rubocop/ast/node_pattern/parser.racc.rb#317 + # source://rubocop-ast//lib/rubocop/ast/node_pattern/parser.racc.rb#319 def _reduce_6(val, _values); end - # source://rubocop-ast//lib/rubocop/ast/node_pattern/parser.racc.rb#321 + # source://rubocop-ast//lib/rubocop/ast/node_pattern/parser.racc.rb#323 def _reduce_7(val, _values); end - # source://rubocop-ast//lib/rubocop/ast/node_pattern/parser.racc.rb#325 + # source://rubocop-ast//lib/rubocop/ast/node_pattern/parser.racc.rb#327 def _reduce_8(val, _values); end - # source://rubocop-ast//lib/rubocop/ast/node_pattern/parser.racc.rb#329 + # source://rubocop-ast//lib/rubocop/ast/node_pattern/parser.racc.rb#331 def _reduce_9(val, _values); end - # source://rubocop-ast//lib/rubocop/ast/node_pattern/parser.racc.rb#463 + # source://rubocop-ast//lib/rubocop/ast/node_pattern/parser.racc.rb#465 def _reduce_none(val, _values); end # source://forwardable/1.3.2/forwardable.rb#229 @@ -5010,10 +5010,10 @@ RuboCop::AST::NodePattern::Parser::Lexer = RuboCop::AST::NodePattern::Lexer # source://rubocop-ast//lib/rubocop/ast/node_pattern/parser.racc.rb#227 RuboCop::AST::NodePattern::Parser::Racc_arg = T.let(T.unsafe(nil), Array) -# source://rubocop-ast//lib/rubocop/ast/node_pattern/parser.racc.rb#293 +# source://rubocop-ast//lib/rubocop/ast/node_pattern/parser.racc.rb#295 RuboCop::AST::NodePattern::Parser::Racc_debug_parser = T.let(T.unsafe(nil), FalseClass) -# source://rubocop-ast//lib/rubocop/ast/node_pattern/parser.racc.rb#243 +# source://rubocop-ast//lib/rubocop/ast/node_pattern/parser.racc.rb#244 RuboCop::AST::NodePattern::Parser::Racc_token_to_s_table = T.let(T.unsafe(nil), Array) # Overrides Parser to use `WithMeta` variants and provide additional methods @@ -5150,7 +5150,37 @@ RuboCop::AST::NodePattern::Sets::SET_ANY_EMPTY = T.let(T.unsafe(nil), Set) RuboCop::AST::NodePattern::Sets::SET_ANY_EMPTY_NONE_ETC = T.let(T.unsafe(nil), Set) # source://rubocop-ast//lib/rubocop/ast/node_pattern/sets.rb#10 -RuboCop::AST::NodePattern::Sets::SET_ASSERT_EQUAL_REFUTE_EQUAL = T.let(T.unsafe(nil), Set) +RuboCop::AST::NodePattern::Sets::SET_ASSERT_EMPTY_ASSERT_NOT_EMPTY_REFUTE_EMPTY = T.let(T.unsafe(nil), Set) + +# source://rubocop-ast//lib/rubocop/ast/node_pattern/sets.rb#10 +RuboCop::AST::NodePattern::Sets::SET_ASSERT_EQUAL_ASSERT_NOT_EQUAL_REFUTE_EQUAL = T.let(T.unsafe(nil), Set) + +# source://rubocop-ast//lib/rubocop/ast/node_pattern/sets.rb#10 +RuboCop::AST::NodePattern::Sets::SET_ASSERT_FALSE = T.let(T.unsafe(nil), Set) + +# source://rubocop-ast//lib/rubocop/ast/node_pattern/sets.rb#10 +RuboCop::AST::NodePattern::Sets::SET_ASSERT_INCLUDES_ASSERT_NOT_INCLUDES_REFUTE_INCLUDES = T.let(T.unsafe(nil), Set) + +# source://rubocop-ast//lib/rubocop/ast/node_pattern/sets.rb#10 +RuboCop::AST::NodePattern::Sets::SET_ASSERT_INSTANCE_OF_ASSERT_NOT_INSTANCE_OF_REFUTE_INSTANCE_OF = T.let(T.unsafe(nil), Set) + +# source://rubocop-ast//lib/rubocop/ast/node_pattern/sets.rb#10 +RuboCop::AST::NodePattern::Sets::SET_ASSERT_IN_DELTA_ASSERT_NOT_IN_DELTA_REFUTE_IN_DELTA = T.let(T.unsafe(nil), Set) + +# source://rubocop-ast//lib/rubocop/ast/node_pattern/sets.rb#10 +RuboCop::AST::NodePattern::Sets::SET_ASSERT_KIND_OF_ASSERT_NOT_KIND_OF_REFUTE_KIND_OF = T.let(T.unsafe(nil), Set) + +# source://rubocop-ast//lib/rubocop/ast/node_pattern/sets.rb#10 +RuboCop::AST::NodePattern::Sets::SET_ASSERT_MATCH_REFUTE_MATCH = T.let(T.unsafe(nil), Set) + +# source://rubocop-ast//lib/rubocop/ast/node_pattern/sets.rb#10 +RuboCop::AST::NodePattern::Sets::SET_ASSERT_NIL_ASSERT_NOT_NIL_REFUTE_NIL = T.let(T.unsafe(nil), Set) + +# source://rubocop-ast//lib/rubocop/ast/node_pattern/sets.rb#10 +RuboCop::AST::NodePattern::Sets::SET_ASSERT_PREDICATE_ASSERT_NOT_PREDICATE_REFUTE_PREDICATE = T.let(T.unsafe(nil), Set) + +# source://rubocop-ast//lib/rubocop/ast/node_pattern/sets.rb#10 +RuboCop::AST::NodePattern::Sets::SET_ASSERT_TRUE = T.let(T.unsafe(nil), Set) # source://rubocop-ast//lib/rubocop/ast/node_pattern/sets.rb#10 RuboCop::AST::NodePattern::Sets::SET_ATTR_READER_ATTR_WRITER_ATTR_ACCESSOR = T.let(T.unsafe(nil), Set) @@ -5910,7 +5940,7 @@ class RuboCop::AST::ProcessedSource # source://rubocop-ast//lib/rubocop/ast/processed_source.rb#29 def initialize(source, ruby_version, path = T.unsafe(nil), parser_engine: T.unsafe(nil)); end - # source://rubocop-ast//lib/rubocop/ast/processed_source.rb#72 + # source://rubocop-ast//lib/rubocop/ast/processed_source.rb#73 def [](*args); end # Returns the value of attribute ast. @@ -5918,12 +5948,12 @@ class RuboCop::AST::ProcessedSource # source://rubocop-ast//lib/rubocop/ast/processed_source.rb#21 def ast; end - # source://rubocop-ast//lib/rubocop/ast/processed_source.rb#50 + # source://rubocop-ast//lib/rubocop/ast/processed_source.rb#51 def ast_with_comments; end # @return [Boolean] # - # source://rubocop-ast//lib/rubocop/ast/processed_source.rb#111 + # source://rubocop-ast//lib/rubocop/ast/processed_source.rb#112 def blank?; end # Returns the value of attribute buffer. @@ -5933,12 +5963,12 @@ class RuboCop::AST::ProcessedSource # Raw source checksum for tracking infinite loops. # - # source://rubocop-ast//lib/rubocop/ast/processed_source.rb#83 + # source://rubocop-ast//lib/rubocop/ast/processed_source.rb#84 def checksum; end # @return [Comment, nil] the comment at that line, if any. # - # source://rubocop-ast//lib/rubocop/ast/processed_source.rb#116 + # source://rubocop-ast//lib/rubocop/ast/processed_source.rb#117 def comment_at_line(line); end # Consider using `each_comment_in_lines` instead @@ -5946,7 +5976,7 @@ class RuboCop::AST::ProcessedSource # @deprecated use contains_comment? # @return [Boolean] if any of the lines in the given `source_range` has a comment. # - # source://rubocop-ast//lib/rubocop/ast/processed_source.rb#138 + # source://rubocop-ast//lib/rubocop/ast/processed_source.rb#139 def commented?(source_range); end # Returns the value of attribute comments. @@ -5958,17 +5988,17 @@ class RuboCop::AST::ProcessedSource # # @deprecated Use `each_comment_in_lines` # - # source://rubocop-ast//lib/rubocop/ast/processed_source.rb#146 + # source://rubocop-ast//lib/rubocop/ast/processed_source.rb#147 def comments_before_line(line); end # Consider using `each_comment_in_lines` instead # # @return [Boolean] if any of the lines in the given `source_range` has a comment. # - # source://rubocop-ast//lib/rubocop/ast/processed_source.rb#138 + # source://rubocop-ast//lib/rubocop/ast/processed_source.rb#139 def contains_comment?(source_range); end - # source://rubocop-ast//lib/rubocop/ast/processed_source.rb#160 + # source://rubocop-ast//lib/rubocop/ast/processed_source.rb#161 def current_line(token); end # Returns the value of attribute diagnostics. @@ -5978,53 +6008,53 @@ class RuboCop::AST::ProcessedSource # @deprecated Use `comments.each` # - # source://rubocop-ast//lib/rubocop/ast/processed_source.rb#88 + # source://rubocop-ast//lib/rubocop/ast/processed_source.rb#89 def each_comment(&block); end # Enumerates on the comments contained with the given `line_range` # - # source://rubocop-ast//lib/rubocop/ast/processed_source.rb#126 + # source://rubocop-ast//lib/rubocop/ast/processed_source.rb#127 def each_comment_in_lines(line_range); end # @deprecated Use `tokens.each` # - # source://rubocop-ast//lib/rubocop/ast/processed_source.rb#98 + # source://rubocop-ast//lib/rubocop/ast/processed_source.rb#99 def each_token(&block); end - # source://rubocop-ast//lib/rubocop/ast/processed_source.rb#107 + # source://rubocop-ast//lib/rubocop/ast/processed_source.rb#108 def file_path; end # @deprecated Use `comment_at_line`, `each_comment_in_lines`, or `comments.find` # - # source://rubocop-ast//lib/rubocop/ast/processed_source.rb#93 + # source://rubocop-ast//lib/rubocop/ast/processed_source.rb#94 def find_comment(&block); end # @deprecated Use `tokens.find` # - # source://rubocop-ast//lib/rubocop/ast/processed_source.rb#103 + # source://rubocop-ast//lib/rubocop/ast/processed_source.rb#104 def find_token(&block); end - # source://rubocop-ast//lib/rubocop/ast/processed_source.rb#181 + # source://rubocop-ast//lib/rubocop/ast/processed_source.rb#182 def first_token_of(range_or_node); end - # source://rubocop-ast//lib/rubocop/ast/processed_source.rb#164 + # source://rubocop-ast//lib/rubocop/ast/processed_source.rb#165 def following_line(token); end - # source://rubocop-ast//lib/rubocop/ast/processed_source.rb#185 + # source://rubocop-ast//lib/rubocop/ast/processed_source.rb#186 def last_token_of(range_or_node); end - # source://rubocop-ast//lib/rubocop/ast/processed_source.rb#168 + # source://rubocop-ast//lib/rubocop/ast/processed_source.rb#169 def line_indentation(line_number); end # @return [Boolean] if the given line number has a comment. # - # source://rubocop-ast//lib/rubocop/ast/processed_source.rb#121 + # source://rubocop-ast//lib/rubocop/ast/processed_source.rb#122 def line_with_comment?(line); end # Returns the source lines, line break characters removed, excluding a # possible __END__ and everything that comes after. # - # source://rubocop-ast//lib/rubocop/ast/processed_source.rb#58 + # source://rubocop-ast//lib/rubocop/ast/processed_source.rb#59 def lines; end # source://rubocop-md/1.2.2/lib/rubocop/markdown/rubocop_ext.rb#95 @@ -6045,7 +6075,7 @@ class RuboCop::AST::ProcessedSource # source://rubocop-ast//lib/rubocop/ast/processed_source.rb#21 def path; end - # source://rubocop-ast//lib/rubocop/ast/processed_source.rb#156 + # source://rubocop-ast//lib/rubocop/ast/processed_source.rb#157 def preceding_line(token); end # Returns the value of attribute raw_source. @@ -6062,12 +6092,12 @@ class RuboCop::AST::ProcessedSource # is passed as a method argument. In this case tokens are interleaved by # heredoc contents' tokens. # - # source://rubocop-ast//lib/rubocop/ast/processed_source.rb#192 + # source://rubocop-ast//lib/rubocop/ast/processed_source.rb#193 def sorted_tokens; end # @return [Boolean] # - # source://rubocop-ast//lib/rubocop/ast/processed_source.rb#150 + # source://rubocop-ast//lib/rubocop/ast/processed_source.rb#151 def start_with?(string); end # Returns the value of attribute tokens. @@ -6075,35 +6105,35 @@ class RuboCop::AST::ProcessedSource # source://rubocop-ast//lib/rubocop/ast/processed_source.rb#21 def tokens; end - # source://rubocop-ast//lib/rubocop/ast/processed_source.rb#175 + # source://rubocop-ast//lib/rubocop/ast/processed_source.rb#176 def tokens_within(range_or_node); end # @return [Boolean] # - # source://rubocop-ast//lib/rubocop/ast/processed_source.rb#76 + # source://rubocop-ast//lib/rubocop/ast/processed_source.rb#77 def valid_syntax?; end private - # source://rubocop-ast//lib/rubocop/ast/processed_source.rb#199 + # source://rubocop-ast//lib/rubocop/ast/processed_source.rb#200 def comment_index; end - # source://rubocop-ast//lib/rubocop/ast/processed_source.rb#311 + # source://rubocop-ast//lib/rubocop/ast/processed_source.rb#312 def create_parser(ruby_version, parser_engine); end - # source://rubocop-ast//lib/rubocop/ast/processed_source.rb#327 + # source://rubocop-ast//lib/rubocop/ast/processed_source.rb#328 def first_token_index(range_or_node); end - # source://rubocop-ast//lib/rubocop/ast/processed_source.rb#332 + # source://rubocop-ast//lib/rubocop/ast/processed_source.rb#333 def last_token_index(range_or_node); end - # source://rubocop-ast//lib/rubocop/ast/processed_source.rb#239 + # source://rubocop-ast//lib/rubocop/ast/processed_source.rb#240 def parser_class(ruby_version, parser_engine); end - # source://rubocop-ast//lib/rubocop/ast/processed_source.rb#337 + # source://rubocop-ast//lib/rubocop/ast/processed_source.rb#338 def source_range(range_or_node); end - # source://rubocop-ast//lib/rubocop/ast/processed_source.rb#222 + # source://rubocop-ast//lib/rubocop/ast/processed_source.rb#223 def tokenize(parser); end class << self diff --git a/Library/Homebrew/sorbet/rbi/gems/rubocop@1.61.0.rbi b/Library/Homebrew/sorbet/rbi/gems/rubocop@1.62.1.rbi similarity index 99% rename from Library/Homebrew/sorbet/rbi/gems/rubocop@1.61.0.rbi rename to Library/Homebrew/sorbet/rbi/gems/rubocop@1.62.1.rbi index ca22da7e137d2f..e24281ad5ee20d 100644 --- a/Library/Homebrew/sorbet/rbi/gems/rubocop@1.61.0.rbi +++ b/Library/Homebrew/sorbet/rbi/gems/rubocop@1.62.1.rbi @@ -11,25 +11,25 @@ module CopHelper extend ::RSpec::Its extend ::RSpec::Core::SharedContext - # source://rubocop//lib/rubocop/rspec/cop_helper.rb#71 + # source://rubocop//lib/rubocop/rspec/cop_helper.rb#77 def _investigate(cop, processed_source); end - # source://rubocop//lib/rubocop/rspec/cop_helper.rb#61 + # source://rubocop//lib/rubocop/rspec/cop_helper.rb#67 def autocorrect_source(source, file = T.unsafe(nil)); end - # source://rubocop//lib/rubocop/rspec/cop_helper.rb#57 + # source://rubocop//lib/rubocop/rspec/cop_helper.rb#63 def autocorrect_source_file(source); end - # source://rubocop//lib/rubocop/rspec/cop_helper.rb#37 + # source://rubocop//lib/rubocop/rspec/cop_helper.rb#43 def configuration; end - # source://rubocop//lib/rubocop/rspec/cop_helper.rb#12 + # source://rubocop//lib/rubocop/rspec/cop_helper.rb#16 def inspect_source(source, file = T.unsafe(nil)); end - # source://rubocop//lib/rubocop/rspec/cop_helper.rb#24 + # source://rubocop//lib/rubocop/rspec/cop_helper.rb#28 def parse_source(source, file = T.unsafe(nil)); end - # source://rubocop//lib/rubocop/rspec/cop_helper.rb#45 + # source://rubocop//lib/rubocop/rspec/cop_helper.rb#51 def registry; end end @@ -209,77 +209,83 @@ end class RuboCop::CLI::Command::AutoGenerateConfig < ::RuboCop::CLI::Command::Base # @api private # - # source://rubocop//lib/rubocop/cli/command/auto_generate_config.rb#22 + # source://rubocop//lib/rubocop/cli/command/auto_generate_config.rb#25 def run; end private # @api private # - # source://rubocop//lib/rubocop/cli/command/auto_generate_config.rb#98 + # source://rubocop//lib/rubocop/cli/command/auto_generate_config.rb#107 def add_formatter; end # @api private # - # source://rubocop//lib/rubocop/cli/command/auto_generate_config.rb#106 + # source://rubocop//lib/rubocop/cli/command/auto_generate_config.rb#115 def add_inheritance_from_auto_generated_file(config_file); end # @api private # - # source://rubocop//lib/rubocop/cli/command/auto_generate_config.rb#102 + # source://rubocop//lib/rubocop/cli/command/auto_generate_config.rb#111 def execute_runner; end # @api private # - # source://rubocop//lib/rubocop/cli/command/auto_generate_config.rb#127 + # source://rubocop//lib/rubocop/cli/command/auto_generate_config.rb#136 def existing_configuration(config_file); end # @api private # - # source://rubocop//lib/rubocop/cli/command/auto_generate_config.rb#60 + # source://rubocop//lib/rubocop/cli/command/auto_generate_config.rb#65 def line_length_cop(config); end # @api private # @return [Boolean] # - # source://rubocop//lib/rubocop/cli/command/auto_generate_config.rb#48 + # source://rubocop//lib/rubocop/cli/command/auto_generate_config.rb#53 def line_length_enabled?(config); end # @api private # - # source://rubocop//lib/rubocop/cli/command/auto_generate_config.rb#56 + # source://rubocop//lib/rubocop/cli/command/auto_generate_config.rb#61 def max_line_length(config); end # @api private # - # source://rubocop//lib/rubocop/cli/command/auto_generate_config.rb#31 + # source://rubocop//lib/rubocop/cli/command/auto_generate_config.rb#34 def maybe_run_line_length_cop; end # @api private # @return [Boolean] # - # source://rubocop//lib/rubocop/cli/command/auto_generate_config.rb#153 + # source://rubocop//lib/rubocop/cli/command/auto_generate_config.rb#73 + def only_exclude?; end + + # @api private + # @return [Boolean] + # + # source://rubocop//lib/rubocop/cli/command/auto_generate_config.rb#162 def options_config_in_root?; end # @api private # @return [Boolean] # - # source://rubocop//lib/rubocop/cli/command/auto_generate_config.rb#64 + # source://rubocop//lib/rubocop/cli/command/auto_generate_config.rb#69 def options_has_only_flag?; end # @api private # - # source://rubocop//lib/rubocop/cli/command/auto_generate_config.rb#144 + # source://rubocop//lib/rubocop/cli/command/auto_generate_config.rb#153 def relative_path_to_todo_from_options_config; end # @api private # - # source://rubocop//lib/rubocop/cli/command/auto_generate_config.rb#91 + # source://rubocop//lib/rubocop/cli/command/auto_generate_config.rb#100 def reset_config_and_auto_gen_file; end # @api private # - # source://rubocop//lib/rubocop/cli/command/auto_generate_config.rb#82 + # source://rubocop//lib/rubocop/cli/command/auto_generate_config.rb#91 def run_all_cops(line_length_contents); end # Do an initial run with only Layout/LineLength so that cops that @@ -288,23 +294,23 @@ class RuboCop::CLI::Command::AutoGenerateConfig < ::RuboCop::CLI::Command::Base # # @api private # - # source://rubocop//lib/rubocop/cli/command/auto_generate_config.rb#71 + # source://rubocop//lib/rubocop/cli/command/auto_generate_config.rb#80 def run_line_length_cop; end # @api private # @return [Boolean] # - # source://rubocop//lib/rubocop/cli/command/auto_generate_config.rb#52 + # source://rubocop//lib/rubocop/cli/command/auto_generate_config.rb#57 def same_max_line_length?(config1, config2); end # @api private # - # source://rubocop//lib/rubocop/cli/command/auto_generate_config.rb#43 + # source://rubocop//lib/rubocop/cli/command/auto_generate_config.rb#48 def skip_line_length_cop(reason); end # @api private # - # source://rubocop//lib/rubocop/cli/command/auto_generate_config.rb#133 + # source://rubocop//lib/rubocop/cli/command/auto_generate_config.rb#142 def write_config_file(file_name, file_string, rubocop_yml_contents); end end @@ -331,7 +337,12 @@ RuboCop::CLI::Command::AutoGenerateConfig::PHASE_1_OVERRIDDEN = T.let(T.unsafe(n # @api private # # source://rubocop//lib/rubocop/cli/command/auto_generate_config.rb#20 -RuboCop::CLI::Command::AutoGenerateConfig::PHASE_1_SKIPPED = T.let(T.unsafe(nil), String) +RuboCop::CLI::Command::AutoGenerateConfig::PHASE_1_SKIPPED_ONLY_COPS = T.let(T.unsafe(nil), String) + +# @api private +# +# source://rubocop//lib/rubocop/cli/command/auto_generate_config.rb#22 +RuboCop::CLI::Command::AutoGenerateConfig::PHASE_1_SKIPPED_ONLY_EXCLUDE = T.let(T.unsafe(nil), String) # @api private # @@ -1028,7 +1039,7 @@ class RuboCop::Config # source://rubocop//lib/rubocop/config.rb#237 def base_dir_for_path_parameters; end - # source://rubocop//lib/rubocop/config.rb#262 + # source://rubocop//lib/rubocop/config.rb#266 def bundler_lock_file_path; end # source://rubocop//lib/rubocop/config.rb#51 @@ -1104,7 +1115,7 @@ class RuboCop::Config # source://rubocop//lib/rubocop/config.rb#153 def for_department(department_name); end - # source://rubocop//lib/rubocop/config.rb#285 + # source://rubocop//lib/rubocop/config.rb#289 def inspect; end # True if this is a config file that is shipped with RuboCop @@ -1137,6 +1148,9 @@ class RuboCop::Config # source://forwardable/1.3.2/forwardable.rb#229 def merge(*args, **_arg1, &block); end + # source://rubocop//lib/rubocop/config.rb#247 + def parser_engine; end + # source://rubocop//lib/rubocop/config.rb#228 def path_relative_to_config(path); end @@ -1146,7 +1160,7 @@ class RuboCop::Config # source://rubocop//lib/rubocop/config.rb#220 def patterns_to_include; end - # source://rubocop//lib/rubocop/config.rb#273 + # source://rubocop//lib/rubocop/config.rb#277 def pending_cops; end # Returns true if there's a chance that an Include pattern matches hidden @@ -1163,10 +1177,10 @@ class RuboCop::Config # source://rubocop//lib/rubocop/config.rb#71 def signature; end - # source://rubocop//lib/rubocop/config.rb#258 + # source://rubocop//lib/rubocop/config.rb#262 def smart_loaded_path; end - # source://rubocop//lib/rubocop/config.rb#247 + # source://rubocop//lib/rubocop/config.rb#251 def target_rails_version; end # source://forwardable/1.3.2/forwardable.rb#229 @@ -1192,18 +1206,18 @@ class RuboCop::Config private - # source://rubocop//lib/rubocop/config.rb#320 + # source://rubocop//lib/rubocop/config.rb#324 def department_of(qualified_cop_name); end # @return [Boolean] # - # source://rubocop//lib/rubocop/config.rb#308 + # source://rubocop//lib/rubocop/config.rb#312 def enable_cop?(qualified_cop_name, cop_options); end - # source://rubocop//lib/rubocop/config.rb#295 + # source://rubocop//lib/rubocop/config.rb#299 def read_rails_version_from_bundler_lock_file; end - # source://rubocop//lib/rubocop/config.rb#291 + # source://rubocop//lib/rubocop/config.rb#295 def target_rails_version_from_bundler_lock_file; end class << self @@ -2944,7 +2958,7 @@ class RuboCop::Cop::Base # @return [Boolean] # - # source://rubocop//lib/rubocop/cop/base.rb#239 + # source://rubocop//lib/rubocop/cop/base.rb#243 def active_support_extensions_enabled?; end # Adds an offense that has no particular location. @@ -2964,19 +2978,19 @@ class RuboCop::Cop::Base # @api private # @return [Boolean] # - # source://rubocop//lib/rubocop/cop/base.rb#309 + # source://rubocop//lib/rubocop/cop/base.rb#313 def always_autocorrect?; end # Called before any investigation # # @api private # - # source://rubocop//lib/rubocop/cop/base.rb#295 + # source://rubocop//lib/rubocop/cop/base.rb#299 def begin_investigation(processed_source, offset: T.unsafe(nil), original: T.unsafe(nil)); end # @api private # - # source://rubocop//lib/rubocop/cop/base.rb#280 + # source://rubocop//lib/rubocop/cop/base.rb#284 def callbacks_needed; end # Returns the value of attribute config. @@ -2993,7 +3007,7 @@ class RuboCop::Cop::Base # @api private # @return [Boolean] # - # source://rubocop//lib/rubocop/cop/base.rb#315 + # source://rubocop//lib/rubocop/cop/base.rb#319 def contextual_autocorrect?; end # Configuration Helpers @@ -3006,7 +3020,7 @@ class RuboCop::Cop::Base # @return [Boolean] # - # source://rubocop//lib/rubocop/cop/base.rb#251 + # source://rubocop//lib/rubocop/cop/base.rb#255 def excluded_file?(file); end # This method should be overridden when a cop's behavior depends @@ -3028,7 +3042,7 @@ class RuboCop::Cop::Base # source://rubocop//lib/rubocop/cop/base.rb#205 def external_dependency_checksum; end - # source://rubocop//lib/rubocop/cop/base.rb#319 + # source://rubocop//lib/rubocop/cop/base.rb#323 def inspect; end # Gets called if no message is specified when calling `add_offense` or @@ -3043,7 +3057,7 @@ class RuboCop::Cop::Base # @deprecated Make potential errors with previous API more obvious # - # source://rubocop//lib/rubocop/cop/base.rb#271 + # source://rubocop//lib/rubocop/cop/base.rb#275 def offenses; end # Called after all on_... have been called @@ -3066,9 +3080,12 @@ class RuboCop::Cop::Base # There should be very limited reasons for a Cop to do it's own parsing # - # source://rubocop//lib/rubocop/cop/base.rb#256 + # source://rubocop//lib/rubocop/cop/base.rb#260 def parse(source, path = T.unsafe(nil)); end + # source://rubocop//lib/rubocop/cop/base.rb#235 + def parser_engine; end + # Returns the value of attribute processed_source. # # source://rubocop//lib/rubocop/cop/base.rb#43 @@ -3078,15 +3095,15 @@ class RuboCop::Cop::Base # # @api private # - # source://rubocop//lib/rubocop/cop/base.rb#262 + # source://rubocop//lib/rubocop/cop/base.rb#266 def ready; end # @return [Boolean] # - # source://rubocop//lib/rubocop/cop/base.rb#243 + # source://rubocop//lib/rubocop/cop/base.rb#247 def relevant_file?(file); end - # source://rubocop//lib/rubocop/cop/base.rb#235 + # source://rubocop//lib/rubocop/cop/base.rb#239 def target_rails_version; end # source://rubocop//lib/rubocop/cop/base.rb#231 @@ -3094,83 +3111,83 @@ class RuboCop::Cop::Base private - # source://rubocop//lib/rubocop/cop/base.rb#447 + # source://rubocop//lib/rubocop/cop/base.rb#451 def annotate(message); end - # source://rubocop//lib/rubocop/cop/base.rb#331 + # source://rubocop//lib/rubocop/cop/base.rb#335 def apply_correction(corrector); end # @return [Symbol] offense status # - # source://rubocop//lib/rubocop/cop/base.rb#411 + # source://rubocop//lib/rubocop/cop/base.rb#415 def attempt_correction(range, corrector); end # Reserved for Cop::Cop # - # source://rubocop//lib/rubocop/cop/base.rb#327 + # source://rubocop//lib/rubocop/cop/base.rb#331 def callback_argument(range); end # Called to complete an investigation # - # source://rubocop//lib/rubocop/cop/base.rb#360 + # source://rubocop//lib/rubocop/cop/base.rb#364 def complete_investigation; end # @return [Symbol, Corrector] offense status # - # source://rubocop//lib/rubocop/cop/base.rb#385 + # source://rubocop//lib/rubocop/cop/base.rb#389 def correct(range); end - # source://rubocop//lib/rubocop/cop/base.rb#345 + # source://rubocop//lib/rubocop/cop/base.rb#349 def current_corrector; end # Reserved for Commissioner: # - # source://rubocop//lib/rubocop/cop/base.rb#337 + # source://rubocop//lib/rubocop/cop/base.rb#341 def current_offense_locations; end - # source://rubocop//lib/rubocop/cop/base.rb#349 + # source://rubocop//lib/rubocop/cop/base.rb#353 def current_offenses; end - # source://rubocop//lib/rubocop/cop/base.rb#341 + # source://rubocop//lib/rubocop/cop/base.rb#345 def currently_disabled_lines; end - # source://rubocop//lib/rubocop/cop/base.rb#475 + # source://rubocop//lib/rubocop/cop/base.rb#479 def custom_severity; end - # source://rubocop//lib/rubocop/cop/base.rb#471 + # source://rubocop//lib/rubocop/cop/base.rb#475 def default_severity; end - # source://rubocop//lib/rubocop/cop/base.rb#425 + # source://rubocop//lib/rubocop/cop/base.rb#429 def disable_uncorrectable(range); end # @return [Boolean] # - # source://rubocop//lib/rubocop/cop/base.rb#461 + # source://rubocop//lib/rubocop/cop/base.rb#465 def enabled_line?(line_number); end # @return [Boolean] # - # source://rubocop//lib/rubocop/cop/base.rb#453 + # source://rubocop//lib/rubocop/cop/base.rb#457 def file_name_matches_any?(file, parameter, default_result); end - # source://rubocop//lib/rubocop/cop/base.rb#443 + # source://rubocop//lib/rubocop/cop/base.rb#447 def find_message(range, message); end - # source://rubocop//lib/rubocop/cop/base.rb#467 + # source://rubocop//lib/rubocop/cop/base.rb#471 def find_severity(_range, severity); end - # source://rubocop//lib/rubocop/cop/base.rb#488 + # source://rubocop//lib/rubocop/cop/base.rb#492 def range_for_original(range); end - # source://rubocop//lib/rubocop/cop/base.rb#432 + # source://rubocop//lib/rubocop/cop/base.rb#436 def range_from_node_or_range(node_or_range); end - # source://rubocop//lib/rubocop/cop/base.rb#380 + # source://rubocop//lib/rubocop/cop/base.rb#384 def reset_investigation; end # @return [Symbol] offense status # - # source://rubocop//lib/rubocop/cop/base.rb#400 + # source://rubocop//lib/rubocop/cop/base.rb#404 def use_corrector(range, corrector); end class << self @@ -3190,7 +3207,7 @@ class RuboCop::Cop::Base # @api private # - # source://rubocop//lib/rubocop/cop/base.rb#285 + # source://rubocop//lib/rubocop/cop/base.rb#289 def callbacks_needed; end # source://rubocop//lib/rubocop/cop/base.rb#93 @@ -3260,15 +3277,15 @@ class RuboCop::Cop::Base # @return [Boolean] # - # source://rubocop//lib/rubocop/cop/base.rb#371 + # source://rubocop//lib/rubocop/cop/base.rb#375 def builtin?; end - # source://rubocop//lib/rubocop/cop/base.rb#353 + # source://rubocop//lib/rubocop/cop/base.rb#357 def restrict_on_send; end end end -# source://rubocop//lib/rubocop/cop/base.rb#357 +# source://rubocop//lib/rubocop/cop/base.rb#361 RuboCop::Cop::Base::EMPTY_OFFENSES = T.let(T.unsafe(nil), Array) # Reports of an investigation. @@ -4889,10 +4906,10 @@ class RuboCop::Cop::Cop < ::RuboCop::Cop::Base # source://rubocop//lib/rubocop/cop/cop.rb#70 def find_location(node, loc); end - # source://rubocop//lib/rubocop/rspec/cop_helper.rb#88 + # source://rubocop//lib/rubocop/rspec/cop_helper.rb#94 def highlights; end - # source://rubocop//lib/rubocop/rspec/cop_helper.rb#84 + # source://rubocop//lib/rubocop/rspec/cop_helper.rb#90 def messages; end # Returns the value of attribute offenses. @@ -6160,7 +6177,7 @@ class RuboCop::Cop::Gemspec::RequiredRubyVersion < ::RuboCop::Cop::Base # source://rubocop//lib/rubocop/cop/gemspec/required_ruby_version.rb#78 def on_new_investigation; end - # source://rubocop//lib/rubocop/cop/gemspec/required_ruby_version.rb#82 + # source://rubocop//lib/rubocop/cop/gemspec/required_ruby_version.rb#84 def on_send(node); end # source://rubocop//lib/rubocop/cop/gemspec/required_ruby_version.rb#65 @@ -6170,13 +6187,13 @@ class RuboCop::Cop::Gemspec::RequiredRubyVersion < ::RuboCop::Cop::Base # @return [Boolean] # - # source://rubocop//lib/rubocop/cop/gemspec/required_ruby_version.rb#94 + # source://rubocop//lib/rubocop/cop/gemspec/required_ruby_version.rb#96 def dynamic_version?(node); end - # source://rubocop//lib/rubocop/cop/gemspec/required_ruby_version.rb#100 + # source://rubocop//lib/rubocop/cop/gemspec/required_ruby_version.rb#102 def extract_ruby_version(required_ruby_version); end - # source://rubocop//lib/rubocop/cop/gemspec/required_ruby_version.rb#118 + # source://rubocop//lib/rubocop/cop/gemspec/required_ruby_version.rb#120 def not_equal_message(required_ruby_version, target_ruby_version); end end @@ -8959,15 +8976,19 @@ class RuboCop::Cop::Layout::EmptyLineAfterMagicComment < ::RuboCop::Cop::Base private + # source://rubocop//lib/rubocop/cop/layout/empty_line_after_magic_comment.rb#61 + def comments_before_code(source); end + # Find the last magic comment in the source file. # - # Take all comments that precede the first line of code, select the + # Take all comments that precede the first line of code (or just take + # them all in the case when there is no code), select the # magic comments, and return the last magic comment in the file. # # @return [Parser::Source::Comment] if magic comments exist before code # @return [nil] otherwise # - # source://rubocop//lib/rubocop/cop/layout/empty_line_after_magic_comment.rb#54 + # source://rubocop//lib/rubocop/cop/layout/empty_line_after_magic_comment.rb#55 def last_magic_comment(source); end # source://rubocop//lib/rubocop/cop/layout/empty_line_after_magic_comment.rb#43 @@ -14164,17 +14185,17 @@ class RuboCop::Cop::Layout::RedundantLineBreak < ::RuboCop::Cop::Base # @return [Boolean] # - # source://rubocop//lib/rubocop/cop/layout/redundant_line_break.rb#127 + # source://rubocop//lib/rubocop/cop/layout/redundant_line_break.rb#133 def comment_within?(node); end # @return [Boolean] # - # source://rubocop//lib/rubocop/cop/layout/redundant_line_break.rb#97 + # source://rubocop//lib/rubocop/cop/layout/redundant_line_break.rb#103 def configured_to_not_be_inspected?(node); end # @return [Boolean] # - # source://rubocop//lib/rubocop/cop/layout/redundant_line_break.rb#121 + # source://rubocop//lib/rubocop/cop/layout/redundant_line_break.rb#127 def convertible_block?(node); end # @return [Boolean] @@ -14184,10 +14205,10 @@ class RuboCop::Cop::Layout::RedundantLineBreak < ::RuboCop::Cop::Base # @return [Boolean] # - # source://rubocop//lib/rubocop/cop/layout/redundant_line_break.rb#91 + # source://rubocop//lib/rubocop/cop/layout/redundant_line_break.rb#97 def index_access_call_chained?(node); end - # source://rubocop//lib/rubocop/cop/layout/redundant_line_break.rb#149 + # source://rubocop//lib/rubocop/cop/layout/redundant_line_break.rb#155 def max_line_length; end # @return [Boolean] @@ -14197,7 +14218,7 @@ class RuboCop::Cop::Layout::RedundantLineBreak < ::RuboCop::Cop::Base # @return [Boolean] # - # source://rubocop//lib/rubocop/cop/layout/redundant_line_break.rb#104 + # source://rubocop//lib/rubocop/cop/layout/redundant_line_break.rb#110 def other_cop_takes_precedence?(node); end # source://rubocop//lib/rubocop/cop/layout/redundant_line_break.rb#79 @@ -14205,20 +14226,25 @@ class RuboCop::Cop::Layout::RedundantLineBreak < ::RuboCop::Cop::Base # @return [Boolean] # - # source://rubocop//lib/rubocop/cop/layout/redundant_line_break.rb#110 + # source://rubocop//lib/rubocop/cop/layout/redundant_line_break.rb#93 + def require_backslash?(node); end + + # @return [Boolean] + # + # source://rubocop//lib/rubocop/cop/layout/redundant_line_break.rb#116 def single_line_block_chain_enabled?; end # @return [Boolean] # - # source://rubocop//lib/rubocop/cop/layout/redundant_line_break.rb#114 + # source://rubocop//lib/rubocop/cop/layout/redundant_line_break.rb#120 def suitable_as_single_line?(node); end - # source://rubocop//lib/rubocop/cop/layout/redundant_line_break.rb#140 + # source://rubocop//lib/rubocop/cop/layout/redundant_line_break.rb#146 def to_single_line(source); end # @return [Boolean] # - # source://rubocop//lib/rubocop/cop/layout/redundant_line_break.rb#135 + # source://rubocop//lib/rubocop/cop/layout/redundant_line_break.rb#141 def too_long?(node); end end @@ -22491,15 +22517,15 @@ class RuboCop::Cop::Lint::RedundantWithIndex < ::RuboCop::Cop::Base # source://rubocop//lib/rubocop/cop/lint/redundant_with_index.rb#36 def on_numblock(node); end - # source://rubocop//lib/rubocop/cop/lint/redundant_with_index.rb#56 + # source://rubocop//lib/rubocop/cop/lint/redundant_with_index.rb#57 def redundant_with_index?(param0 = T.unsafe(nil)); end private - # source://rubocop//lib/rubocop/cop/lint/redundant_with_index.rb#66 + # source://rubocop//lib/rubocop/cop/lint/redundant_with_index.rb#67 def message(node); end - # source://rubocop//lib/rubocop/cop/lint/redundant_with_index.rb#74 + # source://rubocop//lib/rubocop/cop/lint/redundant_with_index.rb#75 def with_index_range(send); end end @@ -23854,12 +23880,12 @@ class RuboCop::Cop::Lint::ToEnumArguments < ::RuboCop::Cop::Base # @return [Boolean] # - # source://rubocop//lib/rubocop/cop/lint/to_enum_arguments.rb#78 + # source://rubocop//lib/rubocop/cop/lint/to_enum_arguments.rb#83 def argument_match?(send_arg, def_arg); end # @return [Boolean] # - # source://rubocop//lib/rubocop/cop/lint/to_enum_arguments.rb#63 + # source://rubocop//lib/rubocop/cop/lint/to_enum_arguments.rb#68 def arguments_match?(arguments, def_node); end end @@ -36705,7 +36731,7 @@ class RuboCop::Cop::Style::For < ::RuboCop::Cop::Base # @return [Boolean] # - # source://rubocop//lib/rubocop/cop/style/for.rb#82 + # source://rubocop//lib/rubocop/cop/style/for.rb#84 def suspect_enumerable?(node); end end @@ -41290,33 +41316,33 @@ class RuboCop::Cop::Style::MultilineMethodSignature < ::RuboCop::Cop::Base private - # source://rubocop//lib/rubocop/cop/style/multiline_method_signature.rb#60 + # source://rubocop//lib/rubocop/cop/style/multiline_method_signature.rb#69 def arguments_range(node); end - # source://rubocop//lib/rubocop/cop/style/multiline_method_signature.rb#41 + # source://rubocop//lib/rubocop/cop/style/multiline_method_signature.rb#42 def autocorrect(corrector, node, begin_of_arguments); end - # source://rubocop//lib/rubocop/cop/style/multiline_method_signature.rb#72 + # source://rubocop//lib/rubocop/cop/style/multiline_method_signature.rb#81 def closing_line(node); end # @return [Boolean] # - # source://rubocop//lib/rubocop/cop/style/multiline_method_signature.rb#76 + # source://rubocop//lib/rubocop/cop/style/multiline_method_signature.rb#85 def correction_exceeds_max_line_length?(node); end - # source://rubocop//lib/rubocop/cop/style/multiline_method_signature.rb#84 + # source://rubocop//lib/rubocop/cop/style/multiline_method_signature.rb#93 def definition_width(node); end - # source://rubocop//lib/rubocop/cop/style/multiline_method_signature.rb#80 + # source://rubocop//lib/rubocop/cop/style/multiline_method_signature.rb#89 def indentation_width(node); end - # source://rubocop//lib/rubocop/cop/style/multiline_method_signature.rb#56 + # source://rubocop//lib/rubocop/cop/style/multiline_method_signature.rb#65 def last_line_source_of_arguments(arguments); end - # source://rubocop//lib/rubocop/cop/style/multiline_method_signature.rb#88 + # source://rubocop//lib/rubocop/cop/style/multiline_method_signature.rb#97 def max_line_length; end - # source://rubocop//lib/rubocop/cop/style/multiline_method_signature.rb#68 + # source://rubocop//lib/rubocop/cop/style/multiline_method_signature.rb#77 def opening_line(node); end end @@ -41634,7 +41660,7 @@ class RuboCop::Cop::Style::MutableConstant < ::RuboCop::Cop::Base include ::RuboCop::Cop::ConfigurableEnforcedStyle extend ::RuboCop::Cop::AutoCorrector - # source://rubocop-sorbet/0.7.7/lib/rubocop/cop/sorbet/mutable_constant_sorbet_aware_behaviour.rb#18 + # source://rubocop-sorbet/0.7.8/lib/rubocop/cop/sorbet/mutable_constant_sorbet_aware_behaviour.rb#18 def on_assignment(value); end # source://rubocop//lib/rubocop/cop/style/mutable_constant.rb#127 @@ -41652,7 +41678,7 @@ class RuboCop::Cop::Style::MutableConstant < ::RuboCop::Cop::Base # source://rubocop//lib/rubocop/cop/style/mutable_constant.rb#217 def splat_value(param0 = T.unsafe(nil)); end - # source://rubocop-sorbet/0.7.7/lib/rubocop/cop/sorbet/mutable_constant_sorbet_aware_behaviour.rb#12 + # source://rubocop-sorbet/0.7.8/lib/rubocop/cop/sorbet/mutable_constant_sorbet_aware_behaviour.rb#12 def t_let(param0 = T.unsafe(nil)); end private @@ -42399,17 +42425,17 @@ class RuboCop::Cop::Style::NilComparison < ::RuboCop::Cop::Base private - # source://rubocop//lib/rubocop/cop/style/nil_comparison.rb#65 + # source://rubocop//lib/rubocop/cop/style/nil_comparison.rb#67 def message(_node); end # @return [Boolean] # - # source://rubocop//lib/rubocop/cop/style/nil_comparison.rb#77 + # source://rubocop//lib/rubocop/cop/style/nil_comparison.rb#79 def prefer_comparison?; end # @return [Boolean] # - # source://rubocop//lib/rubocop/cop/style/nil_comparison.rb#69 + # source://rubocop//lib/rubocop/cop/style/nil_comparison.rb#71 def style_check?(node, &block); end end @@ -50295,7 +50321,7 @@ class RuboCop::Cop::Style::TrailingCommaInArguments < ::RuboCop::Cop::Base def on_send(node); end class << self - # source://rubocop-rspec/2.26.1/lib/rubocop-rspec.rb#60 + # source://rubocop-rspec/2.27.1/lib/rubocop-rspec.rb#60 def autocorrect_incompatible_with; end end end @@ -53691,176 +53717,181 @@ RuboCop::Cop::VisibilityHelp::VISIBILITY_SCOPES = T.let(T.unsafe(nil), Set) class RuboCop::DirectiveComment # @return [DirectiveComment] a new instance of DirectiveComment # - # source://rubocop//lib/rubocop/directive_comment.rb#30 + # source://rubocop//lib/rubocop/directive_comment.rb#32 def initialize(comment, cop_registry = T.unsafe(nil)); end # Checks if all cops specified in this directive # # @return [Boolean] # - # source://rubocop//lib/rubocop/directive_comment.rb#80 + # source://rubocop//lib/rubocop/directive_comment.rb#82 def all_cops?; end # Returns the value of attribute comment. # - # source://rubocop//lib/rubocop/directive_comment.rb#28 + # source://rubocop//lib/rubocop/directive_comment.rb#30 def comment; end # Returns array of specified in this directive cop names # - # source://rubocop//lib/rubocop/directive_comment.rb#85 + # source://rubocop//lib/rubocop/directive_comment.rb#87 def cop_names; end # Returns the value of attribute cop_registry. # - # source://rubocop//lib/rubocop/directive_comment.rb#28 + # source://rubocop//lib/rubocop/directive_comment.rb#30 def cop_registry; end # Returns the value of attribute cops. # - # source://rubocop//lib/rubocop/directive_comment.rb#28 + # source://rubocop//lib/rubocop/directive_comment.rb#30 def cops; end # Returns array of specified in this directive department names # when all department disabled # - # source://rubocop//lib/rubocop/directive_comment.rb#91 + # source://rubocop//lib/rubocop/directive_comment.rb#93 def department_names; end - # source://rubocop//lib/rubocop/directive_comment.rb#105 + # source://rubocop//lib/rubocop/directive_comment.rb#107 def directive_count; end # Checks if this directive disables cops # # @return [Boolean] # - # source://rubocop//lib/rubocop/directive_comment.rb#60 + # source://rubocop//lib/rubocop/directive_comment.rb#62 def disabled?; end # Checks if this directive disables all cops # # @return [Boolean] # - # source://rubocop//lib/rubocop/directive_comment.rb#75 + # source://rubocop//lib/rubocop/directive_comment.rb#77 def disabled_all?; end # Checks if this directive enables cops # # @return [Boolean] # - # source://rubocop//lib/rubocop/directive_comment.rb#65 + # source://rubocop//lib/rubocop/directive_comment.rb#67 def enabled?; end # Checks if this directive enables all cops # # @return [Boolean] # - # source://rubocop//lib/rubocop/directive_comment.rb#70 + # source://rubocop//lib/rubocop/directive_comment.rb#72 def enabled_all?; end # Checks if directive departments include cop # # @return [Boolean] # - # source://rubocop//lib/rubocop/directive_comment.rb#96 + # source://rubocop//lib/rubocop/directive_comment.rb#98 def in_directive_department?(cop); end # Returns line number for directive # - # source://rubocop//lib/rubocop/directive_comment.rb#110 + # source://rubocop//lib/rubocop/directive_comment.rb#112 def line_number; end # Checks if this directive contains all the given cop names # # @return [Boolean] # - # source://rubocop//lib/rubocop/directive_comment.rb#42 + # source://rubocop//lib/rubocop/directive_comment.rb#44 def match?(cop_names); end # Returns match captures to directive comment pattern # - # source://rubocop//lib/rubocop/directive_comment.rb#55 + # source://rubocop//lib/rubocop/directive_comment.rb#57 def match_captures; end # Returns the value of attribute mode. # - # source://rubocop//lib/rubocop/directive_comment.rb#28 + # source://rubocop//lib/rubocop/directive_comment.rb#30 def mode; end # Checks if cop department has already used in directive comment # # @return [Boolean] # - # source://rubocop//lib/rubocop/directive_comment.rb#101 + # source://rubocop//lib/rubocop/directive_comment.rb#103 def overridden_by_department?(cop); end - # source://rubocop//lib/rubocop/directive_comment.rb#46 + # source://rubocop//lib/rubocop/directive_comment.rb#48 def range; end # Checks if this directive relates to single line # # @return [Boolean] # - # source://rubocop//lib/rubocop/directive_comment.rb#37 + # source://rubocop//lib/rubocop/directive_comment.rb#39 def single_line?; end private - # source://rubocop//lib/rubocop/directive_comment.rb#130 + # source://rubocop//lib/rubocop/directive_comment.rb#133 def all_cop_names; end - # source://rubocop//lib/rubocop/directive_comment.rb#134 + # source://rubocop//lib/rubocop/directive_comment.rb#137 def cop_names_for_department(department); end # @return [Boolean] # - # source://rubocop//lib/rubocop/directive_comment.rb#126 + # source://rubocop//lib/rubocop/directive_comment.rb#129 def department?(name); end - # source://rubocop//lib/rubocop/directive_comment.rb#140 - def exclude_redundant_directive_cop(cops); end + # source://rubocop//lib/rubocop/directive_comment.rb#142 + def exclude_lint_department_cops(cops); end - # source://rubocop//lib/rubocop/directive_comment.rb#120 + # source://rubocop//lib/rubocop/directive_comment.rb#122 def parsed_cop_names; end - # source://rubocop//lib/rubocop/directive_comment.rb#116 + # source://rubocop//lib/rubocop/directive_comment.rb#118 def splitted_cops_string; end class << self - # source://rubocop//lib/rubocop/directive_comment.rb#24 + # source://rubocop//lib/rubocop/directive_comment.rb#26 def before_comment(line); end end end # @api private # -# source://rubocop//lib/rubocop/directive_comment.rb#17 +# source://rubocop//lib/rubocop/directive_comment.rb#19 RuboCop::DirectiveComment::COPS_PATTERN = T.let(T.unsafe(nil), String) # @api private # -# source://rubocop//lib/rubocop/directive_comment.rb#15 +# source://rubocop//lib/rubocop/directive_comment.rb#17 RuboCop::DirectiveComment::COP_NAMES_PATTERN = T.let(T.unsafe(nil), String) # @api private # -# source://rubocop//lib/rubocop/directive_comment.rb#13 +# source://rubocop//lib/rubocop/directive_comment.rb#15 RuboCop::DirectiveComment::COP_NAME_PATTERN = T.let(T.unsafe(nil), String) # @api private # -# source://rubocop//lib/rubocop/directive_comment.rb#19 +# source://rubocop//lib/rubocop/directive_comment.rb#21 RuboCop::DirectiveComment::DIRECTIVE_COMMENT_REGEXP = T.let(T.unsafe(nil), Regexp) +# @api private +# +# source://rubocop//lib/rubocop/directive_comment.rb#9 +RuboCop::DirectiveComment::LINT_DEPARTMENT = T.let(T.unsafe(nil), String) + # @api private # # source://rubocop//lib/rubocop/directive_comment.rb#11 -RuboCop::DirectiveComment::REDUNDANT_DIRECTIVE_COP = T.let(T.unsafe(nil), String) +RuboCop::DirectiveComment::LINT_REDUNDANT_DIRECTIVE_COP = T.let(T.unsafe(nil), String) # @api private # -# source://rubocop//lib/rubocop/directive_comment.rb#9 -RuboCop::DirectiveComment::REDUNDANT_DIRECTIVE_COP_DEPARTMENT = T.let(T.unsafe(nil), String) +# source://rubocop//lib/rubocop/directive_comment.rb#13 +RuboCop::DirectiveComment::LINT_SYNTAX_COP = T.let(T.unsafe(nil), String) # An Error exception is different from an Offense with severity 'error' # When this exception is raised, it means that RuboCop is unable to perform @@ -56560,7 +56591,9 @@ module RuboCop::RSpec::ExpectOffense # source://rubocop//lib/rubocop/rspec/expect_offense.rb#130 def expect_correction(correction, loop: T.unsafe(nil), source: T.unsafe(nil)); end - # source://rubocop//lib/rubocop/rspec/expect_offense.rb#168 + # @raise [RuboCop::Runner::InfiniteCorrectionLoop] + # + # source://rubocop//lib/rubocop/rspec/expect_offense.rb#167 def expect_no_corrections; end # source://rubocop//lib/rubocop/rspec/expect_offense.rb#181 @@ -57172,7 +57205,7 @@ class RuboCop::Runner # otherwise dormant team that can be used for config- and option- # level caching in ResultCache. # - # source://rubocop//lib/rubocop/runner.rb#492 + # source://rubocop//lib/rubocop/runner.rb#499 def standby_team(config); end # @return [Boolean] @@ -57269,173 +57302,180 @@ RuboCop::StringInterpreter::STRING_ESCAPES = T.let(T.unsafe(nil), Hash) # source://rubocop//lib/rubocop/string_interpreter.rb#12 RuboCop::StringInterpreter::STRING_ESCAPE_REGEX = T.let(T.unsafe(nil), Regexp) -# This class finds target files to inspect by scanning the directory tree -# and picking ruby files. +# This class finds target files to inspect by scanning the directory tree and picking ruby files. # # @api private # -# source://rubocop//lib/rubocop/target_finder.rb#7 +# source://rubocop//lib/rubocop/target_finder.rb#6 class RuboCop::TargetFinder # @api private # @return [TargetFinder] a new instance of TargetFinder # - # source://rubocop//lib/rubocop/target_finder.rb#10 + # source://rubocop//lib/rubocop/target_finder.rb#9 def initialize(config_store, options = T.unsafe(nil)); end + # Generate a list of target files by expanding globbing patterns (if any). If args is empty, + # recursively find all Ruby source files under the current directory + # + # @api private + # @return [Array] array of file paths + # + # source://rubocop//lib/rubocop/target_finder.rb#17 + def find(args, mode); end + + # Search for files recursively starting at the given base directory using the given flags that + # determine how the match is made. Excluded files will be removed later by the caller, but as an + # optimization find_files removes the top level directories that are excluded in configuration + # in the normal way (dir/**/*). + # # @api private # - # source://rubocop//lib/rubocop/target_finder.rb#149 - def all_cops_include; end + # source://rubocop//lib/rubocop/target_finder.rb#58 + def find_files(base_dir, flags); end + + # @api private + # @return [Boolean] + # + # source://rubocop-md/1.2.2/lib/rubocop/markdown/rubocop_ext.rb#88 + def ruby_file?(file); end + + # Finds all Ruby source files under the current or other supplied directory. A Ruby source file + # is defined as a file with the `.rb` extension or a file with no extension that has a ruby + # shebang line as its first line. + # It is possible to specify includes and excludes using the config file, so you can include + # other Ruby files like Rakefiles and gemspecs. + # + # @api private + # @param base_dir Root directory under which to search for + # ruby source files + # @return [Array] Array of filenames + # + # source://rubocop//lib/rubocop/target_finder.rb#41 + def target_files_in_dir(base_dir = T.unsafe(nil)); end + + private # @api private # # source://rubocop//lib/rubocop/target_finder.rb#120 + def all_cops_include; end + + # @api private + # + # source://rubocop//lib/rubocop/target_finder.rb#106 def combined_exclude_glob_patterns(base_dir); end # @api private # @return [Boolean] # - # source://rubocop//lib/rubocop/target_finder.rb#176 + # source://rubocop//lib/rubocop/target_finder.rb#172 def configured_include?(file); end # @api private # @return [Boolean] # - # source://rubocop//lib/rubocop/target_finder.rb#19 + # source://rubocop//lib/rubocop/target_finder.rb#208 def debug?; end # @api private # @return [Boolean] # - # source://rubocop//lib/rubocop/target_finder.rb#23 + # source://rubocop//lib/rubocop/target_finder.rb#212 def fail_fast?; end - # Generate a list of target files by expanding globbing patterns - # (if any). If args is empty, recursively find all Ruby source - # files under the current directory - # # @api private - # @return [Array] array of file paths + # @return [Boolean] # - # source://rubocop//lib/rubocop/target_finder.rb#31 - def find(args, mode); end + # source://rubocop//lib/rubocop/target_finder.rb#200 + def force_exclusion?; end - # Search for files recursively starting at the given base directory using - # the given flags that determine how the match is made. Excluded files will - # be removed later by the caller, but as an optimization find_files removes - # the top level directories that are excluded in configuration in the - # normal way (dir/**/*). - # # @api private + # @return [Boolean] # - # source://rubocop//lib/rubocop/target_finder.rb#83 - def find_files(base_dir, flags); end + # source://rubocop//lib/rubocop/target_finder.rb#204 + def ignore_parent_exclusion?; end # @api private # @return [Boolean] # - # source://rubocop//lib/rubocop/target_finder.rb#15 - def force_exclusion?; end + # source://rubocop//lib/rubocop/target_finder.rb#145 + def included_file?(file); end # @api private - # @return [Boolean] # - # source://rubocop//lib/rubocop/target_finder.rb#180 - def included_file?(file); end + # source://rubocop//lib/rubocop/target_finder.rb#191 + def order; end # @api private # - # source://rubocop//lib/rubocop/target_finder.rb#184 + # source://rubocop//lib/rubocop/target_finder.rb#124 def process_explicit_path(path, mode); end # @api private # @return [Boolean] # - # source://rubocop//lib/rubocop/target_finder.rb#153 + # source://rubocop//lib/rubocop/target_finder.rb#176 def ruby_executable?(file); end # @api private # @return [Boolean] # - # source://rubocop//lib/rubocop/target_finder.rb#127 + # source://rubocop//lib/rubocop/target_finder.rb#157 def ruby_extension?(file); end # @api private # - # source://rubocop//lib/rubocop/target_finder.rb#131 + # source://rubocop//lib/rubocop/target_finder.rb#161 def ruby_extensions; end # @api private # @return [Boolean] # - # source://rubocop-md/1.2.2/lib/rubocop/markdown/rubocop_ext.rb#88 - def ruby_file?(file); end - - # @api private - # @return [Boolean] - # - # source://rubocop//lib/rubocop/target_finder.rb#138 + # source://rubocop//lib/rubocop/target_finder.rb#168 def ruby_filename?(file); end # @api private # - # source://rubocop//lib/rubocop/target_finder.rb#142 + # source://rubocop//lib/rubocop/target_finder.rb#113 def ruby_filenames; end # @api private # - # source://rubocop//lib/rubocop/target_finder.rb#164 + # source://rubocop//lib/rubocop/target_finder.rb#187 def ruby_interpreters(file); end # @api private # @return [Boolean] # - # source://rubocop//lib/rubocop/target_finder.rb#168 + # source://rubocop//lib/rubocop/target_finder.rb#153 def stdin?; end # @api private # @return [Boolean] # - # source://rubocop//lib/rubocop/target_finder.rb#112 + # source://rubocop//lib/rubocop/target_finder.rb#98 def symlink_excluded_or_infinite_loop?(base_dir, current_dir, exclude_pattern, flags); end - # Finds all Ruby source files under the current or other supplied - # directory. A Ruby source file is defined as a file with the `.rb` - # extension or a file with no extension that has a ruby shebang line - # as its first line. - # It is possible to specify includes and excludes using the config file, - # so you can include other Ruby files like Rakefiles and gemspecs. - # - # @api private - # @param base_dir Root directory under which to search for - # ruby source files - # @return [Array] Array of filenames - # - # source://rubocop//lib/rubocop/target_finder.rb#56 - def target_files_in_dir(base_dir = T.unsafe(nil)); end - # @api private # @return [Boolean] # - # source://rubocop//lib/rubocop/target_finder.rb#69 + # source://rubocop//lib/rubocop/target_finder.rb#73 def to_inspect?(file, hidden_files, base_dir_config); end # @api private # - # source://rubocop//lib/rubocop/target_finder.rb#96 + # source://rubocop//lib/rubocop/target_finder.rb#82 def wanted_dir_patterns(base_dir, exclude_pattern, flags); end - private - # @api private # - # source://rubocop//lib/rubocop/target_finder.rb#201 - def order; end + # source://rubocop//lib/rubocop/target_finder.rb#134 + def without_excluded(files); end end # @api private # -# source://rubocop//lib/rubocop/target_finder.rb#8 +# source://rubocop//lib/rubocop/target_finder.rb#7 RuboCop::TargetFinder::HIDDEN_PATH_SUBSTRING = T.let(T.unsafe(nil), String) # The kind of Ruby that code inspected by RuboCop is written in. @@ -57447,34 +57487,34 @@ class RuboCop::TargetRuby # @api private # @return [TargetRuby] a new instance of TargetRuby # - # source://rubocop//lib/rubocop/target_ruby.rb#252 + # source://rubocop//lib/rubocop/target_ruby.rb#254 def initialize(config); end # @api private # - # source://rubocop//lib/rubocop/target_ruby.rb#268 + # source://rubocop//lib/rubocop/target_ruby.rb#270 def rubocop_version_with_support; end # @api private # - # source://rubocop//lib/rubocop/target_ruby.rb#256 + # source://rubocop//lib/rubocop/target_ruby.rb#258 def source; end # @api private # @return [Boolean] # - # source://rubocop//lib/rubocop/target_ruby.rb#264 + # source://rubocop//lib/rubocop/target_ruby.rb#266 def supported?; end # @api private # - # source://rubocop//lib/rubocop/target_ruby.rb#260 + # source://rubocop//lib/rubocop/target_ruby.rb#262 def version; end class << self # @api private # - # source://rubocop//lib/rubocop/target_ruby.rb#238 + # source://rubocop//lib/rubocop/target_ruby.rb#240 def supported_versions; end end end @@ -57483,23 +57523,23 @@ end # # @api private # -# source://rubocop//lib/rubocop/target_ruby.rb#185 +# source://rubocop//lib/rubocop/target_ruby.rb#187 class RuboCop::TargetRuby::BundlerLockFile < ::RuboCop::TargetRuby::Source # @api private # - # source://rubocop//lib/rubocop/target_ruby.rb#186 + # source://rubocop//lib/rubocop/target_ruby.rb#188 def name; end private # @api private # - # source://rubocop//lib/rubocop/target_ruby.rb#219 + # source://rubocop//lib/rubocop/target_ruby.rb#221 def bundler_lock_file_path; end # @api private # - # source://rubocop//lib/rubocop/target_ruby.rb#192 + # source://rubocop//lib/rubocop/target_ruby.rb#194 def find_version; end end @@ -57512,18 +57552,18 @@ RuboCop::TargetRuby::DEFAULT_VERSION = T.let(T.unsafe(nil), Float) # # @api private # -# source://rubocop//lib/rubocop/target_ruby.rb#226 +# source://rubocop//lib/rubocop/target_ruby.rb#228 class RuboCop::TargetRuby::Default < ::RuboCop::TargetRuby::Source # @api private # - # source://rubocop//lib/rubocop/target_ruby.rb#227 + # source://rubocop//lib/rubocop/target_ruby.rb#229 def name; end private # @api private # - # source://rubocop//lib/rubocop/target_ruby.rb#233 + # source://rubocop//lib/rubocop/target_ruby.rb#235 def find_version; end end @@ -57550,7 +57590,7 @@ class RuboCop::TargetRuby::GemspecFile < ::RuboCop::TargetRuby::Source # @api private # - # source://rubocop//lib/rubocop/target_ruby.rb#119 + # source://rubocop//lib/rubocop/target_ruby.rb#121 def find_default_minimal_known_ruby(right_hand_side); end # @api private @@ -57570,7 +57610,7 @@ class RuboCop::TargetRuby::GemspecFile < ::RuboCop::TargetRuby::Source # @api private # - # source://rubocop//lib/rubocop/target_ruby.rb#115 + # source://rubocop//lib/rubocop/target_ruby.rb#117 def version_from_array(array); end # @api private @@ -57580,7 +57620,7 @@ class RuboCop::TargetRuby::GemspecFile < ::RuboCop::TargetRuby::Source # @api private # - # source://rubocop//lib/rubocop/target_ruby.rb#103 + # source://rubocop//lib/rubocop/target_ruby.rb#105 def version_from_right_hand_side(right_hand_side); end end @@ -57622,49 +57662,49 @@ end # # @api private # -# source://rubocop//lib/rubocop/target_ruby.rb#131 +# source://rubocop//lib/rubocop/target_ruby.rb#133 class RuboCop::TargetRuby::RubyVersionFile < ::RuboCop::TargetRuby::Source # @api private # - # source://rubocop//lib/rubocop/target_ruby.rb#135 + # source://rubocop//lib/rubocop/target_ruby.rb#137 def name; end private # @api private # - # source://rubocop//lib/rubocop/target_ruby.rb#141 + # source://rubocop//lib/rubocop/target_ruby.rb#143 def filename; end # @api private # - # source://rubocop//lib/rubocop/target_ruby.rb#149 + # source://rubocop//lib/rubocop/target_ruby.rb#151 def find_version; end # @api private # - # source://rubocop//lib/rubocop/target_ruby.rb#145 + # source://rubocop//lib/rubocop/target_ruby.rb#147 def pattern; end # @api private # - # source://rubocop//lib/rubocop/target_ruby.rb#156 + # source://rubocop//lib/rubocop/target_ruby.rb#158 def version_file; end end # @api private # -# source://rubocop//lib/rubocop/target_ruby.rb#132 +# source://rubocop//lib/rubocop/target_ruby.rb#134 RuboCop::TargetRuby::RubyVersionFile::RUBY_VERSION_FILENAME = T.let(T.unsafe(nil), String) # @api private # -# source://rubocop//lib/rubocop/target_ruby.rb#133 +# source://rubocop//lib/rubocop/target_ruby.rb#135 RuboCop::TargetRuby::RubyVersionFile::RUBY_VERSION_PATTERN = T.let(T.unsafe(nil), Regexp) # @api private # -# source://rubocop//lib/rubocop/target_ruby.rb#242 +# source://rubocop//lib/rubocop/target_ruby.rb#244 RuboCop::TargetRuby::SOURCES = T.let(T.unsafe(nil), Array) # A place where information about a target ruby version is found. @@ -57700,34 +57740,34 @@ end # # @api private # -# source://rubocop//lib/rubocop/target_ruby.rb#164 +# source://rubocop//lib/rubocop/target_ruby.rb#166 class RuboCop::TargetRuby::ToolVersionsFile < ::RuboCop::TargetRuby::RubyVersionFile # @api private # - # source://rubocop//lib/rubocop/target_ruby.rb#168 + # source://rubocop//lib/rubocop/target_ruby.rb#170 def name; end private # @api private # - # source://rubocop//lib/rubocop/target_ruby.rb#174 + # source://rubocop//lib/rubocop/target_ruby.rb#176 def filename; end # @api private # - # source://rubocop//lib/rubocop/target_ruby.rb#178 + # source://rubocop//lib/rubocop/target_ruby.rb#180 def pattern; end end # @api private # -# source://rubocop//lib/rubocop/target_ruby.rb#165 +# source://rubocop//lib/rubocop/target_ruby.rb#167 RuboCop::TargetRuby::ToolVersionsFile::TOOL_VERSIONS_FILENAME = T.let(T.unsafe(nil), String) # @api private # -# source://rubocop//lib/rubocop/target_ruby.rb#166 +# source://rubocop//lib/rubocop/target_ruby.rb#168 RuboCop::TargetRuby::ToolVersionsFile::TOOL_VERSIONS_PATTERN = T.let(T.unsafe(nil), Regexp) # source://rubocop//lib/rubocop/ast_aliases.rb#7 @@ -57753,12 +57793,12 @@ module RuboCop::Version class << self # @api private # - # source://rubocop//lib/rubocop/version.rb#93 + # source://rubocop//lib/rubocop/version.rb#108 def document_version; end # @api private # - # source://rubocop//lib/rubocop/version.rb#43 + # source://rubocop//lib/rubocop/version.rb#58 def extension_versions(env); end # Returns feature version in one of two ways: @@ -57768,12 +57808,17 @@ module RuboCop::Version # # @api private # - # source://rubocop//lib/rubocop/version.rb#77 + # source://rubocop//lib/rubocop/version.rb#92 def feature_version(feature); end # @api private # - # source://rubocop//lib/rubocop/version.rb#98 + # source://rubocop//lib/rubocop/version.rb#43 + def parser_version; end + + # @api private + # + # source://rubocop//lib/rubocop/version.rb#113 def server_mode; end # @api private diff --git a/Library/Homebrew/sorbet/rbi/upstream.rbi b/Library/Homebrew/sorbet/rbi/upstream.rbi index 2aa21d6a36dbd9..a00487f95aced4 100644 --- a/Library/Homebrew/sorbet/rbi/upstream.rbi +++ b/Library/Homebrew/sorbet/rbi/upstream.rbi @@ -2,21 +2,3 @@ # This file contains temporary definitions for fixes that have # been submitted upstream to https://github.com/sorbet/sorbet. - -# https://github.com/sorbet/sorbet/pull/7650 -class Etc::Group < Struct - sig { returns(Integer) } - def gid; end - sig { returns(T::Array[String]) } - def mem; end - sig { returns(String) } - def name; end - sig { returns(String) } - def passwd; end -end - -# https://github.com/sorbet/sorbet/pull/7647 -module IRB - sig { params(ap_path: T.nilable(String), argv: T::Array[String]).void } - def self.setup(ap_path, argv: ::ARGV); end -end diff --git a/Library/Homebrew/sorbet/tapioca/compilers/args.rb b/Library/Homebrew/sorbet/tapioca/compilers/args.rb new file mode 100644 index 00000000000000..5a226f1eaa35a9 --- /dev/null +++ b/Library/Homebrew/sorbet/tapioca/compilers/args.rb @@ -0,0 +1,74 @@ +# typed: strict +# frozen_string_literal: true + +require_relative "../../../global" + +module Tapioca + module Compilers + class Args < Tapioca::Dsl::Compiler + # This is ugly, but we're moving to a new interface that will use a consistent DSL + # These are cmd/dev-cmd methods that end in `_args` but are not parsers + NON_PARSER_ARGS_METHODS = T.let([ + :formulae_all_installs_from_args, + :reproducible_gnutar_args, + :tar_args, + ].freeze, T::Array[Symbol]) + + # FIXME: Enable cop again when https://github.com/sorbet/sorbet/issues/3532 is fixed. + # rubocop:disable Style/MutableConstant + ConstantType = type_member { { fixed: T.class_of(Homebrew::CLI::Args) } } + # rubocop:enable Style/MutableConstant + + sig { override.returns(T::Enumerable[T.class_of(Homebrew::CLI::Args)]) } + def self.gather_constants + # require all the commands to ensure the _arg methods are defined + ["cmd", "dev-cmd"].each do |dir| + Dir[File.join(__dir__, "../../../#{dir}", "*.rb")].each { require(_1) } + end + [Homebrew::CLI::Args] + end + + sig { override.void } + def decorate + root.create_path(Homebrew::CLI::Args) do |klass| + Homebrew.methods(false).select { _1.end_with?("_args") }.each do |args_method_name| + next if NON_PARSER_ARGS_METHODS.include?(args_method_name) + + parser = Homebrew.method(args_method_name).call + comma_array_methods = comma_arrays(parser) + args_table(parser).each do |method_name, value| + # some args are used in multiple commands (this is ok as long as they have the same type) + next if klass.nodes.any? { T.cast(_1, RBI::Method).name.to_sym == method_name } + + return_type = get_return_type(method_name, value, comma_array_methods) + klass.create_method(method_name.to_s, return_type:) + end + end + end + end + + sig { params(parser: Homebrew::CLI::Parser).returns(T::Hash[Symbol, T.untyped]) } + def args_table(parser) + # we exclude non-args from the table, such as :named and :remaining + parser.instance_variable_get(:@args).instance_variable_get(:@table).except(:named, :remaining) + end + + sig { params(parser: Homebrew::CLI::Parser).returns(T::Array[Symbol]) } + def comma_arrays(parser) + parser.instance_variable_get(:@non_global_processed_options) + .filter_map { |k, v| parser.option_to_name(k).to_sym if v == :comma_array } + end + + sig { params(method_name: Symbol, value: T.untyped, comma_array_methods: T::Array[Symbol]).returns(String) } + def get_return_type(method_name, value, comma_array_methods) + if comma_array_methods.include?(method_name) + "T.nilable(T::Array[String])" + elsif [true, false].include?(value) + "T::Boolean" + else + "T.nilable(String)" + end + end + end + end +end diff --git a/Library/Homebrew/sorbet/tapioca/config.yml b/Library/Homebrew/sorbet/tapioca/config.yml index 3c183d90d3d447..3ecfe9fb27a554 100644 --- a/Library/Homebrew/sorbet/tapioca/config.yml +++ b/Library/Homebrew/sorbet/tapioca/config.yml @@ -13,16 +13,12 @@ gem: - docile - hana - highline - - hpricot - language_server-protocol - - mustache - netrc - parallel - public_suffix - racc - - rdiscount - rexml - - ronn - rspec-github - rspec-mocks - rspec-retry diff --git a/Library/Homebrew/standalone/sorbet.rb b/Library/Homebrew/standalone/sorbet.rb index d15116a8f1e4b5..85647b6fbe8e7a 100644 --- a/Library/Homebrew/standalone/sorbet.rb +++ b/Library/Homebrew/standalone/sorbet.rb @@ -13,19 +13,19 @@ # @private module TNoChecks def cast(value, type, checked: false) - super(value, type, checked: checked) + super(value, type, checked:) end def let(value, type, checked: false) - super(value, type, checked: checked) + super(value, type, checked:) end def bind(value, type, checked: false) - super(value, type, checked: checked) + super(value, type, checked:) end def assert_type!(value, type, checked: false) - super(value, type, checked: checked) + super(value, type, checked:) end end diff --git a/Library/Homebrew/startup/bootsnap.rb b/Library/Homebrew/startup/bootsnap.rb index 8bd7f230838fcd..f082307efde2ae 100644 --- a/Library/Homebrew/startup/bootsnap.rb +++ b/Library/Homebrew/startup/bootsnap.rb @@ -38,7 +38,7 @@ Bootsnap.setup( cache_dir: cache, - ignore_directories: ignore_directories, + ignore_directories:, load_path_cache: true, compile_cache_iseq: true, compile_cache_yaml: true, diff --git a/Library/Homebrew/style.rb b/Library/Homebrew/style.rb index 954d06f0d8ce6e..69d13d8a1a6fa4 100644 --- a/Library/Homebrew/style.rb +++ b/Library/Homebrew/style.rb @@ -23,7 +23,7 @@ def self.check_style_and_print(files, **options) line = o.location.line column = o.location.line - annotation = GitHub::Actions::Annotation.new(:error, o.message, file: path, line: line, column: column) + annotation = GitHub::Actions::Annotation.new(:error, o.message, file: path, line:, column:) puts annotation if annotation.relevant? end end @@ -54,23 +54,23 @@ def self.check_style_impl(files, output_type, (output_type == :json) ? [] : true else run_rubocop(ruby_files, output_type, - fix: fix, - except_cops: except_cops, only_cops: only_cops, - display_cop_names: display_cop_names, - reset_cache: reset_cache, - debug: debug, verbose: verbose) + fix:, + except_cops:, only_cops:, + display_cop_names:, + reset_cache:, + debug:, verbose:) end shellcheck_result = if ruby_files.any? && shell_files.none? (output_type == :json) ? [] : true else - run_shellcheck(shell_files, output_type, fix: fix) + run_shellcheck(shell_files, output_type, fix:) end shfmt_result = if ruby_files.any? && shell_files.none? true else - run_shfmt(shell_files, fix: fix) + run_shfmt(shell_files, fix:) end if output_type == :json diff --git a/Library/Homebrew/system_command.rb b/Library/Homebrew/system_command.rb index d9935d007d41c2..55ec51978990a0 100644 --- a/Library/Homebrew/system_command.rb +++ b/Library/Homebrew/system_command.rb @@ -276,7 +276,7 @@ def each_output_line(&block) sig { params(raw_stdin: IO).void } def write_input_to(raw_stdin) - input.each(&raw_stdin.method(:write)) + input.each { raw_stdin.write(_1) } end sig { params(sources: T::Array[IO], _block: T.proc.params(type: Symbol, line: String).void).void } diff --git a/Library/Homebrew/tab.rb b/Library/Homebrew/tab.rb index 44225a085bc4e2..1431c8fdcdfd4d 100644 --- a/Library/Homebrew/tab.rb +++ b/Library/Homebrew/tab.rb @@ -322,11 +322,11 @@ def versions end def stable_version - versions["stable"]&.then(&Version.method(:new)) + versions["stable"]&.then { Version.new(_1) } end def head_version - versions["head"]&.then(&Version.method(:new)) + versions["head"]&.then { Version.new(_1) } end def version_scheme diff --git a/Library/Homebrew/tap.rb b/Library/Homebrew/tap.rb index b6e0c1d2ad5d0a..8599a20bfc8cb7 100644 --- a/Library/Homebrew/tap.rb +++ b/Library/Homebrew/tap.rb @@ -22,9 +22,10 @@ class Tap HOMEBREW_TAP_FORMULA_RENAMES_FILE = "formula_renames.json" HOMEBREW_TAP_MIGRATIONS_FILE = "tap_migrations.json" HOMEBREW_TAP_AUTOBUMP_FILE = ".github/autobump.txt" + HOMEBREW_TAP_PYPI_FORMULA_MAPPINGS_FILE = "pypi_formula_mappings.json" + HOMEBREW_TAP_SYNCED_VERSIONS_FORMULAE_FILE = "synced_versions_formulae.json" HOMEBREW_TAP_AUDIT_EXCEPTIONS_DIR = "audit_exceptions" HOMEBREW_TAP_STYLE_EXCEPTIONS_DIR = "style_exceptions" - HOMEBREW_TAP_PYPI_FORMULA_MAPPINGS = "pypi_formula_mappings.json" TAP_MIGRATIONS_STALE_SECONDS = 86400 # 1 day @@ -32,42 +33,46 @@ class Tap #{HOMEBREW_TAP_FORMULA_RENAMES_FILE} #{HOMEBREW_TAP_CASK_RENAMES_FILE} #{HOMEBREW_TAP_MIGRATIONS_FILE} + #{HOMEBREW_TAP_PYPI_FORMULA_MAPPINGS_FILE} + #{HOMEBREW_TAP_SYNCED_VERSIONS_FORMULAE_FILE} #{HOMEBREW_TAP_AUDIT_EXCEPTIONS_DIR}/*.json #{HOMEBREW_TAP_STYLE_EXCEPTIONS_DIR}/*.json - #{HOMEBREW_TAP_PYPI_FORMULA_MAPPINGS} ].freeze - def self.fetch(*args) - case args.length - when 1 - user, repo = args.first.split("/", 2) - when 2 - user = args.first - repo = args.second + sig { params(user: String, repo: String).returns(Tap) } + def self.fetch(user, repo = T.unsafe(nil)) + user, repo = user.split("/", 2) if repo.nil? + + if [user, repo].any? { |part| part.nil? || part.include?("/") } + raise ArgumentError, "Invalid tap name: '#{[*user, *repo].join("/")}'" end - raise "Invalid tap name '#{args.join("/")}'" if [user, repo].any? { |part| part.nil? || part.include?("/") } + user = T.must(user) + repo = T.must(repo) # We special case homebrew and linuxbrew so that users don't have to shift in a terminal. - user = user.capitalize if ["homebrew", "linuxbrew"].include? user + user = user.capitalize if ["homebrew", "linuxbrew"].include?(user) repo = repo.sub(HOMEBREW_OFFICIAL_REPO_PREFIXES_REGEX, "") return CoreTap.instance if ["Homebrew", "Linuxbrew"].include?(user) && ["core", "homebrew"].include?(repo) return CoreCaskTap.instance if user == "Homebrew" && repo == "cask" cache_key = "#{user}/#{repo}".downcase - cache.fetch(cache_key) { |key| cache[key] = Tap.new(user, repo) } + cache.fetch(cache_key) { |key| cache[key] = new(user, repo) } end def self.from_path(path) match = File.expand_path(path).match(HOMEBREW_TAP_PATH_REGEX) - return if match.blank? || match[:user].blank? || match[:repo].blank? - fetch(match[:user], match[:repo]) + return unless match + return unless (user = match[:user]) + return unless (repo = match[:repo]) + + fetch(user, repo) end # @private - sig { params(name: String).returns(T.nilable([T.attached_class, String])) } + sig { params(name: String).returns(T.nilable([Tap, String])) } def self.with_formula_name(name) return unless (match = name.match(HOMEBREW_TAP_FORMULA_REGEX)) @@ -83,7 +88,7 @@ def self.with_formula_name(name) end # @private - sig { params(token: String).returns(T.nilable([T.attached_class, String])) } + sig { params(token: String).returns(T.nilable([Tap, String])) } def self.with_cask_token(token) return unless (match = token.match(HOMEBREW_TAP_CASK_REGEX)) @@ -140,6 +145,9 @@ def self.install_default_cask_tap_if_necessary(force: false) sig { returns(GitRepository) } attr_reader :git_repo + # Always use `Tap.fetch` instead of `Tap.new`. + private_class_method :new + # @private def initialize(user, repo) @user = user @@ -148,38 +156,48 @@ def initialize(user, repo) @full_name = "#{@user}/homebrew-#{@repo}" @path = TAP_DIRECTORY/@full_name.downcase @git_repo = GitRepository.new(@path) - @alias_table = nil - @alias_reverse_table = nil end # Clear internal cache. def clear_cache @remote = nil @repo_var_suffix = nil + remove_instance_variable(:@private) if instance_variable_defined?(:@private) + @formula_dir = nil - @cask_dir = nil - @command_dir = nil - @formula_names = nil @formula_files = nil @formula_files_by_name = nil + @formula_names = nil + @prefix_to_versioned_formulae_names = nil + @formula_renames = nil @formula_reverse_renames = nil + + @cask_dir = nil @cask_files = nil @cask_files_by_name = nil + @cask_tokens = nil + @cask_renames = nil @cask_reverse_renames = nil + @alias_dir = nil @alias_files = nil @aliases = nil @alias_table = nil @alias_reverse_table = nil + + @command_dir = nil @command_files = nil - @formula_renames = nil + @tap_migrations = nil + @reverse_tap_migrations_renames = nil + @audit_exceptions = nil @style_exceptions = nil @pypi_formula_mappings = nil + @synced_versions_formulae = nil + @config = nil @spell_checker = nil - remove_instance_variable(:@private) if instance_variable_defined?(:@private) end sig { void } @@ -199,8 +217,9 @@ def remote # The remote repository name of this {Tap}. # e.g. `user/homebrew-repo` + sig { returns(T.nilable(String)) } def remote_repo - return unless remote + return unless (remote = self.remote) @remote_repo ||= remote.delete_prefix("https://github.com/") .delete_prefix("git@github.com:") @@ -266,11 +285,29 @@ def official? user == "Homebrew" end - # True if the remote of this {Tap} is a private repository. + # Check whether the remote of this {Tap} is a private repository. + sig { returns(T::Boolean) } def private? - return @private if instance_variable_defined?(:@private) + return @private if defined?(@private) - @private = read_or_set_private_config + @private = if (value = config[:private]).nil? + config[:private] = begin + if custom_remote? + true + else + # Don't store config if we don't know for sure. + return false if (value = GitHub.private_repo?(full_name)).nil? + + value + end + rescue GitHub::API::HTTPNotFoundError + true + rescue GitHub::API::Error + false + end + else + value + end end # {TapConfig} of this {Tap}. @@ -284,6 +321,7 @@ def config end # True if this {Tap} has been installed. + sig { returns(T::Boolean) } def installed? path.directory? end @@ -308,13 +346,11 @@ def core_cask_tap? # Install this {Tap}. # # @param clone_target [String] If passed, it will be used as the clone remote. - # @param force_auto_update [Boolean, nil] If present, whether to override the - # logic that skips non-GitHub repositories during auto-updates. # @param quiet [Boolean] If set, suppress all output. # @param custom_remote [Boolean] If set, change the tap's remote if already installed. # @param verify [Boolean] If set, verify all the formula, casks and aliases in the tap are valid. # @param force [Boolean] If set, force core and cask taps to install even under API mode. - def install(quiet: false, clone_target: nil, force_auto_update: nil, + def install(quiet: false, clone_target: nil, custom_remote: false, verify: false, force: false) require "descriptions" require "readall" @@ -332,7 +368,7 @@ def install(quiet: false, clone_target: nil, force_auto_update: nil, if installed? && !custom_remote raise TapRemoteMismatchError.new(name, @remote, requested_remote) if clone_target && requested_remote != remote - raise TapAlreadyTappedError, name if force_auto_update.nil? && !shallow? + raise TapAlreadyTappedError, name unless shallow? end # ensure git is installed @@ -340,17 +376,10 @@ def install(quiet: false, clone_target: nil, force_auto_update: nil, if installed? if requested_remote != remote # we are sure that clone_target is not nil and custom_remote is true here - fix_remote_configuration(requested_remote: requested_remote, quiet: quiet) + fix_remote_configuration(requested_remote:, quiet:) end - unless force_auto_update.nil? - if force_auto_update - config["forceautoupdate"] = force_auto_update - elsif config["forceautoupdate"] == "true" - config.delete("forceautoupdate") - end - return - end + config.delete(:forceautoupdate) $stderr.ohai "Unshallowing #{name}" if shallow? && !quiet args = %w[fetch] @@ -365,6 +394,7 @@ def install(quiet: false, clone_target: nil, force_auto_update: nil, end clear_cache + Tap.clear_cache $stderr.ohai "Tapping #{name}" unless quiet args = %W[clone #{requested_remote} #{path}] @@ -395,8 +425,6 @@ def install(quiet: false, clone_target: nil, force_auto_update: nil, raise end - config["forceautoupdate"] = force_auto_update unless force_auto_update.nil? - Commands.rebuild_commands_completion_list link_completions_and_manpages @@ -509,6 +537,7 @@ def uninstall(manual: false) Commands.rebuild_commands_completion_list clear_cache + Tap.clear_cache return if !manual || !official? @@ -520,10 +549,11 @@ def uninstall(manual: false) end # True if the {#remote} of {Tap} is customized. + sig { returns(T::Boolean) } def custom_remote? - return true unless remote + return true unless (remote = self.remote) - remote.casecmp(default_remote).nonzero? + !remote.casecmp(default_remote).zero? end # Path to the directory of all {Formula} files for this {Tap}. @@ -710,30 +740,25 @@ def aliases @aliases ||= alias_table.keys end - # a table mapping alias to formula name + # Mapping from aliases to formula names. + # # @private sig { returns(T::Hash[String, String]) } def alias_table - return @alias_table if @alias_table - - @alias_table = {} - alias_files.each do |alias_file| - @alias_table[alias_file_to_name(alias_file)] = formula_file_to_name(alias_file.resolved_path) + @alias_table ||= alias_files.each_with_object({}) do |alias_file, alias_table| + alias_table[alias_file_to_name(alias_file)] = formula_file_to_name(alias_file.resolved_path) end - @alias_table end - # a table mapping formula name to aliases + # Mapping from formula names to aliases. + # # @private + sig { returns(T::Hash[String, T::Array[String]]) } def alias_reverse_table - return @alias_reverse_table if @alias_reverse_table - - @alias_reverse_table = {} - alias_table.each do |alias_name, formula_name| - @alias_reverse_table[formula_name] ||= [] - @alias_reverse_table[formula_name] << alias_name + @alias_reverse_table ||= alias_table.each_with_object({}) do |(alias_name, formula_name), alias_reverse_table| + alias_reverse_table[formula_name] ||= [] + alias_reverse_table[formula_name] << alias_name end - @alias_reverse_table end sig { returns(Pathname) } @@ -818,21 +843,6 @@ def formula_reverse_renames end end - sig { returns(T::Hash[String, T::Array[String]]) } - def self.reverse_tap_migrations_renames - cache[:reverse_tap_migrations_renames] ||= Tap.each_with_object({}) do |tap, hash| - tap.tap_migrations.each do |old_name, new_name| - new_tap_user, new_tap_repo, new_name = new_name.split("/", 3) - next unless new_name - - new_tap = Tap.fetch(new_tap_user, new_tap_repo) - - hash["#{new_tap}/#{new_name}"] ||= [] - hash["#{new_tap}/#{new_name}"] << old_name - end - end - end - # Hash with tap migrations. sig { returns(T::Hash[String, String]) } def tap_migrations @@ -843,21 +853,73 @@ def tap_migrations end end + sig { returns(T::Hash[String, T::Array[String]]) } + def reverse_tap_migrations_renames + @reverse_tap_migrations_renames ||= tap_migrations.each_with_object({}) do |(old_name, new_name), hash| + # Only include renames: + # + `homebrew/cask/water-buffalo` + # - `homebrew/cask` + next if new_name.count("/") != 2 + + hash[new_name] ||= [] + hash[new_name] << old_name + end + end + + # The old names a formula or cask had before getting migrated to the current tap. + sig { params(current_tap: Tap, name_or_token: String).returns(T::Array[String]) } + def self.tap_migration_oldnames(current_tap, name_or_token) + key = "#{current_tap}/#{name_or_token}" + + Tap.each_with_object([]) do |tap, array| + next unless (renames = tap.reverse_tap_migrations_renames[key]) + + array.concat(renames) + end + end + + # Array with autobump names + sig { returns(T::Array[String]) } + def autobump + @autobump ||= if (autobump_file = path/HOMEBREW_TAP_AUTOBUMP_FILE).file? + autobump_file.readlines(chomp: true) + else + [] + end + end + + # Whether this {Tap} allows running bump commands on the given {Formula} or {Cask}. + sig { params(formula_or_cask_name: String).returns(T::Boolean) } + def allow_bump?(formula_or_cask_name) + ENV["HOMEBREW_TEST_BOT_AUTOBUMP"].present? || !official? || autobump.exclude?(formula_or_cask_name) + end + # Hash with audit exceptions sig { returns(Hash) } def audit_exceptions - @audit_exceptions = read_formula_list_directory "#{HOMEBREW_TAP_AUDIT_EXCEPTIONS_DIR}/*" + @audit_exceptions ||= read_formula_list_directory("#{HOMEBREW_TAP_AUDIT_EXCEPTIONS_DIR}/*") end # Hash with style exceptions sig { returns(Hash) } def style_exceptions - @style_exceptions = read_formula_list_directory "#{HOMEBREW_TAP_STYLE_EXCEPTIONS_DIR}/*" + @style_exceptions ||= read_formula_list_directory("#{HOMEBREW_TAP_STYLE_EXCEPTIONS_DIR}/*") end # Hash with pypi formula mappings + sig { returns(Hash) } def pypi_formula_mappings - @pypi_formula_mappings = read_formula_list path/HOMEBREW_TAP_PYPI_FORMULA_MAPPINGS + @pypi_formula_mappings ||= read_formula_list(path/HOMEBREW_TAP_PYPI_FORMULA_MAPPINGS_FILE) + end + + # Array with synced versions formulae + sig { returns(T::Array[T::Array[String]]) } + def synced_versions_formulae + @synced_versions_formulae ||= if (synced_file = path/HOMEBREW_TAP_SYNCED_VERSIONS_FORMULAE_FILE).file? + JSON.parse(synced_file.read) + else + [] + end end # @private @@ -869,29 +931,44 @@ def should_report_analytics? sig { params(other: T.nilable(T.any(String, Tap))).returns(T::Boolean) } def ==(other) other = Tap.fetch(other) if other.is_a?(String) - self.class == other.class && name == other.name + other.is_a?(self.class) && name == other.name end + alias eql? == - def self.each(&block) - return to_enum unless block + sig { returns(Integer) } + def hash + [self.class, name].hash + end - installed_taps = if TAP_DIRECTORY.directory? - TAP_DIRECTORY.subdirs - .flat_map(&:subdirs) - .map(&method(:from_path)) + # All locally installed taps. + sig { returns(T::Array[Tap]) } + def self.installed + cache[:installed] ||= if TAP_DIRECTORY.directory? + TAP_DIRECTORY.subdirs.flat_map(&:subdirs).map(&method(:from_path)) else [] end + end - available_taps = if Homebrew::EnvConfig.no_install_from_api? - installed_taps - else - default_taps = T.let([CoreTap.instance], T::Array[Tap]) - default_taps << CoreCaskTap.instance if OS.mac? # rubocop:disable Homebrew/MoveToExtendOS - installed_taps + default_taps - end.sort_by(&:name).uniq + # All locally installed and core taps. Core taps might not be installed locally when using the API. + sig { returns(T::Array[Tap]) } + def self.all + cache[:all] ||= begin + core_taps = [ + CoreTap.instance, + (CoreCaskTap.instance if OS.mac?), # rubocop:disable Homebrew/MoveToExtendOS + ].compact + + installed | core_taps + end + end - available_taps.each(&block) + def self.each(&block) + if Homebrew::EnvConfig.no_install_from_api? + installed.each(&block) + else + all.each(&block) + end end # An array of all installed {Tap} names. @@ -945,25 +1022,6 @@ def audit_exception(list, formula_or_cask, value = nil) private - def read_or_set_private_config - case config["private"] - when "true" then true - when "false" then false - else - config["private"] = begin - if custom_remote? - true - else - GitHub.private_repo?(full_name) - end - rescue GitHub::API::HTTPNotFoundError - true - rescue GitHub::API::Error - false - end - end - end - sig { params(file: Pathname).returns(T.any(T::Array[String], Hash)) } def read_formula_list(file) JSON.parse file.read @@ -996,6 +1054,8 @@ class AbstractCoreTap < Tap abstract! + private_class_method :fetch + sig { returns(T.attached_class) } def self.instance @instance ||= T.unsafe(self).new @@ -1016,6 +1076,12 @@ def self.ensure_installed! instance.ensure_installed! end + # @private + sig { params(file: Pathname).returns(String) } + def formula_file_to_name(file) + file.basename(".rb").to_s + end + # @private sig { override.returns(T::Boolean) } def should_report_analytics? @@ -1048,7 +1114,7 @@ def remote end # CoreTap never allows shallow clones (on request from GitHub). - def install(quiet: false, clone_target: nil, force_auto_update: nil, + def install(quiet: false, clone_target: nil, custom_remote: false, verify: false, force: false) remote = Homebrew::EnvConfig.core_git_remote # set by HOMEBREW_CORE_GIT_REMOTE requested_remote = clone_target || remote @@ -1060,8 +1126,7 @@ def install(quiet: false, clone_target: nil, force_auto_update: nil, $stderr.puts "HOMEBREW_CORE_GIT_REMOTE set: using #{remote} as the Homebrew/homebrew-core Git remote." end - super(quiet: quiet, clone_target: remote, force_auto_update: force_auto_update, - custom_remote: custom_remote, force: force) + super(quiet:, clone_target: remote, custom_remote:, force:) end # @private @@ -1141,6 +1206,15 @@ def tap_migrations end end + # @private + sig { returns(T::Array[String]) } + def autobump + @autobump ||= begin + ensure_installed! + super + end + end + # @private sig { returns(Hash) } def audit_exceptions @@ -1169,9 +1243,12 @@ def pypi_formula_mappings end # @private - sig { params(file: Pathname).returns(String) } - def formula_file_to_name(file) - file.basename(".rb").to_s + sig { returns(T::Array[T::Array[String]]) } + def synced_versions_formulae + @synced_versions_formulae ||= begin + ensure_installed! + super + end end # @private @@ -1225,10 +1302,10 @@ def formula_files_by_name end sig { returns(T::Hash[String, T.untyped]) } - def to_api_hash + def to_internal_api_hash formulae_api_hash = formula_names.to_h do |name| formula = Formulary.factory(name) - formula_hash = formula.to_hash_with_variations(hash_method: :to_api_hash) + formula_hash = formula.to_hash_with_variations(hash_method: :to_internal_api_hash) [name, formula_hash] end @@ -1309,10 +1386,27 @@ def tap_migrations migrations end end + + sig { returns(T::Hash[String, T.untyped]) } + def to_internal_api_hash + casks_api_hash = cask_tokens.to_h do |token| + cask = Cask::CaskLoader.load(token) + cask_hash = cask.to_hash_with_variations(hash_method: :to_internal_api_hash) + [token, cask_hash] + end + + { + "tap_git_head" => git_head, + "renames" => cask_renames, + "tap_migrations" => tap_migrations, + "casks" => casks_api_hash, + } + end end # Permanent configuration per {Tap} using `git-config(1)`. class TapConfig + sig { returns(Tap) } attr_reader :tap sig { params(tap: Tap).void } @@ -1320,13 +1414,18 @@ def initialize(tap) @tap = tap end + sig { params(key: Symbol).returns(T.nilable(T::Boolean)) } def [](key) return unless tap.git? return unless Utils::Git.available? - Homebrew::Settings.read key, repo: tap.path + case Homebrew::Settings.read(key, repo: tap.path) + when "true" then true + when "false" then false + end end + sig { params(key: Symbol, value: T::Boolean).void } def []=(key, value) return unless tap.git? return unless Utils::Git.available? @@ -1334,6 +1433,7 @@ def []=(key, value) Homebrew::Settings.write key, value.to_s, repo: tap.path end + sig { params(key: Symbol).void } def delete(key) return unless tap.git? return unless Utils::Git.available? diff --git a/Library/Homebrew/tap_auditor.rb b/Library/Homebrew/tap_auditor.rb index 2910236abd93dc..2e7c3cd08059bc 100644 --- a/Library/Homebrew/tap_auditor.rb +++ b/Library/Homebrew/tap_auditor.rb @@ -14,12 +14,14 @@ def initialize(tap, strict:) Homebrew.with_no_api_env do @name = tap.name @path = tap.path - @cask_tokens = tap.cask_tokens @tap_audit_exceptions = tap.audit_exceptions @tap_style_exceptions = tap.style_exceptions @tap_pypi_formula_mappings = tap.pypi_formula_mappings @problems = [] + @cask_tokens = tap.cask_tokens.map do |cask_token| + cask_token.split("/").last + end @formula_aliases = tap.aliases.map do |formula_alias| formula_alias.split("/").last end @@ -64,7 +66,7 @@ def audit_aliases_renames_duplicates sig { params(message: String).void } def problem(message) - @problems << ({ message: message, location: nil, corrected: false }) + @problems << ({ message:, location: nil, corrected: false }) end private @@ -83,7 +85,7 @@ def check_formula_list(list_file, list) invalid_formulae_casks = list.select do |formula_or_cask_name| formula_names.exclude?(formula_or_cask_name) && formula_aliases.exclude?(formula_or_cask_name) && - cask_tokens.exclude?("#{@name}/#{formula_or_cask_name}") + cask_tokens.exclude?(formula_or_cask_name) end return if invalid_formulae_casks.empty? diff --git a/Library/Homebrew/test.rb b/Library/Homebrew/test.rb index a9c5d3053d9984..9748e84ff84691 100644 --- a/Library/Homebrew/test.rb +++ b/Library/Homebrew/test.rb @@ -40,7 +40,7 @@ end ENV.extend(Stdenv) - ENV.setup_build_environment(formula: formula, testing_formula: true) + ENV.setup_build_environment(formula:, testing_formula: true) # tests can also return false to indicate failure run_test = proc { |_ = nil| raise "test returned false" if formula.run_test(keep_tmp: args.keep_tmp?) == false } diff --git a/Library/Homebrew/test/.rubocop.yml b/Library/Homebrew/test/.rubocop.yml index 85cbaa24440000..47f0ac2690a4ec 100644 --- a/Library/Homebrew/test/.rubocop.yml +++ b/Library/Homebrew/test/.rubocop.yml @@ -14,3 +14,4 @@ RSpec/ContextWording: - unless - for - which + - to diff --git a/Library/Homebrew/test/api/internal_tap_json/formula_spec.rb b/Library/Homebrew/test/api/internal_tap_json/formula_spec.rb index 550036d6e08f49..1426677483c95b 100644 --- a/Library/Homebrew/test/api/internal_tap_json/formula_spec.rb +++ b/Library/Homebrew/test/api/internal_tap_json/formula_spec.rb @@ -17,7 +17,7 @@ end it "creates the expected hash" do - api_hash = CoreTap.instance.to_api_hash + api_hash = CoreTap.instance.to_internal_api_hash api_hash["tap_git_head"] = tap_git_head # tricky to mock expect(JSON.pretty_generate(api_hash)).to eq(internal_tap_json) @@ -33,7 +33,7 @@ .with("internal/v3/homebrew-core.jws.json") .and_return([JSON.parse(internal_tap_json), false]) - # `Tap.reverse_tap_migrations_renames` looks for renames in every + # `Tap.tap_migration_oldnames` looks for renames in every # tap so `CoreCaskTap.tap_migrations` gets called and tries to # fetch stuff from the API. This just avoids errors. allow(Homebrew::API).to receive(:fetch_json_api_file) diff --git a/Library/Homebrew/test/api_spec.rb b/Library/Homebrew/test/api_spec.rb index e8b7fee401b942..585c91f0eecd88 100644 --- a/Library/Homebrew/test/api_spec.rb +++ b/Library/Homebrew/test/api_spec.rb @@ -13,7 +13,7 @@ end def mock_curl_output(stdout: "", success: true) - curl_output = instance_double(SystemCommand::Result, stdout: stdout, success?: success) + curl_output = instance_double(SystemCommand::Result, stdout:, success?: success) allow(Utils::Curl).to receive(:curl_output).and_return curl_output end diff --git a/Library/Homebrew/test/cache_store_spec.rb b/Library/Homebrew/test/cache_store_spec.rb index cc950b83deda0b..ef0cc72bfdc22f 100644 --- a/Library/Homebrew/test/cache_store_spec.rb +++ b/Library/Homebrew/test/cache_store_spec.rb @@ -23,7 +23,7 @@ it "sets the value in the `CacheStoreDatabase`" do allow(File).to receive(:write) - allow(sample_db).to receive_messages(created?: true, db: db) + allow(sample_db).to receive_messages(created?: true, db:) expect(db).to receive(:has_key?).with(:foo).and_return(false) expect(db).not_to have_key(:foo) @@ -37,7 +37,7 @@ it "gets value in the `CacheStoreDatabase` corresponding to the key" do expect(db).to receive(:has_key?).with(:foo).and_return(true) - allow(sample_db).to receive_messages(created?: true, db: db) + allow(sample_db).to receive_messages(created?: true, db:) expect(db).to have_key(:foo) expect(sample_db.get(:foo)).to eq("bar") end @@ -47,7 +47,7 @@ let(:db) { instance_double(Hash, "db", :[] => nil) } before do - allow(sample_db).to receive_messages(created?: false, db: db) + allow(sample_db).to receive_messages(created?: false, db:) end it "does not get value in the `CacheStoreDatabase` corresponding to key" do @@ -66,7 +66,7 @@ let(:db) { instance_double(Hash, "db", :[] => { foo: "bar" }) } before do - allow(sample_db).to receive_messages(created?: true, db: db) + allow(sample_db).to receive_messages(created?: true, db:) end it "deletes value in the `CacheStoreDatabase` corresponding to the key" do @@ -79,7 +79,7 @@ let(:db) { instance_double(Hash, "db", delete: nil) } before do - allow(sample_db).to receive_messages(created?: false, db: db) + allow(sample_db).to receive_messages(created?: false, db:) end it "does not call `db.delete` if `CacheStoreDatabase.created?` is `false`" do diff --git a/Library/Homebrew/test/cask/artifact/app_spec.rb b/Library/Homebrew/test/cask/artifact/app_spec.rb index ccc0e3e1e0fd66..1b967d0886afce 100644 --- a/Library/Homebrew/test/cask/artifact/app_spec.rb +++ b/Library/Homebrew/test/cask/artifact/app_spec.rb @@ -10,8 +10,8 @@ let(:source_path) { cask.staged_path.join("Caffeine.app") } let(:target_path) { cask.config.appdir.join("Caffeine.app") } - let(:install_phase) { app.install_phase(command: command, adopt: adopt, force: force) } - let(:uninstall_phase) { app.uninstall_phase(command: command, force: force) } + let(:install_phase) { app.install_phase(command:, adopt:, force:) } + let(:uninstall_phase) { app.uninstall_phase(command:, force:) } before do InstallHelper.install_without_artifacts(cask) @@ -315,13 +315,13 @@ inode = target_path.stat.ino expect(contents_path).to exist - app.uninstall_phase(command: command, force: force, successor: cask) + app.uninstall_phase(command:, force:, successor: cask) expect(target_path).to exist expect(target_path.children).to be_empty expect(contents_path).not_to exist - app.install_phase(command: command, adopt: adopt, force: force, predecessor: cask) + app.install_phase(command:, adopt:, force:, predecessor: cask) expect(target_path).to exist expect(target_path.stat.ino).to eq(inode) @@ -335,10 +335,10 @@ expect(File).to receive(:write).with(target_path / ".homebrew-write-test", instance_of(String)).and_raise(Errno::EACCES) - app.uninstall_phase(command: command, force: force, successor: cask) + app.uninstall_phase(command:, force:, successor: cask) expect(target_path).not_to exist - app.install_phase(command: command, adopt: adopt, force: force, predecessor: cask) + app.install_phase(command:, adopt:, force:, predecessor: cask) expect(target_contents_path).to exist end end @@ -360,12 +360,12 @@ .and_call_original expect(FileUtils).not_to receive(:move).with(source_contents_path, an_instance_of(Pathname)) - app.uninstall_phase(command: command, force: force, successor: cask) + app.uninstall_phase(command:, force:, successor: cask) expect(target_contents_path).not_to exist expect(target_path).to exist expect(source_contents_path).to exist - app.install_phase(command: command, adopt: adopt, force: force, predecessor: cask) + app.install_phase(command:, adopt:, force:, predecessor: cask) expect(target_contents_path).to exist end @@ -382,10 +382,10 @@ .and_raise(ErrorDuringExecution.new([], status: 1, output: [[:stderr, "touch: #{target_path}/.homebrew-write-test: Operation not permitted\n"]], secrets: [])) - app.uninstall_phase(command: command, force: force, successor: cask) + app.uninstall_phase(command:, force:, successor: cask) expect(target_path).not_to exist - app.install_phase(command: command, adopt: adopt, force: force, predecessor: cask) + app.install_phase(command:, adopt:, force:, predecessor: cask) expect(target_contents_path).to exist end end diff --git a/Library/Homebrew/test/cask/artifact/installer_spec.rb b/Library/Homebrew/test/cask/artifact/installer_spec.rb index 8730c5334bde36..95f30f748f430f 100644 --- a/Library/Homebrew/test/cask/artifact/installer_spec.rb +++ b/Library/Homebrew/test/cask/artifact/installer_spec.rb @@ -4,7 +4,7 @@ subject(:installer) { described_class.new(cask, **args) } let(:staged_path) { mktmpdir } - let(:cask) { instance_double(Cask::Cask, staged_path: staged_path) } + let(:cask) { instance_double(Cask::Cask, staged_path:) } let(:command) { SystemCommand } @@ -16,7 +16,7 @@ it "shows a message prompting to run the installer manually" do expect do - installer.install_phase(command: command) + installer.install_phase(command:) end.to output(%r{open #{staged_path}/installer}).to_stdout end end @@ -37,7 +37,7 @@ ), ) - installer.install_phase(command: command) + installer.install_phase(command:) end end end diff --git a/Library/Homebrew/test/cask/audit_spec.rb b/Library/Homebrew/test/cask/audit_spec.rb index c3102466f69fa9..3c0ae7db0b872b 100644 --- a/Library/Homebrew/test/cask/audit_spec.rb +++ b/Library/Homebrew/test/cask/audit_spec.rb @@ -52,13 +52,13 @@ def outcome(audit) let(:token_conflicts) { nil } let(:signing) { nil } let(:audit) do - described_class.new(cask, online: online, - strict: strict, - new_cask: new_cask, - token_conflicts: token_conflicts, - signing: signing, - only: only, - except: except) + described_class.new(cask, online:, + strict:, + new_cask:, + token_conflicts:, + signing:, + only:, + except:) end describe "#new" do @@ -220,11 +220,43 @@ def tmp_cask(name, text) end end - context "when cask token has @" do - let(:cask_token) { "app@stuff" } + context "when cask token is @-versioned with number" do + let(:cask_token) { "app@10" } + + it "does not fail" do + expect(run).to pass + end + end + + context "when cask token is @-versioned with word" do + let(:cask_token) { "app@beta" } + + it "does not fail" do + expect(run).to pass + end + end + + context "when cask token has multiple @" do + let(:cask_token) { "app@stuff@beta" } + + it "fails" do + expect(run).to error_with(/@ unrelated to versioning should be replaced by -at-/) + end + end + + context "when cask token has a hyphen followed by @" do + let(:cask_token) { "app-@beta" } + + it "fails" do + expect(run).to error_with(/should not contain a hyphen followed by @/) + end + end + + context "when cask token has @ followed by a hyphen" do + let(:cask_token) { "app@-beta" } it "fails" do - expect(run).to error_with(/@ should be replaced by -at-/) + expect(run).to error_with(/should not contain @ followed by a hyphen/) end end @@ -248,7 +280,7 @@ def tmp_cask(name, text) let(:cask_token) { "app(stuff)" } it "fails" do - expect(run).to error_with(/alphanumeric characters and hyphens/) + expect(run).to error_with(/alphanumeric characters, hyphens and @/) end end diff --git a/Library/Homebrew/test/cask/cask_loader_spec.rb b/Library/Homebrew/test/cask/cask_loader_spec.rb index 52823dd6434533..e7fcc9696ec78c 100644 --- a/Library/Homebrew/test/cask/cask_loader_spec.rb +++ b/Library/Homebrew/test/cask/cask_loader_spec.rb @@ -72,52 +72,88 @@ ENV["HOMEBREW_NO_INSTALL_FROM_API"] = "1" end - context "when a cask is migrated to the default tap" do + context "when a cask is migrated" do let(:token) { "local-caffeine" } + + let(:core_tap) { CoreTap.instance } + let(:core_cask_tap) { CoreCaskTap.instance } + let(:tap_migrations) do { - token => default_tap.name, + token => new_tap.name, } end - let(:old_tap) { CoreTap.instance } - let(:default_tap) { CoreCaskTap.instance } before do + old_tap.path.mkpath + new_tap.path.mkpath (old_tap.path/"tap_migrations.json").write tap_migrations.to_json end - it "does not warn when loading the short token" do - expect do - described_class.for(token) - end.not_to output.to_stderr - end + context "to a formula in the default tap" do + let(:old_tap) { core_cask_tap } + let(:new_tap) { core_tap } - it "does not warn when loading the full token in the default tap" do - expect do - described_class.for("#{default_tap}/#{token}") - end.not_to output.to_stderr - end + let(:formula_file) { new_tap.formula_dir/"#{token}.rb" } - it "warns when loading the full token in the old tap" do - expect do - described_class.for("#{old_tap}/#{token}") - end.to output(%r{Cask #{old_tap}/#{token} was renamed to #{token}\.}).to_stderr + before do + new_tap.formula_dir.mkpath + FileUtils.touch formula_file + end + + it "warn only once" do + expect do + described_class.for(token) + end.to output( + a_string_including("Warning: Cask #{token} was renamed to #{new_tap}/#{token}.").once, + ).to_stderr + end end - # FIXME - # context "when there is an infinite tap migration loop" do - # before do - # (default_tap.path/"tap_migrations.json").write({ - # token => old_tap.name, - # }.to_json) - # end - # - # it "stops recursing" do - # expect do - # described_class.for("#{default_tap}/#{token}") - # end.not_to output.to_stderr - # end - # end + context "to the default tap" do + let(:old_tap) { core_tap } + let(:new_tap) { core_cask_tap } + + let(:cask_file) { new_tap.cask_dir/"#{token}.rb" } + + before do + new_tap.cask_dir.mkpath + FileUtils.touch cask_file + end + + it "does not warn when loading the short token" do + expect do + described_class.for(token) + end.not_to output.to_stderr + end + + it "does not warn when loading the full token in the default tap" do + expect do + described_class.for("#{new_tap}/#{token}") + end.not_to output.to_stderr + end + + it "warns when loading the full token in the old tap" do + expect do + described_class.for("#{old_tap}/#{token}") + end.to output(%r{Cask #{old_tap}/#{token} was renamed to #{token}\.}).to_stderr + end + + # FIXME + # context "when there is an infinite tap migration loop" do + # before do + # (new_tap.path/"tap_migrations.json").write({ + # token => old_tap.name, + # }.to_json) + # end + # + # it "stops recursing" do + # expect do + # described_class.for("#{new_tap}/#{token}") + # end.not_to output.to_stderr + # end + # end + end end end end diff --git a/Library/Homebrew/test/cask/cask_spec.rb b/Library/Homebrew/test/cask/cask_spec.rb index 4284294a0e7b2a..fea5589a37025c 100644 --- a/Library/Homebrew/test/cask/cask_spec.rb +++ b/Library/Homebrew/test/cask/cask_spec.rb @@ -107,7 +107,7 @@ expectations.each do |installed_version, expected_output| context "when version #{installed_version.inspect} is installed and the tap version is #{tap_version}" do it { - allow(cask).to receive_messages(installed_version: installed_version, + allow(cask).to receive_messages(installed_version:, version: Cask::DSL::Version.new(tap_version)) expect(cask).to receive(:outdated_version).and_call_original expect(subject).to eq expected_output @@ -136,10 +136,10 @@ context "when versions #{installed_version} are installed and the " \ "tap version is #{tap_version}, #{"not " unless greedy}greedy " \ "and sha is #{"not " unless outdated_sha}outdated" do - subject { cask.outdated_version(greedy: greedy) } + subject { cask.outdated_version(greedy:) } it { - allow(cask).to receive_messages(installed_version: installed_version, + allow(cask).to receive_messages(installed_version:, version: Cask::DSL::Version.new(tap_version), outdated_download_sha?: outdated_sha) expect(cask).to receive(:outdated_version).and_call_original diff --git a/Library/Homebrew/test/cask/dsl_spec.rb b/Library/Homebrew/test/cask/dsl_spec.rb index b7594c609af415..3cc70983d187f7 100644 --- a/Library/Homebrew/test/cask/dsl_spec.rb +++ b/Library/Homebrew/test/cask/dsl_spec.rb @@ -525,7 +525,7 @@ def caveats appdir: "/Applications/", }) - cask = Cask::Cask.new("appdir-trailing-slash", config: config) do + cask = Cask::Cask.new("appdir-trailing-slash", config:) do binary "#{appdir}/some/path" end diff --git a/Library/Homebrew/test/cask/list_spec.rb b/Library/Homebrew/test/cask/list_spec.rb index ff96c2cc2661c1..6fea3f479806db 100644 --- a/Library/Homebrew/test/cask/list_spec.rb +++ b/Library/Homebrew/test/cask/list_spec.rb @@ -97,7 +97,7 @@ let(:casks) { [caffeine, transmission] } it "lists the installed files for those Casks" do - casks.each(&InstallHelper.method(:install_without_artifacts_with_caskfile)) + casks.each { InstallHelper.install_without_artifacts_with_caskfile(_1) } transmission.artifacts.select { |a| a.is_a?(Cask::Artifact::App) }.each do |artifact| artifact.install_phase(command: NeverSudoSystemCommand, force: false) diff --git a/Library/Homebrew/test/cask/uninstall_spec.rb b/Library/Homebrew/test/cask/uninstall_spec.rb index e281a6a1628f3c..6fdf8b589871c8 100644 --- a/Library/Homebrew/test/cask/uninstall_spec.rb +++ b/Library/Homebrew/test/cask/uninstall_spec.rb @@ -124,7 +124,7 @@ before do app.tap(&:mkpath) .join("Contents").tap(&:mkpath) - .join("Info.plist").tap(&FileUtils.method(:touch)) + .join("Info.plist").tap { FileUtils.touch(_1) } caskroom_path.mkpath diff --git a/Library/Homebrew/test/cask/upgrade_spec.rb b/Library/Homebrew/test/cask/upgrade_spec.rb index 940f547f5d7d15..3b5455fcc44854 100644 --- a/Library/Homebrew/test/cask/upgrade_spec.rb +++ b/Library/Homebrew/test/cask/upgrade_spec.rb @@ -55,7 +55,7 @@ expect(renamed_app_new_path).not_to be_a_directory expect(renamed_app.installed_version).to eq "1.0.0" - described_class.upgrade_casks(dry_run: true, args: args) + described_class.upgrade_casks(dry_run: true, args:) expect(local_caffeine).to be_installed expect(local_caffeine_path).to be_a_directory @@ -82,7 +82,7 @@ expect(local_transmission_path).to be_a_directory expect(local_transmission.installed_version).to eq "2.60" - described_class.upgrade_casks(local_caffeine, dry_run: true, args: args) + described_class.upgrade_casks(local_caffeine, dry_run: true, args:) expect(local_caffeine).to be_installed expect(local_caffeine_path).to be_a_directory @@ -109,7 +109,7 @@ expect(renamed_app_new_path).not_to be_a_directory expect(renamed_app.installed_version).to eq "1.0.0" - described_class.upgrade_casks(local_caffeine, auto_updates, dry_run: true, args: args) + described_class.upgrade_casks(local_caffeine, auto_updates, dry_run: true, args:) expect(local_caffeine).to be_installed expect(local_caffeine_path).to be_a_directory @@ -152,7 +152,7 @@ version_latest.download_sha_path.write("fake download sha") expect(version_latest.outdated_download_sha?).to be(true) - described_class.upgrade_casks(greedy: true, dry_run: true, args: args) + described_class.upgrade_casks(greedy: true, dry_run: true, args:) expect(local_caffeine).to be_installed expect(local_caffeine_path).to be_a_directory @@ -182,7 +182,7 @@ expect(auto_updates_path).to be_a_directory expect(auto_updates.installed_version).to eq "2.57" - described_class.upgrade_casks(auto_updates, dry_run: true, greedy: true, args: args) + described_class.upgrade_casks(auto_updates, dry_run: true, greedy: true, args:) expect(auto_updates).to be_installed expect(auto_updates_path).to be_a_directory @@ -199,7 +199,7 @@ version_latest.download_sha_path.write("fake download sha") expect(version_latest.outdated_download_sha?).to be(true) - described_class.upgrade_casks(version_latest, dry_run: true, greedy: true, args: args) + described_class.upgrade_casks(version_latest, dry_run: true, greedy: true, args:) expect(version_latest).to be_installed expect(version_latest_paths).to all be_a_directory @@ -230,7 +230,7 @@ expect(will_fail_if_upgraded.installed_version).to eq "1.2.2" expect do - described_class.upgrade_casks(will_fail_if_upgraded, args: args) + described_class.upgrade_casks(will_fail_if_upgraded, args:) end.to raise_error(Cask::CaskError).and output(output_reverted).to_stderr expect(will_fail_if_upgraded).to be_installed @@ -248,7 +248,7 @@ expect(bad_checksum.installed_version).to eq "1.2.2" expect do - described_class.upgrade_casks(bad_checksum, args: args) + described_class.upgrade_casks(bad_checksum, args:) end.to raise_error(ChecksumMismatchError).and(not_to_output(output_reverted).to_stderr) expect(bad_checksum).to be_installed @@ -287,7 +287,7 @@ expect(bad_checksum_2.installed_version).to eq "1.2.2" expect do - described_class.upgrade_casks(args: args) + described_class.upgrade_casks(args:) end.to raise_error(Cask::MultipleCaskErrors) expect(bad_checksum).to be_installed diff --git a/Library/Homebrew/test/cask/utils_spec.rb b/Library/Homebrew/test/cask/utils_spec.rb index 394879957d512d..3ee2d33ca3ea37 100644 --- a/Library/Homebrew/test/cask/utils_spec.rb +++ b/Library/Homebrew/test/cask/utils_spec.rb @@ -9,9 +9,9 @@ describe "::gain_permissions_mkpath" do it "creates a directory" do expect(path).not_to exist - described_class.gain_permissions_mkpath path, command: command + described_class.gain_permissions_mkpath(path, command:) expect(path).to be_a_directory - described_class.gain_permissions_mkpath path, command: command + described_class.gain_permissions_mkpath(path, command:) expect(path).to be_a_directory end @@ -27,9 +27,9 @@ end expect(path).not_to exist - described_class.gain_permissions_mkpath path, command: command + described_class.gain_permissions_mkpath(path, command:) expect(path).to be_a_directory - described_class.gain_permissions_mkpath path, command: command + described_class.gain_permissions_mkpath(path, command:) expect(path).to be_a_directory expect(dir).not_to be_writable @@ -48,12 +48,12 @@ expect(link).to be_a_symlink expect(link.realpath).to eq path - described_class.gain_permissions_remove link, command: command + described_class.gain_permissions_remove(link, command:) expect(path).to be_a_file expect(link).not_to exist - described_class.gain_permissions_remove path, command: command + described_class.gain_permissions_remove(path, command:) expect(path).not_to exist end @@ -66,12 +66,12 @@ expect(link).to be_a_symlink expect(link.realpath).to eq path - described_class.gain_permissions_remove link, command: command + described_class.gain_permissions_remove(link, command:) expect(path).to be_a_directory expect(link).not_to exist - described_class.gain_permissions_remove path, command: command + described_class.gain_permissions_remove(path, command:) expect(path).not_to exist end diff --git a/Library/Homebrew/test/cleaner_spec.rb b/Library/Homebrew/test/cleaner_spec.rb index 0c02b81256d963..f5f51a29418b01 100644 --- a/Library/Homebrew/test/cleaner_spec.rb +++ b/Library/Homebrew/test/cleaner_spec.rb @@ -155,6 +155,52 @@ expect(arch_file).not_to exist expect(name_file).to exist end + + it "removes '*.dist-info/direct_url.json' files" do + dir = f.lib/"python3.12/site-packages/test.dist-info" + file = dir/"direct_url.json" + unrelated_file = dir/"METADATA" + unrelated_dir_file = f.lib/"direct_url.json" + + dir.mkpath + touch file + touch unrelated_file + touch unrelated_dir_file + + cleaner.clean + + expect(file).not_to exist + expect(unrelated_file).to exist + expect(unrelated_dir_file).to exist + end + + it "removes '*.dist-info/RECORD' files" do + dir = f.lib/"python3.12/site-packages/test.dist-info" + file = dir/"RECORD" + unrelated_file = dir/"METADATA" + unrelated_dir_file = f.lib/"RECORD" + + dir.mkpath + touch file + touch unrelated_file + touch unrelated_dir_file + + cleaner.clean + + expect(file).not_to exist + expect(unrelated_file).to exist + expect(unrelated_dir_file).to exist + end + + it "modifies '*.dist-info/INSTALLER' files" do + file = f.lib/"python3.12/site-packages/test.dist-info/INSTALLER" + file.dirname.mkpath + file.write "pip\n" + + cleaner.clean + + expect(file.read).to eq "brew\n" + end end describe "::skip_clean" do diff --git a/Library/Homebrew/test/cleanup_spec.rb b/Library/Homebrew/test/cleanup_spec.rb index b4a09a8721d1c7..b166364594fb1f 100644 --- a/Library/Homebrew/test/cleanup_spec.rb +++ b/Library/Homebrew/test/cleanup_spec.rb @@ -95,6 +95,76 @@ end end + describe "::prune_prefix_symlinks_and_directories" do + let(:lib) { HOMEBREW_PREFIX/"lib" } + + before do + lib.mkpath + end + + it "keeps required empty directories" do + cleanup.prune_prefix_symlinks_and_directories + expect(lib).to exist + expect(lib.children).to be_empty + end + + it "removes broken symlinks" do + FileUtils.ln_s lib/"foo", lib/"bar" + FileUtils.touch lib/"baz" + + cleanup.prune_prefix_symlinks_and_directories + expect(lib).to exist + expect(lib.children).to eq([lib/"baz"]) + end + + it "removes empty directories" do + dir = lib/"test" + dir.mkpath + file = lib/"keep/file" + file.dirname.mkpath + FileUtils.touch file + + cleanup.prune_prefix_symlinks_and_directories + expect(dir).not_to exist + expect(file).to exist + end + + context "when nested directories exist with only broken symlinks" do + let(:dir) { HOMEBREW_PREFIX/"lib/foo" } + let(:child_dir) { dir/"bar" } + let(:grandchild_dir) { child_dir/"baz" } + let(:broken_link) { dir/"broken" } + let(:link_to_broken_link) { child_dir/"another-broken" } + + before do + grandchild_dir.mkpath + FileUtils.ln_s dir/"missing", broken_link + FileUtils.ln_s broken_link, link_to_broken_link + end + + it "removes broken symlinks and resulting empty directories" do + cleanup.prune_prefix_symlinks_and_directories + expect(dir).not_to exist + end + + it "doesn't remove anything and only prints removal steps if `dry_run` is true" do + expect do + described_class.new(dry_run: true).prune_prefix_symlinks_and_directories + end.to output(<<~EOS).to_stdout + Would remove (broken link): #{link_to_broken_link} + Would remove (broken link): #{broken_link} + Would remove (empty directory): #{grandchild_dir} + Would remove (empty directory): #{child_dir} + Would remove (empty directory): #{dir} + EOS + + expect(broken_link).to be_a_symlink + expect(link_to_broken_link).to be_a_symlink + expect(grandchild_dir).to exist + end + end + end + specify "::cleanup_formula" do f1 = Class.new(Testball) do version "1.0" diff --git a/Library/Homebrew/test/cli/named_args_spec.rb b/Library/Homebrew/test/cli/named_args_spec.rb index b1f5c115cce106..702214109918f6 100644 --- a/Library/Homebrew/test/cli/named_args_spec.rb +++ b/Library/Homebrew/test/cli/named_args_spec.rb @@ -312,7 +312,7 @@ def setup_unredable_cask(name) it "raises an error for invalid tap" do taps = described_class.new("homebrew/foo", "barbaz") - expect { taps.to_taps }.to raise_error(RuntimeError, /Invalid tap name/) + expect { taps.to_taps }.to raise_error(ArgumentError, /Invalid tap name/) end end @@ -333,7 +333,7 @@ def setup_unredable_cask(name) it "raises an error for invalid tap" do taps = described_class.new("homebrew/foo", "barbaz") - expect { taps.to_installed_taps }.to raise_error(RuntimeError, /Invalid tap name/) + expect { taps.to_installed_taps }.to raise_error(ArgumentError, /Invalid tap name/) end end end diff --git a/Library/Homebrew/test/cmd/log_spec.rb b/Library/Homebrew/test/cmd/log_spec.rb index 9ac40c7856b71b..c89c86d0d05c30 100644 --- a/Library/Homebrew/test/cmd/log_spec.rb +++ b/Library/Homebrew/test/cmd/log_spec.rb @@ -8,7 +8,7 @@ it "shows the Git log for a given Formula", :integration_test do setup_test_formula "testball" - core_tap = CoreTap.new + core_tap = CoreTap.instance core_tap.path.cd do system "git", "init" system "git", "add", "--all" diff --git a/Library/Homebrew/test/cmd/readall_spec.rb b/Library/Homebrew/test/cmd/readall_spec.rb index 3714d79f26f57b..a16c3669c45f9d 100644 --- a/Library/Homebrew/test/cmd/readall_spec.rb +++ b/Library/Homebrew/test/cmd/readall_spec.rb @@ -8,7 +8,7 @@ it "imports all Formulae for a given Tap", :integration_test do formula_file = setup_test_formula "testball" - alias_file = CoreTap.new.alias_dir/"foobar" + alias_file = CoreTap.instance.alias_dir/"foobar" alias_file.parent.mkpath FileUtils.ln_s formula_file, alias_file diff --git a/Library/Homebrew/test/cmd/update-report_spec.rb b/Library/Homebrew/test/cmd/update-report_spec.rb index bb8b7cc28bfec1..6d0daef15fec1b 100644 --- a/Library/Homebrew/test/cmd/update-report_spec.rb +++ b/Library/Homebrew/test/cmd/update-report_spec.rb @@ -9,7 +9,7 @@ it_behaves_like "parseable arguments" describe Reporter do - let(:tap) { CoreTap.new } + let(:tap) { CoreTap.instance } let(:reporter_class) do Class.new(described_class) do def initialize(tap) @@ -87,7 +87,7 @@ def perform_update(fixture_name = "") end context "when updating a Tap other than the core Tap" do - let(:tap) { Tap.new("foo", "bar") } + let(:tap) { Tap.fetch("foo", "bar") } before do (tap.path/"Formula").mkpath diff --git a/Library/Homebrew/test/dependency_expansion_spec.rb b/Library/Homebrew/test/dependency_expansion_spec.rb index c02332a1d90143..7876ecc50ec8da 100644 --- a/Library/Homebrew/test/dependency_expansion_spec.rb +++ b/Library/Homebrew/test/dependency_expansion_spec.rb @@ -6,7 +6,7 @@ def build_dep(name, tags = [], deps = []) dep = described_class.new(name.to_s, tags) allow(dep).to receive(:to_formula).and_return \ - instance_double(Formula, deps: deps, name: name, full_name: name) + instance_double(Formula, deps:, name:, full_name: name) dep end @@ -15,7 +15,7 @@ def build_dep(name, tags = [], deps = []) let(:baz) { build_dep(:baz) } let(:qux) { build_dep(:qux) } let(:deps) { [foo, bar, baz, qux] } - let(:formula) { instance_double(Formula, deps: deps, name: "f") } + let(:formula) { instance_double(Formula, deps:, name: "f") } describe "::expand" do it "yields dependent and dependency pairs" do @@ -52,13 +52,13 @@ def build_dep(name, tags = [], deps = []) it "skips optionals by default" do deps = [build_dep(:foo, [:optional]), bar, baz, qux] - f = instance_double(Formula, deps: deps, build: instance_double(BuildOptions, with?: false), name: "f") + f = instance_double(Formula, deps:, build: instance_double(BuildOptions, with?: false), name: "f") expect(described_class.expand(f)).to eq([bar, baz, qux]) end it "keeps recommended dependencies by default" do deps = [build_dep(:foo, [:recommended]), bar, baz, qux] - f = instance_double(Formula, deps: deps, build: instance_double(BuildOptions, with?: true), name: "f") + f = instance_double(Formula, deps:, build: instance_double(BuildOptions, with?: true), name: "f") expect(described_class.expand(f)).to eq(deps) end diff --git a/Library/Homebrew/test/dependency_spec.rb b/Library/Homebrew/test/dependency_spec.rb index cd84d51edb0023..7472335310709c 100644 --- a/Library/Homebrew/test/dependency_spec.rb +++ b/Library/Homebrew/test/dependency_spec.rb @@ -99,7 +99,7 @@ describe "#tap" do it "returns a tap passed a fully-qualified name" do dependency = described_class.new("foo/bar/dog") - expect(dependency.tap).to eq(Tap.new("foo", "bar")) + expect(dependency.tap).to eq(Tap.fetch("foo", "bar")) end it "returns no tap passed a simple name" do diff --git a/Library/Homebrew/test/dev-cmd/audit_spec.rb b/Library/Homebrew/test/dev-cmd/audit_spec.rb index 4b85beadbe0052..2c6c24b32bc48c 100644 --- a/Library/Homebrew/test/dev-cmd/audit_spec.rb +++ b/Library/Homebrew/test/dev-cmd/audit_spec.rb @@ -144,7 +144,7 @@ class Foo < Formula end it "detects no license info" do - fa = formula_auditor "foo", <<~RUBY, spdx_license_data: spdx_license_data, new_formula: true, core_tap: true + fa = formula_auditor "foo", <<~RUBY, spdx_license_data:, new_formula: true, core_tap: true class Foo < Formula url "https://brew.sh/foo-1.0.tgz" end @@ -155,7 +155,7 @@ class Foo < Formula end it "detects if license is not a standard spdx-id" do - fa = formula_auditor "foo", <<~RUBY, spdx_license_data: spdx_license_data, new_formula: true + fa = formula_auditor "foo", <<~RUBY, spdx_license_data:, new_formula: true class Foo < Formula url "https://brew.sh/foo-1.0.tgz" license "zzz" @@ -170,7 +170,7 @@ class Foo < Formula end it "detects if license is a deprecated spdx-id" do - fa = formula_auditor "foo", <<~RUBY, spdx_license_data: spdx_license_data, new_formula: true, strict: true + fa = formula_auditor "foo", <<~RUBY, spdx_license_data:, new_formula: true, strict: true class Foo < Formula url "https://brew.sh/foo-1.0.tgz" license "#{deprecated_spdx_id}" @@ -186,7 +186,7 @@ class Foo < Formula end it "detects if license with AND contains a non-standard spdx-id" do - fa = formula_auditor "foo", <<~RUBY, spdx_license_data: spdx_license_data, new_formula: true + fa = formula_auditor "foo", <<~RUBY, spdx_license_data:, new_formula: true class Foo < Formula url "https://brew.sh/foo-1.0.tgz" license #{license_all_custom_id} @@ -201,7 +201,7 @@ class Foo < Formula end it "detects if license array contains a non-standard spdx-id" do - fa = formula_auditor "foo", <<~RUBY, spdx_license_data: spdx_license_data, new_formula: true + fa = formula_auditor "foo", <<~RUBY, spdx_license_data:, new_formula: true class Foo < Formula url "https://brew.sh/foo-1.0.tgz" license #{license_any_nonstandard} @@ -216,7 +216,7 @@ class Foo < Formula end it "detects if license array contains a deprecated spdx-id" do - fa = formula_auditor "foo", <<~RUBY, spdx_license_data: spdx_license_data, new_formula: true, strict: true + fa = formula_auditor "foo", <<~RUBY, spdx_license_data:, new_formula: true, strict: true class Foo < Formula url "https://brew.sh/foo-1.0.tgz" license #{license_any_deprecated} @@ -232,7 +232,7 @@ class Foo < Formula end it "verifies that a license info is a standard spdx id" do - fa = formula_auditor "foo", <<~RUBY, spdx_license_data: spdx_license_data, new_formula: true + fa = formula_auditor "foo", <<~RUBY, spdx_license_data:, new_formula: true class Foo < Formula url "https://brew.sh/foo-1.0.tgz" license "0BSD" @@ -244,7 +244,7 @@ class Foo < Formula end it "verifies that a license info with plus is a standard spdx id" do - fa = formula_auditor "foo", <<~RUBY, spdx_license_data: spdx_license_data, new_formula: true + fa = formula_auditor "foo", <<~RUBY, spdx_license_data:, new_formula: true class Foo < Formula url "https://brew.sh/foo-1.0.tgz" license "0BSD+" @@ -256,7 +256,7 @@ class Foo < Formula end it "allows :public_domain license" do - fa = formula_auditor "foo", <<~RUBY, spdx_license_data: spdx_license_data, new_formula: true + fa = formula_auditor "foo", <<~RUBY, spdx_license_data:, new_formula: true class Foo < Formula url "https://brew.sh/foo-1.0.tgz" license :public_domain @@ -268,7 +268,7 @@ class Foo < Formula end it "verifies that a license info with multiple licenses are standard spdx ids" do - fa = formula_auditor "foo", <<~RUBY, spdx_license_data: spdx_license_data, new_formula: true + fa = formula_auditor "foo", <<~RUBY, spdx_license_data:, new_formula: true class Foo < Formula url "https://brew.sh/foo-1.0.tgz" license any_of: ["0BSD", "MIT"] @@ -286,15 +286,15 @@ class Foo < Formula license "Apache-2.0" => { with: "LLVM-exception" } end RUBY - fa = formula_auditor "foo", formula_text, new_formula: true, - spdx_license_data: spdx_license_data, spdx_exception_data: spdx_exception_data + fa = formula_auditor("foo", formula_text, new_formula: true, + spdx_license_data:, spdx_exception_data:) fa.audit_license expect(fa.problems).to be_empty end it "verifies that a license array contains only standard spdx id" do - fa = formula_auditor "foo", <<~RUBY, spdx_license_data: spdx_license_data, new_formula: true + fa = formula_auditor "foo", <<~RUBY, spdx_license_data:, new_formula: true class Foo < Formula url "https://brew.sh/foo-1.0.tgz" license #{license_any} @@ -306,7 +306,7 @@ class Foo < Formula end it "verifies that a license array contains only standard spdx id with plus" do - fa = formula_auditor "foo", <<~RUBY, spdx_license_data: spdx_license_data, new_formula: true + fa = formula_auditor "foo", <<~RUBY, spdx_license_data:, new_formula: true class Foo < Formula url "https://brew.sh/foo-1.0.tgz" license #{license_any_with_plus} @@ -318,7 +318,7 @@ class Foo < Formula end it "verifies that a license array with AND contains only standard spdx ids" do - fa = formula_auditor "foo", <<~RUBY, spdx_license_data: spdx_license_data, new_formula: true + fa = formula_auditor "foo", <<~RUBY, spdx_license_data:, new_formula: true class Foo < Formula url "https://brew.sh/foo-1.0.tgz" license #{license_nested_conditions} @@ -338,7 +338,7 @@ class Cask < Formula license "GPL-3.0" end RUBY - fa = formula_auditor "cask", formula_text, spdx_license_data: spdx_license_data, + fa = formula_auditor "cask", formula_text, spdx_license_data:, online: true, core_tap: true, new_formula: true fa.audit_license @@ -354,7 +354,7 @@ class Cask < Formula license all_of: ["GPL-3.0-or-later", "MIT"] end RUBY - fa = formula_auditor "cask", formula_text, spdx_license_data: spdx_license_data, + fa = formula_auditor "cask", formula_text, spdx_license_data:, online: true, core_tap: true, new_formula: true fa.audit_license @@ -370,8 +370,8 @@ class Cask < Formula license "GPL-3.0-or-later" => { with: "LLVM-exception" } end RUBY - fa = formula_auditor "cask", formula_text, online: true, core_tap: true, new_formula: true, - spdx_license_data: spdx_license_data, spdx_exception_data: spdx_exception_data + fa = formula_auditor("cask", formula_text, online: true, core_tap: true, new_formula: true, + spdx_license_data:, spdx_exception_data:) fa.audit_license expect(fa.problems).to be_empty @@ -385,8 +385,8 @@ class Cask < Formula license "GPL-3.0-or-later" => { with: "zzz" } end RUBY - fa = formula_auditor "cask", formula_text, core_tap: true, new_formula: true, - spdx_license_data: spdx_license_data, spdx_exception_data: spdx_exception_data + fa = formula_auditor("cask", formula_text, core_tap: true, new_formula: true, + spdx_license_data:, spdx_exception_data:) fa.audit_license expect(fa.problems.first[:message]).to match <<~EOS @@ -404,8 +404,8 @@ class Cask < Formula license "GPL-3.0-or-later" => { with: "#{deprecated_spdx_exception}" } end RUBY - fa = formula_auditor "cask", formula_text, core_tap: true, new_formula: true, - spdx_license_data: spdx_license_data, spdx_exception_data: spdx_exception_data + fa = formula_auditor("cask", formula_text, core_tap: true, new_formula: true, + spdx_license_data:, spdx_exception_data:) fa.audit_license expect(fa.problems.first[:message]).to match <<~EOS @@ -417,7 +417,7 @@ class Cask < Formula it "checks online and verifies that a standard license id is in the same exempted license group " \ "as what is indicated on its GitHub repo", :needs_network do - fa = formula_auditor "cask", <<~RUBY, spdx_license_data: spdx_license_data, online: true, new_formula: true + fa = formula_auditor "cask", <<~RUBY, spdx_license_data:, online: true, new_formula: true class Cask < Formula url "https://github.com/cask/cask/archive/v0.8.4.tar.gz" head "https://github.com/cask/cask.git" @@ -431,7 +431,7 @@ class Cask < Formula it "checks online and verifies that a standard license array is in the same exempted license group " \ "as what is indicated on its GitHub repo", :needs_network do - fa = formula_auditor "cask", <<~RUBY, spdx_license_data: spdx_license_data, online: true, new_formula: true + fa = formula_auditor "cask", <<~RUBY, spdx_license_data:, online: true, new_formula: true class Cask < Formula url "https://github.com/cask/cask/archive/v0.8.4.tar.gz" head "https://github.com/cask/cask.git" @@ -452,7 +452,7 @@ class Cask < Formula license "0BSD" end RUBY - fa = formula_auditor "cask", formula_text, spdx_license_data: spdx_license_data, + fa = formula_auditor "cask", formula_text, spdx_license_data:, online: true, core_tap: true, new_formula: true fa.audit_license @@ -469,7 +469,7 @@ class Cask < Formula license "0BSD" end RUBY - fa = formula_auditor "cask", formula_text, spdx_license_data: spdx_license_data, + fa = formula_auditor "cask", formula_text, spdx_license_data:, online: true, core_tap: true, new_formula: true, tap_audit_exceptions: { permitted_formula_license_mismatches: ["cask"] } @@ -486,7 +486,7 @@ class Cask < Formula license #{license_any_mismatch} end RUBY - fa = formula_auditor "cask", formula_text, spdx_license_data: spdx_license_data, + fa = formula_auditor "cask", formula_text, spdx_license_data:, online: true, core_tap: true, new_formula: true fa.audit_license @@ -503,7 +503,7 @@ class Cask < Formula license #{license_any} end RUBY - fa = formula_auditor "cask", formula_text, spdx_license_data: spdx_license_data, + fa = formula_auditor "cask", formula_text, spdx_license_data:, online: true, core_tap: true, new_formula: true fa.audit_license diff --git a/Library/Homebrew/test/dev-cmd/bottle_spec.rb b/Library/Homebrew/test/dev-cmd/bottle_spec.rb index 7fa0034952a7c3..85fe9e93ff23b3 100644 --- a/Library/Homebrew/test/dev-cmd/bottle_spec.rb +++ b/Library/Homebrew/test/dev-cmd/bottle_spec.rb @@ -53,7 +53,7 @@ def stub_hash(parameters) end describe "--merge", :integration_test do - let(:core_tap) { CoreTap.new } + let(:core_tap) { CoreTap.instance } let(:tarball) do if OS.linux? TEST_FIXTURE_DIR/"tarballs/testball-0.1-linux.tbz" diff --git a/Library/Homebrew/test/dev-cmd/bump_spec.rb b/Library/Homebrew/test/dev-cmd/bump_spec.rb index f576b23efb7e93..11b422088a2d2d 100644 --- a/Library/Homebrew/test/dev-cmd/bump_spec.rb +++ b/Library/Homebrew/test/dev-cmd/bump_spec.rb @@ -20,4 +20,11 @@ .and be_a_success end end + + it "gives an error for `--tap` with official taps", :integration_test do + expect { brew "bump", "--tap", "Homebrew/core" } + .to output(/Invalid usage/).to_stderr + .and not_to_output.to_stdout + .and be_a_failure + end end diff --git a/Library/Homebrew/test/dev-cmd/create_spec.rb b/Library/Homebrew/test/dev-cmd/create_spec.rb index 380c569fe633dc..fefc85dab283f7 100644 --- a/Library/Homebrew/test/dev-cmd/create_spec.rb +++ b/Library/Homebrew/test/dev-cmd/create_spec.rb @@ -4,7 +4,7 @@ RSpec.describe "brew create" do let(:url) { "file://#{TEST_FIXTURE_DIR}/tarballs/testball-0.1.tbz" } - let(:formula_file) { CoreTap.new.new_formula_path("testball") } + let(:formula_file) { CoreTap.instance.new_formula_path("testball") } it_behaves_like "parseable arguments" diff --git a/Library/Homebrew/test/dev-cmd/extract_spec.rb b/Library/Homebrew/test/dev-cmd/extract_spec.rb index 1a8a1a6e22a1d5..9f1ec85e49c224 100644 --- a/Library/Homebrew/test/dev-cmd/extract_spec.rb +++ b/Library/Homebrew/test/dev-cmd/extract_spec.rb @@ -10,7 +10,7 @@ path = Tap::TAP_DIRECTORY/"homebrew/homebrew-foo" (path/"Formula").mkpath target = Tap.from_path(path) - core_tap = CoreTap.new + core_tap = CoreTap.instance core_tap.path.cd do system "git", "init" # Start with deprecated bottle syntax @@ -30,7 +30,7 @@ system "git", "add", "--all" system "git", "commit", "-m", "testball 0.2" end - { name: target.name, path: path } + { name: target.name, path: } end it "retrieves the most recent version of formula", :integration_test do diff --git a/Library/Homebrew/test/dev-cmd/pr-pull_spec.rb b/Library/Homebrew/test/dev-cmd/pr-pull_spec.rb index 72550c42540c43..19ff337e3f46a9 100644 --- a/Library/Homebrew/test/dev-cmd/pr-pull_spec.rb +++ b/Library/Homebrew/test/dev-cmd/pr-pull_spec.rb @@ -96,7 +96,7 @@ class Foo < Formula safe_system Utils::Git.git, "commit", formula_file, "-m", "revision" File.write(formula_file, formula_version) safe_system Utils::Git.git, "commit", formula_file, "-m", "version", "--author=#{secondary_author}" - described_class.autosquash!(original_hash, tap: tap) + described_class.autosquash!(original_hash, tap:) expect(tap.git_repo.commit_message).to include("foo 2.0") expect(tap.git_repo.commit_message).to include("Co-authored-by: #{secondary_author}") end @@ -111,7 +111,7 @@ class Foo < Formula safe_system Utils::Git.git, "commit", cask_file, "-m", "rebuild" File.write(cask_file, cask_version) safe_system Utils::Git.git, "commit", cask_file, "-m", "version", "--author=#{secondary_author}" - described_class.autosquash!(original_hash, tap: tap) + described_class.autosquash!(original_hash, tap:) git_repo = GitRepository.new(path) expect(git_repo.commit_message).to include("food 2.0") expect(git_repo.commit_message).to include("Co-authored-by: #{secondary_author}") diff --git a/Library/Homebrew/test/download_strategies/curl_spec.rb b/Library/Homebrew/test/download_strategies/curl_spec.rb index 08007ef84b3b07..a71caf5ef1cf78 100644 --- a/Library/Homebrew/test/download_strategies/curl_spec.rb +++ b/Library/Homebrew/test/download_strategies/curl_spec.rb @@ -19,7 +19,7 @@ before do allow(strategy).to receive(:curl_headers).with(any_args) - .and_return({ responses: [{ headers: headers }] }) + .and_return({ responses: [{ headers: }] }) end it "parses the opts and sets the corresponding args" do diff --git a/Library/Homebrew/test/error_during_execution_spec.rb b/Library/Homebrew/test/error_during_execution_spec.rb index 5407bce8e48bbb..39caf3313ea15a 100644 --- a/Library/Homebrew/test/error_during_execution_spec.rb +++ b/Library/Homebrew/test/error_during_execution_spec.rb @@ -1,10 +1,10 @@ # frozen_string_literal: true RSpec.describe ErrorDuringExecution do - subject(:error) { described_class.new(command, status: status, output: output) } + subject(:error) { described_class.new(command, status:, output:) } let(:command) { ["false"] } - let(:status) { instance_double(Process::Status, exitstatus: exitstatus, termsig: nil) } + let(:status) { instance_double(Process::Status, exitstatus:, termsig: nil) } let(:exitstatus) { 1 } let(:output) { nil } @@ -17,13 +17,13 @@ it "fails when only given a status" do expect do - described_class.new(status: status) + described_class.new(status:) end.to raise_error(ArgumentError) end it "does not raise an error when given both a command and a status" do expect do - described_class.new(command, status: status) + described_class.new(command, status:) end.not_to raise_error end end diff --git a/Library/Homebrew/test/exceptions_spec.rb b/Library/Homebrew/test/exceptions_spec.rb index f93a853d8c9cba..72150318238a27 100644 --- a/Library/Homebrew/test/exceptions_spec.rb +++ b/Library/Homebrew/test/exceptions_spec.rb @@ -194,7 +194,7 @@ class Baz < Formula; end end describe ErrorDuringExecution do - subject { described_class.new(["badprg", "arg1", "arg2"], status: status) } + subject { described_class.new(["badprg", "arg1", "arg2"], status:) } let(:status) { instance_double(Process::Status, exitstatus: 17, termsig: nil) } diff --git a/Library/Homebrew/test/formula_installer_spec.rb b/Library/Homebrew/test/formula_installer_spec.rb index 13ba7871e593e0..971463ea6f6791 100644 --- a/Library/Homebrew/test/formula_installer_spec.rb +++ b/Library/Homebrew/test/formula_installer_spec.rb @@ -82,7 +82,7 @@ def temporary_install(formula, **options) ENV["HOMEBREW_DEVELOPER"] = "1" dep_name = "homebrew-test-cyclic" - dep_path = CoreTap.new.new_formula_path(dep_name) + dep_path = CoreTap.instance.new_formula_path(dep_name) dep_path.write <<~RUBY class #{Formulary.class_s(dep_name)} < Formula url "foo" @@ -105,7 +105,7 @@ class #{Formulary.class_s(dep_name)} < Formula formula1_name = "homebrew-test-formula1" formula2_name = "homebrew-test-formula2" - formula1_path = CoreTap.new.new_formula_path(formula1_name) + formula1_path = CoreTap.instance.new_formula_path(formula1_name) formula1_path.write <<~RUBY class #{Formulary.class_s(formula1_name)} < Formula url "foo" @@ -116,7 +116,7 @@ class #{Formulary.class_s(formula1_name)} < Formula Formulary.cache.delete(formula1_path) formula1 = Formulary.factory(formula1_name) - formula2_path = CoreTap.new.new_formula_path(formula2_name) + formula2_path = CoreTap.instance.new_formula_path(formula2_name) formula2_path.write <<~RUBY class #{Formulary.class_s(formula2_name)} < Formula url "foo" @@ -135,7 +135,7 @@ class #{Formulary.class_s(formula2_name)} < Formula it "raises on pinned dependency" do dep_name = "homebrew-test-dependency" - dep_path = CoreTap.new.new_formula_path(dep_name) + dep_path = CoreTap.instance.new_formula_path(dep_name) dep_path.write <<~RUBY class #{Formulary.class_s(dep_name)} < Formula url "foo" diff --git a/Library/Homebrew/test/formula_pin_spec.rb b/Library/Homebrew/test/formula_pin_spec.rb index c17b6f81cef886..900f663896ba22 100644 --- a/Library/Homebrew/test/formula_pin_spec.rb +++ b/Library/Homebrew/test/formula_pin_spec.rb @@ -6,7 +6,7 @@ subject(:formula_pin) { described_class.new(formula) } let(:name) { "double" } - let(:formula) { instance_double(Formula, name: name, rack: HOMEBREW_CELLAR/name) } + let(:formula) { instance_double(Formula, name:, rack: HOMEBREW_CELLAR/name) } before do formula.rack.mkpath diff --git a/Library/Homebrew/test/formula_spec.rb b/Library/Homebrew/test/formula_spec.rb index 9d8f5163f7a67f..73d1584bf90a63 100644 --- a/Library/Homebrew/test/formula_spec.rb +++ b/Library/Homebrew/test/formula_spec.rb @@ -30,7 +30,7 @@ let(:alias_name) { "baz@1" } let(:alias_path) { CoreTap.instance.alias_dir/alias_name } let(:f) { klass.new(name, path, spec) } - let(:f_alias) { klass.new(name, path, spec, alias_path: alias_path) } + let(:f_alias) { klass.new(name, path, spec, alias_path:) } specify "formula instantiation" do expect(f.name).to eq(name) @@ -59,7 +59,7 @@ end context "when in a Tap" do - let(:tap) { Tap.new("foo", "bar") } + let(:tap) { Tap.fetch("foo", "bar") } let(:path) { (tap.path/"Formula/#{name}.rb") } let(:full_name) { "#{tap.user}/#{tap.repo}/#{name}" } let(:full_alias_name) { "#{tap.user}/#{tap.repo}/#{alias_name}" } @@ -204,10 +204,10 @@ end example "installed alias with tap" do - tap = Tap.new("user", "repo") + tap = Tap.fetch("user", "repo") name = "foo" path = tap.path/"Formula/#{name}.rb" - f = formula name, path: path do + f = formula(name, path:) do url "foo-1.0" end @@ -417,7 +417,7 @@ example "alias paths with build options" do alias_path = (CoreTap.instance.alias_dir/"another_name") - f = formula alias_path: alias_path do + f = formula(alias_path:) do url "foo-1.0" end f.build = BuildOptions.new(Options.new, f.options) @@ -430,7 +430,7 @@ alias_path = (CoreTap.instance.alias_dir/"another_name") source_path = CoreTap.instance.new_formula_path("another_other_name") - f = formula alias_path: alias_path do + f = formula(alias_path:) do url "foo-1.0" end f.build = Tab.new(source: { "path" => source_path.to_s }) @@ -443,7 +443,7 @@ alias_path = (CoreTap.instance.alias_dir/"another_name") source_path = (CoreTap.instance.alias_dir/"another_other_name") - f = formula alias_path: alias_path do + f = formula(alias_path:) do url "foo-1.0" end f.build = Tab.new(source: { "path" => source_path.to_s }) @@ -847,7 +847,7 @@ def post_install allow(tap_loader).to receive(:get_formula).and_raise(RuntimeError, "tried resolving tap formula") allow(Formulary).to receive(:loader_for).with("foo/bar/f1", from: nil).and_return(tap_loader) - f2_path = Tap.new("baz", "qux").path/"Formula/f2.rb" + f2_path = Tap.fetch("baz", "qux").path/"Formula/f2.rb" stub_formula_loader(formula("f2", path: f2_path) { url("f2-1.0") }, "baz/qux/f2") f3 = formula "f3" do @@ -859,7 +859,7 @@ def post_install expect(f3.runtime_dependencies.map(&:name)).to eq(["baz/qux/f2"]) - f1_path = Tap.new("foo", "bar").path/"Formula/f1.rb" + f1_path = Tap.fetch("foo", "bar").path/"Formula/f1.rb" stub_formula_loader(formula("f1", path: f1_path) { url("f1-1.0") }, "foo/bar/f1") f3.build = BuildOptions.new(Options.create(["--with-f1"]), f3.options) @@ -956,7 +956,7 @@ def post_install end describe "#to_hash_with_variations", :needs_macos do - let(:formula_path) { CoreTap.new.new_formula_path("foo-variations") } + let(:formula_path) { CoreTap.instance.new_formula_path("foo-variations") } let(:formula_content) do <<~RUBY class FooVariations < Formula @@ -1227,13 +1227,13 @@ def pour_bottle? describe "alias changes" do let(:f) do - formula "formula_name", alias_path: alias_path do + formula("formula_name", alias_path:) do url "foo-1.0" end end let(:new_formula) do - formula "new_formula_name", alias_path: alias_path do + formula("new_formula_name", alias_path:) do url "foo-1.1" end end @@ -1415,7 +1415,7 @@ def setup_tab_for_prefix(prefix, options = {}) end example "outdated old alias targets installed" do - f = formula alias_path: alias_path do + f = formula(alias_path:) do url "foo-1.0" end @@ -1430,7 +1430,7 @@ def setup_tab_for_prefix(prefix, options = {}) end example "outdated old alias targets not installed" do - f = formula alias_path: alias_path do + f = formula(alias_path:) do url "foo-1.0" end diff --git a/Library/Homebrew/test/formulary_spec.rb b/Library/Homebrew/test/formulary_spec.rb index 92e13432253707..86631a3a667ddb 100644 --- a/Library/Homebrew/test/formulary_spec.rb +++ b/Library/Homebrew/test/formulary_spec.rb @@ -6,7 +6,7 @@ RSpec.describe Formulary do let(:formula_name) { "testball_bottle" } - let(:formula_path) { CoreTap.new.new_formula_path(formula_name) } + let(:formula_path) { CoreTap.instance.new_formula_path(formula_name) } let(:formula_content) do <<~RUBY class #{described_class.class_s(formula_name)} < Formula @@ -85,7 +85,7 @@ def install let(:formula_name) { "testball_sharded" } let(:formula_path) do - core_tap = CoreTap.new + core_tap = CoreTap.instance (core_tap.formula_dir/formula_name[0]).mkpath core_tap.new_formula_path(formula_name) end @@ -184,8 +184,8 @@ class Wrong#{described_class.class_s(formula_name)} < Formula end context "when migrating from a Tap" do - let(:tap) { Tap.new("homebrew", "foo") } - let(:another_tap) { Tap.new("homebrew", "bar") } + let(:tap) { Tap.fetch("homebrew", "foo") } + let(:another_tap) { Tap.fetch("homebrew", "bar") } let(:tap_migrations_path) { tap.path/"tap_migrations.json" } let(:another_tap_formula_path) { another_tap.path/"Formula/#{formula_name}.rb" } @@ -226,8 +226,8 @@ class Wrong#{described_class.class_s(formula_name)} < Formula end context "when loading from Tap" do - let(:tap) { Tap.new("homebrew", "foo") } - let(:another_tap) { Tap.new("homebrew", "bar") } + let(:tap) { Tap.fetch("homebrew", "foo") } + let(:another_tap) { Tap.fetch("homebrew", "bar") } let(:formula_path) { tap.path/"Formula/#{formula_name}.rb" } let(:alias_name) { "bar" } let(:alias_dir) { tap.alias_dir } @@ -556,54 +556,90 @@ def formula_json_contents(extra_items = {}) ENV["HOMEBREW_NO_INSTALL_FROM_API"] = "1" end - context "when a formula is migrated to the default tap" do + context "when a formula is migrated" do let(:token) { "foo" } + + let(:core_tap) { CoreTap.instance } + let(:core_cask_tap) { CoreCaskTap.instance } + let(:tap_migrations) do { - token => default_tap.name, + token => new_tap.name, } end - let(:old_tap) { CoreCaskTap.instance } - let(:default_tap) { CoreTap.instance } before do old_tap.path.mkpath + new_tap.path.mkpath (old_tap.path/"tap_migrations.json").write tap_migrations.to_json - FileUtils.touch default_tap.formula_dir/"foo.rb" end - it "does not warn when loading the short token" do - expect do - described_class.loader_for(token) - end.not_to output.to_stderr - end + context "to a cask in the default tap" do + let(:old_tap) { core_tap } + let(:new_tap) { core_cask_tap } - it "does not warn when loading the full token in the default tap" do - expect do - described_class.loader_for("#{default_tap}/#{token}") - end.not_to output.to_stderr - end + let(:cask_file) { new_tap.cask_dir/"#{token}.rb" } - it "warns when loading the full token in the old tap" do - expect do - described_class.loader_for("#{old_tap}/#{token}") - end.to output(%r{Formula #{old_tap}/#{token} was renamed to #{token}\.}).to_stderr + before do + new_tap.cask_dir.mkpath + FileUtils.touch cask_file + end + + it "warn only once" do + expect do + described_class.loader_for(token) + end.to output( + a_string_including("Warning: Formula #{token} was renamed to #{new_tap}/#{token}.").once, + ).to_stderr + end end - # FIXME - # context "when there is an infinite tap migration loop" do - # before do - # (default_tap.path/"tap_migrations.json").write({ - # token => old_tap.name, - # }.to_json) - # end - # - # it "stops recursing" do - # expect do - # described_class.loader_for("#{default_tap}/#{token}") - # end.not_to output.to_stderr - # end - # end + context "to the default tap" do + let(:old_tap) { core_cask_tap } + let(:new_tap) { core_tap } + + let(:formula_file) { new_tap.formula_dir/"#{token}.rb" } + + before do + new_tap.formula_dir.mkpath + FileUtils.touch formula_file + end + + it "does not warn when loading the short token" do + expect do + described_class.loader_for(token) + end.not_to output.to_stderr + end + + it "does not warn when loading the full token in the default tap" do + expect do + described_class.loader_for("#{new_tap}/#{token}") + end.not_to output.to_stderr + end + + it "warns when loading the full token in the old tap" do + expect do + described_class.loader_for("#{old_tap}/#{token}") + end.to output( + a_string_including("Formula #{old_tap}/#{token} was renamed to #{token}.").once, + ).to_stderr + end + + # FIXME + # context "when there is an infinite tap migration loop" do + # before do + # (new_tap.path/"tap_migrations.json").write({ + # token => old_tap.name, + # }.to_json) + # end + # + # it "stops recursing" do + # expect do + # described_class.loader_for("#{new_tap}/#{token}") + # end.not_to output.to_stderr + # end + # end + end end end end diff --git a/Library/Homebrew/test/github_runner_spec.rb b/Library/Homebrew/test/github_runner_spec.rb index d0597db86cd441..3e35126ba9594c 100644 --- a/Library/Homebrew/test/github_runner_spec.rb +++ b/Library/Homebrew/test/github_runner_spec.rb @@ -6,7 +6,7 @@ let(:runner) do spec = MacOSRunnerSpec.new(name: "macOS 11-arm64", runner: "11-arm64", timeout: 90, cleanup: true) version = MacOSVersion.new("11") - described_class.new(platform: :macos, arch: :arm64, spec: spec, macos_version: version) + described_class.new(platform: :macos, arch: :arm64, spec:, macos_version: version) end it "has immutable attributes" do diff --git a/Library/Homebrew/test/language/python/virtualenv_spec.rb b/Library/Homebrew/test/language/python/virtualenv_spec.rb index 0ef5ac6db59865..4f565400ebfdf4 100644 --- a/Library/Homebrew/test/language/python/virtualenv_spec.rb +++ b/Library/Homebrew/test/language/python/virtualenv_spec.rb @@ -11,7 +11,7 @@ let(:resource) { instance_double(Resource, "resource", stage: true) } let(:formula_bin) { dir/"formula_bin" } let(:formula_man) { dir/"formula_man" } - let(:formula) { instance_double(Formula, "formula", resource: resource, bin: formula_bin, man: formula_man) } + let(:formula) { instance_double(Formula, "formula", resource:, bin: formula_bin, man: formula_man) } describe "#create" do it "creates a venv" do diff --git a/Library/Homebrew/test/livecheck/strategy/crate_spec.rb b/Library/Homebrew/test/livecheck/strategy/crate_spec.rb index 0333d735141215..0f914ffb5e7063 100644 --- a/Library/Homebrew/test/livecheck/strategy/crate_spec.rb +++ b/Library/Homebrew/test/livecheck/strategy/crate_spec.rb @@ -54,7 +54,7 @@ "1.0.1" => Version.new("1.0.1"), "1.0.0" => Version.new("1.0.0"), }, - regex: regex, + regex:, url: generated[:url], } end @@ -93,28 +93,28 @@ } { - cached: cached, + cached:, cached_default: cached.merge({ matches: {} }), } end it "finds versions in provided content" do - expect(crate.find_versions(url: crate_url, regex: regex, provided_content: content)) - .to eq(match_data[:cached].merge({ regex: regex })) + expect(crate.find_versions(url: crate_url, regex:, provided_content: content)) + .to eq(match_data[:cached].merge({ regex: })) expect(crate.find_versions(url: crate_url, provided_content: content)) .to eq(match_data[:cached]) end it "finds versions in provided content using a block" do - expect(crate.find_versions(url: crate_url, regex: regex, provided_content: content) do |json, regex| + expect(crate.find_versions(url: crate_url, regex:, provided_content: content) do |json, regex| json["versions"]&.map do |version| next if version["yanked"] == true next if (match = version["num"]&.match(regex)).blank? match[1] end - end).to eq(match_data[:cached].merge({ regex: regex })) + end).to eq(match_data[:cached].merge({ regex: })) expect(crate.find_versions(url: crate_url, provided_content: content) do |json| json["versions"]&.map do |version| diff --git a/Library/Homebrew/test/livecheck/strategy/electron_builder_spec.rb b/Library/Homebrew/test/livecheck/strategy/electron_builder_spec.rb index 403eb2e2e26afe..fde044cb4f0f5f 100644 --- a/Library/Homebrew/test/livecheck/strategy/electron_builder_spec.rb +++ b/Library/Homebrew/test/livecheck/strategy/electron_builder_spec.rb @@ -66,17 +66,17 @@ expect(electron_builder.find_versions(url: http_url, provided_content: content)) .to eq(find_versions_cached_return_hash) - expect(electron_builder.find_versions(url: http_url, regex: regex, provided_content: content) do |yaml, regex| + expect(electron_builder.find_versions(url: http_url, regex:, provided_content: content) do |yaml, regex| yaml["path"][regex, 1] - end).to eq(find_versions_cached_return_hash.merge({ regex: regex })) + end).to eq(find_versions_cached_return_hash.merge({ regex: })) expect(electron_builder.find_versions( url: http_url, - regex: regex, + regex:, provided_content: content_timestamp, ) do |yaml, regex| yaml["path"][regex, 1] - end).to eq(find_versions_cached_return_hash.merge({ regex: regex })) + end).to eq(find_versions_cached_return_hash.merge({ regex: })) # NOTE: A regex should be provided using the `#regex` method in a # `livecheck` block but we're using a regex literal in the `strategy` @@ -89,7 +89,7 @@ end it "errors if a block is not provided" do - expect { electron_builder.find_versions(url: http_url, regex: regex, provided_content: content) } + expect { electron_builder.find_versions(url: http_url, regex:, provided_content: content) } .to raise_error(ArgumentError, "ElectronBuilder only supports a regex when using a `strategy` block") end diff --git a/Library/Homebrew/test/livecheck/strategy/json_spec.rb b/Library/Homebrew/test/livecheck/strategy/json_spec.rb index dadaab33dbe029..43c47250f57cd1 100644 --- a/Library/Homebrew/test/livecheck/strategy/json_spec.rb +++ b/Library/Homebrew/test/livecheck/strategy/json_spec.rb @@ -54,7 +54,7 @@ "1.0.1" => Version.new("1.0.1"), "1.0.0" => Version.new("1.0.0"), }, - regex: regex, + regex:, url: http_url, } end @@ -120,7 +120,7 @@ describe "::find_versions?" do it "finds versions in provided_content using a block" do - expect(json.find_versions(url: http_url, regex: regex, provided_content: content) do |json, regex| + expect(json.find_versions(url: http_url, regex:, provided_content: content) do |json, regex| json["versions"].select { |item| item["version"]&.match?(regex) } .map { |item| item["version"][regex, 1] } end).to eq(find_versions_cached_return_hash) diff --git a/Library/Homebrew/test/livecheck/strategy/page_match_spec.rb b/Library/Homebrew/test/livecheck/strategy/page_match_spec.rb index 3ffd22d5e2483f..4b2fab932167d3 100644 --- a/Library/Homebrew/test/livecheck/strategy/page_match_spec.rb +++ b/Library/Homebrew/test/livecheck/strategy/page_match_spec.rb @@ -50,7 +50,7 @@ "2.0.0" => Version.new("2.0.0"), "1.9.0" => Version.new("1.9.0"), }, - regex: regex, + regex:, url: http_url, } end @@ -105,7 +105,7 @@ describe "::find_versions?" do it "finds versions in provided_content" do - expect(page_match.find_versions(url: http_url, regex: regex, provided_content: content)) + expect(page_match.find_versions(url: http_url, regex:, provided_content: content)) .to eq(find_versions_cached_return_hash) # NOTE: Ideally, a regex should always be provided to `#find_versions` diff --git a/Library/Homebrew/test/livecheck/strategy/sparkle_spec.rb b/Library/Homebrew/test/livecheck/strategy/sparkle_spec.rb index 3e7eff78d3758d..97bc76ca69ec02 100644 --- a/Library/Homebrew/test/livecheck/strategy/sparkle_spec.rb +++ b/Library/Homebrew/test/livecheck/strategy/sparkle_spec.rb @@ -174,13 +174,13 @@ def create_appcast_xml(items_str = "") undefined_namespace = appcast.sub(/\s*xmlns:sparkle="[^"]+"/, "") { - appcast: appcast, - omitted_items: omitted_items, - bad_macos_version: bad_macos_version, - beta_channel_item: beta_channel_item, - no_versions_item: no_versions_item, - no_items: no_items, - undefined_namespace: undefined_namespace, + appcast:, + omitted_items:, + bad_macos_version:, + beta_channel_item:, + no_versions_item:, + no_items:, + undefined_namespace:, } end diff --git a/Library/Homebrew/test/livecheck/strategy/xml_spec.rb b/Library/Homebrew/test/livecheck/strategy/xml_spec.rb index 9ab0d13ff4f11b..b8790495564dfc 100644 --- a/Library/Homebrew/test/livecheck/strategy/xml_spec.rb +++ b/Library/Homebrew/test/livecheck/strategy/xml_spec.rb @@ -111,7 +111,7 @@ "1.0.1" => Version.new("1.0.1"), "1.0.0" => Version.new("1.0.0"), }, - regex: regex, + regex:, url: http_url, } end @@ -213,7 +213,7 @@ describe "::find_versions?" do it "finds versions in provided_content using a block" do - expect(xml.find_versions(url: http_url, regex: regex, provided_content: content_version_text) do |xml, regex| + expect(xml.find_versions(url: http_url, regex:, provided_content: content_version_text) do |xml, regex| xml.get_elements("/versions/version").map { |item| item.text[regex, 1] } end).to eq(find_versions_cached_return_hash) diff --git a/Library/Homebrew/test/livecheck/strategy/yaml_spec.rb b/Library/Homebrew/test/livecheck/strategy/yaml_spec.rb index 835abb2b8da5df..72d7a67f36f819 100644 --- a/Library/Homebrew/test/livecheck/strategy/yaml_spec.rb +++ b/Library/Homebrew/test/livecheck/strategy/yaml_spec.rb @@ -55,7 +55,7 @@ "1.0.1" => Version.new("1.0.1"), "1.0.0" => Version.new("1.0.0"), }, - regex: regex, + regex:, url: http_url, } end @@ -121,7 +121,7 @@ describe "::find_versions?" do it "finds versions in provided_content using a block" do - expect(yaml.find_versions(url: http_url, regex: regex, provided_content: content) do |yaml, regex| + expect(yaml.find_versions(url: http_url, regex:, provided_content: content) do |yaml, regex| yaml["versions"].select { |item| item["version"]&.match?(regex) } .map { |item| item["version"][regex, 1] } end).to eq(find_versions_cached_return_hash) diff --git a/Library/Homebrew/test/missing_formula_spec.rb b/Library/Homebrew/test/missing_formula_spec.rb index 8c69381af525fe..b85a608ce33445 100644 --- a/Library/Homebrew/test/missing_formula_spec.rb +++ b/Library/Homebrew/test/missing_formula_spec.rb @@ -99,7 +99,7 @@ end describe "::cask_reason", :cask do - subject { described_class.cask_reason(formula, show_info: show_info) } + subject { described_class.cask_reason(formula, show_info:) } context "with a formula name that is a cask and show_info: false" do let(:formula) { "local-caffeine" } diff --git a/Library/Homebrew/test/os/linux/pathname_spec.rb b/Library/Homebrew/test/os/linux/pathname_spec.rb index de348cd79c402e..62d4e96bec968c 100644 --- a/Library/Homebrew/test/os/linux/pathname_spec.rb +++ b/Library/Homebrew/test/os/linux/pathname_spec.rb @@ -53,7 +53,7 @@ def patch_elfs prefixes.each do |new_prefix| patch_elfs do |elf| interpreter = elf.interpreter.gsub(placeholder_prefix, new_prefix) - elf.patch!(interpreter: interpreter) + elf.patch!(interpreter:) modified_elf = elf.dirname/"mod.#{elf.basename}" FileUtils.cp(elf, modified_elf) @@ -67,7 +67,7 @@ def patch_elfs prefixes.each do |new_prefix| patch_elfs do |elf| rpath = elf.rpath.gsub(placeholder_prefix, new_prefix) - elf.patch!(rpath: rpath) + elf.patch!(rpath:) modified_elf = elf.dirname/"mod.#{elf.basename}" FileUtils.cp(elf, modified_elf) @@ -82,7 +82,7 @@ def patch_elfs patch_elfs do |elf| interpreter = elf.interpreter.gsub(placeholder_prefix, new_prefix) rpath = elf.rpath.gsub(placeholder_prefix, new_prefix) - elf.patch!(interpreter: interpreter, rpath: rpath) + elf.patch!(interpreter:, rpath:) modified_elf = elf.dirname/"mod.#{elf.basename}" FileUtils.cp(elf, modified_elf) diff --git a/Library/Homebrew/test/patching_spec.rb b/Library/Homebrew/test/patching_spec.rb index bf1be10b9ddc31..7ca14c511c3573 100644 --- a/Library/Homebrew/test/patching_spec.rb +++ b/Library/Homebrew/test/patching_spec.rb @@ -25,7 +25,7 @@ def formula(name = "formula_name", path: Formulary.core_path(name), spec: :stable, alias_path: nil, &block) formula_subclass.class_eval(&block) - formula_subclass.new(name, path, spec, alias_path: alias_path) + formula_subclass.new(name, path, spec, alias_path:) end matcher :be_patched do diff --git a/Library/Homebrew/test/requirements/codesign_requirement_spec.rb b/Library/Homebrew/test/requirements/codesign_requirement_spec.rb index 7f4c1b2586b871..00f101310c3eb3 100644 --- a/Library/Homebrew/test/requirements/codesign_requirement_spec.rb +++ b/Library/Homebrew/test/requirements/codesign_requirement_spec.rb @@ -4,7 +4,7 @@ RSpec.describe CodesignRequirement do subject(:requirement) do - described_class.new([{ identity: identity, with: with, url: url }]) + described_class.new([{ identity:, with:, url: }]) end let(:identity) { "lldb_codesign" } diff --git a/Library/Homebrew/test/rubocops/blank_spec.rb b/Library/Homebrew/test/rubocops/blank_spec.rb index 78504cd4d77f74..ee3fc32a080fd8 100644 --- a/Library/Homebrew/test/rubocops/blank_spec.rb +++ b/Library/Homebrew/test/rubocops/blank_spec.rb @@ -5,7 +5,7 @@ RSpec.describe RuboCop::Cop::Homebrew::Blank, :config do shared_examples "offense" do |source, correction, message| it "registers an offense and corrects" do - expect_offense(<<~RUBY, source: source, message: message) + expect_offense(<<~RUBY, source:, message:) #{source} ^{source} #{message} RUBY diff --git a/Library/Homebrew/test/rubocops/homepage_spec.rb b/Library/Homebrew/test/rubocops/homepage_spec.rb index 8910e3d3c81629..6b845603c48292 100644 --- a/Library/Homebrew/test/rubocops/homepage_spec.rb +++ b/Library/Homebrew/test/rubocops/homepage_spec.rb @@ -163,7 +163,7 @@ class #{name.capitalize} < Formula severity: :convention, line: 2, column: 11, - source: source }] + source: }] expected_offenses.zip([inspect_source(source).last]).each do |expected, actual| expect(actual.message).to eq(expected[:message]) diff --git a/Library/Homebrew/test/rubocops/patches_spec.rb b/Library/Homebrew/test/rubocops/patches_spec.rb index 55109d662c3d5b..0c56e3f6f195e7 100644 --- a/Library/Homebrew/test/rubocops/patches_spec.rb +++ b/Library/Homebrew/test/rubocops/patches_spec.rb @@ -6,7 +6,7 @@ subject(:cop) { described_class.new } def expect_offense_hash(message:, severity:, line:, column:, source:) - [{ message: message, severity: severity, line: line, column: column, source: source }] + [{ message:, severity:, line:, column:, source: }] end context "when auditing legacy patches" do @@ -52,29 +52,29 @@ def patches EOS expected_offense = if patch_url.include?("/raw.github.com/") - expect_offense_hash message: <<~EOS.chomp, severity: :convention, line: 5, column: 4, source: source + expect_offense_hash(message: <<~EOS.chomp, severity: :convention, line: 5, column: 4, source:) FormulaAudit/Patches: GitHub/Gist patches should specify a revision: #{patch_url} EOS elsif patch_url.include?("macports/trunk") - expect_offense_hash message: <<~EOS.chomp, severity: :convention, line: 5, column: 4, source: source + expect_offense_hash(message: <<~EOS.chomp, severity: :convention, line: 5, column: 4, source:) FormulaAudit/Patches: MacPorts patches should specify a revision instead of trunk: #{patch_url} EOS elsif patch_url.start_with?("http://trac.macports.org/") - expect_offense_hash message: <<~EOS.chomp, severity: :convention, line: 5, column: 4, source: source + expect_offense_hash(message: <<~EOS.chomp, severity: :convention, line: 5, column: 4, source:) FormulaAudit/Patches: Patches from MacPorts Trac should be https://, not http: #{patch_url} EOS elsif patch_url.start_with?("http://bugs.debian.org/") - expect_offense_hash message: <<~EOS.chomp, severity: :convention, line: 5, column: 4, source: source + expect_offense_hash(message: <<~EOS.chomp, severity: :convention, line: 5, column: 4, source:) FormulaAudit/Patches: Patches from Debian should be https://, not http: #{patch_url} EOS # rubocop:disable Layout/LineLength elsif patch_url.match?(%r{https?://patch-diff\.githubusercontent\.com/raw/(.+)/(.+)/pull/(.+)\.(?:diff|patch)}) # rubocop:enable Layout/LineLength - expect_offense_hash message: <<~EOS.chomp, severity: :convention, line: 5, column: 4, source: source + expect_offense_hash(message: <<~EOS.chomp, severity: :convention, line: 5, column: 4, source:) FormulaAudit/Patches: Use a commit hash URL rather than patch-diff: #{patch_url} EOS elsif patch_url.match?(%r{https?://github\.com/.+/.+/(?:commit|pull)/[a-fA-F0-9]*.(?:patch|diff)}) - expect_offense_hash message: <<~EOS.chomp, severity: :convention, line: 5, column: 4, source: source + expect_offense_hash(message: <<~EOS.chomp, severity: :convention, line: 5, column: 4, source:) FormulaAudit/Patches: GitHub patches should use the full_index parameter: #{patch_url}?full_index=1 EOS end @@ -108,14 +108,14 @@ def patches severity: :convention, line: 4, column: 2, - source: source, + source:, }, { message: "FormulaAudit/Patches: Patches from MacPorts Trac should be https://, not http: " \ "http://trac.macports.org/export/68507/trunk/dports/net/trafshow/files/", severity: :convention, line: 8, column: 25, - source: source, + source:, } ] @@ -201,41 +201,41 @@ class Foo < Formula RUBY expected_offense = if patch_url.include?("/raw.github.com/") - expect_offense_hash message: <<~EOS.chomp, severity: :convention, line: 5, column: 8, source: source + expect_offense_hash(message: <<~EOS.chomp, severity: :convention, line: 5, column: 8, source:) FormulaAudit/Patches: GitHub/Gist patches should specify a revision: #{patch_url} EOS elsif patch_url.include?("macports/trunk") - expect_offense_hash message: <<~EOS.chomp, severity: :convention, line: 5, column: 8, source: source + expect_offense_hash(message: <<~EOS.chomp, severity: :convention, line: 5, column: 8, source:) FormulaAudit/Patches: MacPorts patches should specify a revision instead of trunk: #{patch_url} EOS elsif patch_url.start_with?("http://trac.macports.org/") - expect_offense_hash message: <<~EOS.chomp, severity: :convention, line: 5, column: 8, source: source + expect_offense_hash(message: <<~EOS.chomp, severity: :convention, line: 5, column: 8, source:) FormulaAudit/Patches: Patches from MacPorts Trac should be https://, not http: #{patch_url} EOS elsif patch_url.start_with?("http://bugs.debian.org/") - expect_offense_hash message: <<~EOS.chomp, severity: :convention, line: 5, column: 8, source: source + expect_offense_hash(message: <<~EOS.chomp, severity: :convention, line: 5, column: 8, source:) FormulaAudit/Patches: Patches from Debian should be https://, not http: #{patch_url} EOS elsif patch_url.match?(%r{https://github.com/[^/]*/[^/]*/pull}) - expect_offense_hash message: <<~EOS.chomp, severity: :convention, line: 5, column: 8, source: source + expect_offense_hash(message: <<~EOS.chomp, severity: :convention, line: 5, column: 8, source:) FormulaAudit/Patches: Use a commit hash URL rather than an unstable pull request URL: #{patch_url} EOS elsif patch_url.match?(%r{.*gitlab.*/merge_request.*}) - expect_offense_hash message: <<~EOS.chomp, severity: :convention, line: 5, column: 8, source: source + expect_offense_hash(message: <<~EOS.chomp, severity: :convention, line: 5, column: 8, source:) FormulaAudit/Patches: Use a commit hash URL rather than an unstable merge request URL: #{patch_url} EOS elsif patch_url.match?(%r{https://github.com/[^/]*/[^/]*/commit/}) - expect_offense_hash message: <<~EOS.chomp, severity: :convention, line: 5, column: 8, source: source + expect_offense_hash(message: <<~EOS.chomp, severity: :convention, line: 5, column: 8, source:) FormulaAudit/Patches: GitHub patches should end with .patch, not .diff: #{patch_url} EOS elsif patch_url.match?(%r{.*gitlab.*/commit/}) - expect_offense_hash message: <<~EOS.chomp, severity: :convention, line: 5, column: 8, source: source + expect_offense_hash(message: <<~EOS.chomp, severity: :convention, line: 5, column: 8, source:) FormulaAudit/Patches: GitLab patches should end with .diff, not .patch: #{patch_url} EOS # rubocop:disable Layout/LineLength elsif patch_url.match?(%r{https?://patch-diff\.githubusercontent\.com/raw/(.+)/(.+)/pull/(.+)\.(?:diff|patch)}) # rubocop:enable Layout/LineLength - expect_offense_hash message: <<~EOS.chomp, severity: :convention, line: 5, column: 8, source: source + expect_offense_hash(message: <<~EOS.chomp, severity: :convention, line: 5, column: 8, source:) FormulaAudit/Patches: Use a commit hash URL rather than patch-diff: #{patch_url} EOS end diff --git a/Library/Homebrew/test/rubocops/presence_spec.rb b/Library/Homebrew/test/rubocops/presence_spec.rb index 23297c66acac63..9d2dd7b4864d18 100644 --- a/Library/Homebrew/test/rubocops/presence_spec.rb +++ b/Library/Homebrew/test/rubocops/presence_spec.rb @@ -321,7 +321,7 @@ context "when a right-hand side of the relational operator" do %w[< > <= >= == !=].each do |operator| it "registers an offense and corrects when `#{operator}`" do - expect_offense(<<~RUBY, operator: operator) + expect_offense(<<~RUBY, operator:) a #{operator} if b.present? _{operator} ^^^^^^^^^^^^^ Use `(b.presence || c)` instead of `if b.present? ... end`. b diff --git a/Library/Homebrew/test/rubocops/present_spec.rb b/Library/Homebrew/test/rubocops/present_spec.rb index 9ee19e8811a381..1c2264583284e2 100644 --- a/Library/Homebrew/test/rubocops/present_spec.rb +++ b/Library/Homebrew/test/rubocops/present_spec.rb @@ -5,7 +5,7 @@ RSpec.describe RuboCop::Cop::Homebrew::Present, :config do shared_examples "offense" do |source, correction, message| it "registers an offense and corrects" do - expect_offense(<<~RUBY, source: source, message: message) + expect_offense(<<~RUBY, source:, message:) #{source} ^{source} #{message} RUBY diff --git a/Library/Homebrew/test/rubocops/urls_spec.rb b/Library/Homebrew/test/rubocops/urls_spec.rb index 2a887c23976770..fe52e72c5008f2 100644 --- a/Library/Homebrew/test/rubocops/urls_spec.rb +++ b/Library/Homebrew/test/rubocops/urls_spec.rb @@ -197,7 +197,7 @@ class Foo < Formula severity: :convention, line: 3, column: offense_info["col"], - source: source }] + source: }] offenses = inspect_source(source) diff --git a/Library/Homebrew/test/sorbet/tapioca/compilers/args_spec.rb b/Library/Homebrew/test/sorbet/tapioca/compilers/args_spec.rb new file mode 100644 index 00000000000000..631a80d2c84b14 --- /dev/null +++ b/Library/Homebrew/test/sorbet/tapioca/compilers/args_spec.rb @@ -0,0 +1,94 @@ +# frozen_string_literal: true + +# require 'tapioca' +require "tapioca/dsl" +require_relative "../../../../sorbet/tapioca/compilers/args" + +RSpec.describe Tapioca::Compilers::Args do + let(:compiler) { described_class.new(Tapioca::Dsl::Pipeline.new(requested_constants: []), RBI::Tree.new, Homebrew) } + let(:list_parser) do + require "cmd/list" + Homebrew.list_args + end + # good testing candidate, bc it has multiple for each of switch, flag, and comma_array args: + let(:update_python_resources_parser) do + require "dev-cmd/update-python-resources" + Homebrew.update_python_resources_args + end + + describe "#args_table" do + it "returns a mapping of list args to default values" do + expect(compiler.args_table(list_parser)).to eq({ + "1?": false, + cask?: false, + casks?: false, + d?: false, + debug?: false, + formula?: false, + formulae?: false, + full_name?: false, + h?: false, + help?: false, + l?: false, + multiple?: false, + pinned?: false, + q?: false, + quiet?: false, + r?: false, + t?: false, + v?: false, + verbose?: false, + versions?: false, + }) + end + + it "rreturns a mapping of update-python-resources args to default values" do + expect(compiler.args_table(update_python_resources_parser)).to eq({ + d?: false, + debug?: false, + exclude_packages: nil, + extra_packages: nil, + h?: false, + help?: false, + ignore_non_pypi_packages?: false, + install_dependencies?: false, + p?: false, + package_name: nil, + print_only?: false, + q?: false, + quiet?: false, + s?: false, + silent?: false, + v?: false, + verbose?: false, + version: nil, + }) + end + end + + describe "#comma_arrays" do + it "returns an empty list when there are no comma_array args" do + expect(compiler.comma_arrays(list_parser)).to eq([]) + end + + it "returns the comma_array args when they exist" do + expect(compiler.comma_arrays(update_python_resources_parser)).to eq([:extra_packages, :exclude_packages]) + end + end + + describe "#get_return_type" do + let(:comma_arrays) { compiler.comma_arrays(update_python_resources_parser) } + + it "returns the correct type for switches" do + expect(compiler.get_return_type(:silent?, false, comma_arrays)).to eq("T::Boolean") + end + + it "returns the correct type for flags" do + expect(compiler.get_return_type(:package_name, nil, comma_arrays)).to eq("T.nilable(String)") + end + + it "returns the correct type for comma_arrays" do + expect(compiler.get_return_type(:extra_packages, nil, comma_arrays)).to eq("T.nilable(T::Array[String])") + end + end +end diff --git a/Library/Homebrew/test/spec_helper.rb b/Library/Homebrew/test/spec_helper.rb index 48068f8f378d67..b8af2d24e957b5 100644 --- a/Library/Homebrew/test/spec_helper.rb +++ b/Library/Homebrew/test/spec_helper.rb @@ -204,7 +204,7 @@ config.around do |example| Homebrew.raise_deprecation_exceptions = true - Tap.each(&:clear_cache) + Tap.installed.each(&:clear_cache) Cachable::Registry.clear_all_caches FormulaInstaller.clear_attempted FormulaInstaller.clear_installed @@ -244,9 +244,6 @@ rescue SystemExit => e example.example.set_exception(e) ensure - # This depends on `HOMEBREW_NO_INSTALL_FROM_API`. - Tap.each(&:clear_cache) - ENV.replace(@__env) Context.current = Context::ContextStruct.new @@ -257,6 +254,7 @@ @__stderr.close @__stdin.close + Tap.all.each(&:clear_cache) Cachable::Registry.clear_all_caches FileUtils.rm_rf [ diff --git a/Library/Homebrew/test/support/fixtures/cask/everything.json b/Library/Homebrew/test/support/fixtures/cask/everything.json index 6efdcaa095993d..59bebe0635c47e 100644 --- a/Library/Homebrew/test/support/fixtures/cask/everything.json +++ b/Library/Homebrew/test/support/fixtures/cask/everything.json @@ -21,6 +21,8 @@ "version": "1.2.3", "installed": null, "installed_time": null, + "bundle_version": null, + "bundle_short_version": null, "outdated": false, "sha256": "c64c05bdc0be845505d6e55e69e696a7f50d40846e76155f0c85d5ff5e7bbb84", "artifacts": [ diff --git a/Library/Homebrew/test/support/helper/formula.rb b/Library/Homebrew/test/support/helper/formula.rb index 558c08de21fba2..a3c042666ebf2a 100644 --- a/Library/Homebrew/test/support/helper/formula.rb +++ b/Library/Homebrew/test/support/helper/formula.rb @@ -5,8 +5,9 @@ module Test module Helper module Formula - def formula(name = "formula_name", path: Formulary.core_path(name), spec: :stable, alias_path: nil, &block) - Class.new(::Formula, &block).new(name, path, spec, alias_path: alias_path) + def formula(name = "formula_name", path: Formulary.core_path(name), spec: :stable, alias_path: nil, tap: nil, + &block) + Class.new(::Formula, &block).new(name, path, spec, alias_path:, tap:) end # Use a stubbed {Formulary::FormulaLoader} to make a given formula be found diff --git a/Library/Homebrew/test/support/helper/spec/shared_context/integration_test.rb b/Library/Homebrew/test/support/helper/spec/shared_context/integration_test.rb index ff4792c29d37fe..fbc361dd0e760c 100644 --- a/Library/Homebrew/test/support/helper/spec/shared_context/integration_test.rb +++ b/Library/Homebrew/test/support/helper/spec/shared_context/integration_test.rb @@ -129,7 +129,7 @@ def brew_sh(*args) end end - def setup_test_formula(name, content = nil, bottle_block: nil) + def setup_test_formula(name, content = nil, tap: CoreTap.instance, bottle_block: nil) case name when /^testball/ tarball = if OS.linux? @@ -174,20 +174,20 @@ def install RUBY end - Formulary.core_path(name).tap do |formula_path| + Formulary.find_formula_in_tap(name.downcase, tap).tap do |formula_path| formula_path.write <<~RUBY class #{Formulary.class_s(name)} < Formula #{content.gsub(/^(?!$)/, " ")} end RUBY - CoreTap.instance.clear_cache + tap.clear_cache end end def install_test_formula(name, content = nil, build_bottle: false) setup_test_formula(name, content) - fi = FormulaInstaller.new(Formula[name], build_bottle: build_bottle) + fi = FormulaInstaller.new(Formula[name], build_bottle:) fi.prelude fi.fetch fi.install diff --git a/Library/Homebrew/test/system_command_spec.rb b/Library/Homebrew/test/system_command_spec.rb index 1dd0c519cd3211..756cc40685c0cf 100644 --- a/Library/Homebrew/test/system_command_spec.rb +++ b/Library/Homebrew/test/system_command_spec.rb @@ -8,10 +8,10 @@ described_class.new( "env", args: env_args, - env: env, + env:, must_succeed: true, - sudo: sudo, - sudo_as_root: sudo_as_root, + sudo:, + sudo_as_root:, ) end diff --git a/Library/Homebrew/test/tab_spec.rb b/Library/Homebrew/test/tab_spec.rb index 2a4865411e2f64..961f9c0e5cded7 100644 --- a/Library/Homebrew/test/tab_spec.rb +++ b/Library/Homebrew/test/tab_spec.rb @@ -252,7 +252,7 @@ depends_on "baz" => :build end - tap = Tap.new("user", "repo") + tap = Tap.fetch("user", "repo") from_tap = formula("from_tap", path: tap.path/"Formula/from_tap.rb") do url "from_tap-1.0" revision 1 @@ -279,7 +279,7 @@ it "can create a Tab from an alias" do alias_path = CoreTap.instance.alias_dir/"bar" - f = formula(alias_path: alias_path) { url "foo-1.0" } + f = formula(alias_path:) { url "foo-1.0" } compiler = DevelopmentTools.default_compiler stdlib = :libcxx tab = described_class.create(f, compiler, stdlib) @@ -313,7 +313,7 @@ it "can create a Tab for for a Formula from an alias" do alias_path = CoreTap.instance.alias_dir/"bar" - f = formula(alias_path: alias_path) { url "foo-1.0" } + f = formula(alias_path:) { url "foo-1.0" } tab = described_class.for_formula(f) expect(tab.source["path"]).to eq(alias_path.to_s) diff --git a/Library/Homebrew/test/tap_spec.rb b/Library/Homebrew/test/tap_spec.rb index 0fd9fb11d91813..93e9317565c10c 100644 --- a/Library/Homebrew/test/tap_spec.rb +++ b/Library/Homebrew/test/tap_spec.rb @@ -4,7 +4,7 @@ alias_matcher :have_formula_file, :be_formula_file alias_matcher :have_custom_remote, :be_custom_remote - subject(:homebrew_foo_tap) { described_class.new("Homebrew", "foo") } + subject(:homebrew_foo_tap) { described_class.fetch("Homebrew", "foo") } let(:path) { Tap::TAP_DIRECTORY/"homebrew/homebrew-foo" } let(:formula_file) { path/"Formula/foo.rb" } @@ -103,15 +103,15 @@ def setup_completion(link:) expect do described_class.fetch("foo") - end.to raise_error(/Invalid tap name/) + end.to raise_error(ArgumentError, /Invalid tap name/) expect do described_class.fetch("homebrew/homebrew/bar") - end.to raise_error(/Invalid tap name/) + end.to raise_error(ArgumentError, /Invalid tap name/) expect do described_class.fetch("homebrew", "homebrew/baz") - end.to raise_error(/Invalid tap name/) + end.to raise_error(ArgumentError, /Invalid tap name/) end describe "::from_path" do @@ -155,7 +155,7 @@ def setup_completion(link:) end specify "#issues_url" do - t = described_class.new("someone", "foo") + t = described_class.fetch("someone", "foo") path = Tap::TAP_DIRECTORY/"someone/homebrew-foo" path.mkpath cd path do @@ -167,7 +167,7 @@ def setup_completion(link:) expect(homebrew_foo_tap.issues_url).to eq("https://github.com/Homebrew/homebrew-foo/issues") (Tap::TAP_DIRECTORY/"someone/homebrew-no-git").mkpath - expect(described_class.new("someone", "no-git").issues_url).to be_nil + expect(described_class.fetch("someone", "no-git").issues_url).to be_nil ensure path.parent.rmtree end @@ -198,7 +198,7 @@ def setup_completion(link:) expect(homebrew_foo_tap.remote).to eq("https://github.com/Homebrew/homebrew-foo") expect(homebrew_foo_tap).not_to have_custom_remote - services_tap = described_class.new("Homebrew", "services") + services_tap = described_class.fetch("Homebrew", "services") services_tap.path.mkpath services_tap.path.cd do system "git", "init" @@ -224,7 +224,7 @@ def setup_completion(link:) expect(homebrew_foo_tap.remote_repo).to eq("Homebrew/homebrew-foo") - services_tap = described_class.new("Homebrew", "services") + services_tap = described_class.fetch("Homebrew", "services") services_tap.path.mkpath services_tap.path.cd do system "git", "init" @@ -238,7 +238,7 @@ def setup_completion(link:) expect(homebrew_foo_tap.remote_repo).to eq("Homebrew/homebrew-foo") - services_tap = described_class.new("Homebrew", "services") + services_tap = described_class.fetch("Homebrew", "services") services_tap.path.mkpath services_tap.path.cd do system "git", "init" @@ -258,6 +258,37 @@ def setup_completion(link:) end end + describe "#custom_remote?" do + subject(:tap) { described_class.fetch("Homebrew", "services") } + + let(:remote) { nil } + + before do + tap.path.mkpath + system "git", "-C", tap.path, "init" + system "git", "-C", tap.path, "remote", "add", "origin", remote if remote + end + + context "if no remote is available" do + it "returns true" do + expect(tap.remote).to be_nil + expect(tap.custom_remote?).to be true + end + end + + context "when using the default remote" do + let(:remote) { "https://github.com/Homebrew/homebrew-services" } + + its(:custom_remote?) { is_expected.to be false } + end + + context "when using a non-default remote" do + let(:remote) { "git@github.com:Homebrew/homebrew-services" } + + its(:custom_remote?) { is_expected.to be true } + end + end + specify "Git variant" do touch path/"README" setup_git_repo @@ -273,14 +304,14 @@ def setup_completion(link:) describe "#install" do it "raises an error when the Tap is already tapped" do setup_git_repo - already_tapped_tap = described_class.new("Homebrew", "foo") + already_tapped_tap = described_class.fetch("Homebrew", "foo") expect(already_tapped_tap).to be_installed expect { already_tapped_tap.install }.to raise_error(TapAlreadyTappedError) end it "raises an error when the Tap is already tapped with the right remote" do setup_git_repo - already_tapped_tap = described_class.new("Homebrew", "foo") + already_tapped_tap = described_class.fetch("Homebrew", "foo") expect(already_tapped_tap).to be_installed right_remote = homebrew_foo_tap.remote expect { already_tapped_tap.install clone_target: right_remote }.to raise_error(TapAlreadyTappedError) @@ -288,7 +319,7 @@ def setup_completion(link:) it "raises an error when the remote doesn't match" do setup_git_repo - already_tapped_tap = described_class.new("Homebrew", "foo") + already_tapped_tap = described_class.fetch("Homebrew", "foo") expect(already_tapped_tap).to be_installed wrong_remote = "#{homebrew_foo_tap.remote}-oops" expect do @@ -306,7 +337,7 @@ def setup_completion(link:) it "raises an error when run `brew tap --custom-remote` without a custom remote (already installed)" do setup_git_repo - already_tapped_tap = described_class.new("Homebrew", "foo") + already_tapped_tap = described_class.fetch("Homebrew", "foo") expect(already_tapped_tap).to be_installed expect do @@ -315,7 +346,7 @@ def setup_completion(link:) end it "raises an error when run `brew tap --custom-remote` without a custom remote (not installed)" do - not_tapped_tap = described_class.new("Homebrew", "bar") + not_tapped_tap = described_class.fetch("Homebrew", "bar") expect(not_tapped_tap).not_to be_installed expect do @@ -323,33 +354,8 @@ def setup_completion(link:) end.to raise_error(TapNoCustomRemoteError) end - describe "force_auto_update" do - before do - setup_git_repo - end - - let(:already_tapped_tap) { described_class.new("Homebrew", "foo") } - - it "defaults to nil" do - expect(already_tapped_tap).to be_installed - expect(already_tapped_tap.config["forceautoupdate"]).to be_nil - end - - it "enables forced auto-updates when true" do - expect(already_tapped_tap).to be_installed - already_tapped_tap.install force_auto_update: true - expect(already_tapped_tap.config["forceautoupdate"]).to eq("true") - end - - it "disables forced auto-updates when false" do - expect(already_tapped_tap).to be_installed - already_tapped_tap.install force_auto_update: false - expect(already_tapped_tap.config["forceautoupdate"]).to be_nil - end - end - specify "Git error" do - tap = described_class.new("user", "repo") + tap = described_class.fetch("user", "repo") expect do tap.install clone_target: "file:///not/existed/remote/url" @@ -362,7 +368,7 @@ def setup_completion(link:) describe "#uninstall" do it "raises an error if the Tap is not available" do - tap = described_class.new("Homebrew", "bar") + tap = described_class.fetch("Homebrew", "bar") expect { tap.uninstall }.to raise_error(TapUnavailableError) end end @@ -372,7 +378,7 @@ def setup_completion(link:) setup_git_repo setup_completion link: true - tap = described_class.new("Homebrew", "bar") + tap = described_class.fetch("Homebrew", "bar") tap.install clone_target: homebrew_foo_tap.path/".git" @@ -398,7 +404,7 @@ def setup_completion(link:) setup_tap_files setup_git_repo setup_completion link: true - tap = described_class.new("NotHomebrew", "baz") + tap = described_class.fetch("NotHomebrew", "baz") tap.install clone_target: homebrew_foo_tap.path/".git" (HOMEBREW_PREFIX/"share/man/man1/brew-tap-cmd.1").delete (HOMEBREW_PREFIX/"etc/bash_completion.d/brew-tap-cmd").delete @@ -419,7 +425,7 @@ def setup_completion(link:) setup_tap_files setup_git_repo setup_completion link: false - tap = described_class.new("NotHomebrew", "baz") + tap = described_class.fetch("NotHomebrew", "baz") tap.install clone_target: homebrew_foo_tap.path/".git" (HOMEBREW_PREFIX/"share/man/man1/brew-tap-cmd.1").delete tap.link_completions_and_manpages @@ -437,7 +443,7 @@ def setup_completion(link:) setup_tap_files setup_git_repo setup_completion link: false - tap = described_class.new("Homebrew", "baz") + tap = described_class.fetch("Homebrew", "baz") tap.install clone_target: homebrew_foo_tap.path/".git" (HOMEBREW_PREFIX/"share/man/man1/brew-tap-cmd.1").delete (HOMEBREW_PREFIX/"etc/bash_completion.d/brew-tap-cmd").delete @@ -457,17 +463,59 @@ def setup_completion(link:) specify "#config" do setup_git_repo - expect(homebrew_foo_tap.config["foo"]).to be_nil - homebrew_foo_tap.config["foo"] = "bar" - expect(homebrew_foo_tap.config["foo"]).to eq("bar") - homebrew_foo_tap.config.delete("foo") - expect(homebrew_foo_tap.config["foo"]).to be_nil + expect(homebrew_foo_tap.config[:foo]).to be_nil + homebrew_foo_tap.config[:foo] = true + expect(homebrew_foo_tap.config[:foo]).to be true + homebrew_foo_tap.config.delete(:foo) + expect(homebrew_foo_tap.config[:foo]).to be_nil end - describe "#each" do + describe ".each" do it "returns an enumerator if no block is passed" do expect(described_class.each).to be_an_instance_of(Enumerator) end + + context "when the core tap is not installed" do + around do |example| + FileUtils.rm_rf CoreTap.instance.path + example.run + ensure + (CoreTap.instance.path/"Formula").mkpath + end + + it "includes the core tap with the api" do + ENV.delete("HOMEBREW_NO_INSTALL_FROM_API") + expect(described_class.to_a).to include(CoreTap.instance) + end + + it "omits the core tap without the api" do + ENV["HOMEBREW_NO_INSTALL_FROM_API"] = "1" + expect(described_class.to_a).not_to include(CoreTap.instance) + end + end + end + + describe ".installed" do + it "includes only installed taps" do + expect(described_class.installed) + .to contain_exactly(CoreTap.instance, described_class.fetch("homebrew/foo")) + end + end + + describe ".all" do + it "includes the core and cask taps by default", :needs_macos do + expect(described_class.all).to contain_exactly( + CoreTap.instance, + CoreCaskTap.instance, + described_class.fetch("homebrew/foo"), + described_class.fetch("third-party/tap"), + ) + end + + it "includes the core tap and excludes the cask tap by default", :needs_linux do + expect(described_class.all) + .to contain_exactly(CoreTap.instance, described_class.fetch("homebrew/foo")) + end end describe "Formula Lists" do @@ -489,6 +537,47 @@ def setup_completion(link:) end end + describe "tap migration renames" do + before do + (path/"tap_migrations.json").write <<~JSON + { + "adobe-air-sdk": "homebrew/cask", + "app-engine-go-32": "homebrew/cask/google-cloud-sdk", + "app-engine-go-64": "homebrew/cask/google-cloud-sdk", + "gimp": "homebrew/cask", + "horndis": "homebrew/cask", + "inkscape": "homebrew/cask", + "schismtracker": "homebrew/cask/schism-tracker" + } + JSON + end + + describe "#reverse_tap_migration_renames" do + it "returns the expected hash" do + expect(homebrew_foo_tap.reverse_tap_migrations_renames).to eq({ + "homebrew/cask/google-cloud-sdk" => %w[app-engine-go-32 app-engine-go-64], + "homebrew/cask/schism-tracker" => %w[schismtracker], + }) + end + end + + describe ".tap_migration_oldnames" do + let(:cask_tap) { CoreCaskTap.instance } + let(:core_tap) { CoreTap.instance } + + it "returns expected renames" do + [ + [cask_tap, "gimp", []], + [core_tap, "schism-tracker", []], + [cask_tap, "schism-tracker", %w[schismtracker]], + [cask_tap, "google-cloud-sdk", %w[app-engine-go-32 app-engine-go-64]], + ].each do |tap, name, result| + expect(described_class.tap_migration_oldnames(tap, name)).to eq(result) + end + end + end + end + describe "#audit_exceptions" do it "returns the audit_exceptions hash" do setup_tap_files @@ -531,7 +620,7 @@ def setup_completion(link:) end describe CoreTap do - subject(:core_tap) { described_class.new } + subject(:core_tap) { described_class.instance } specify "attributes" do expect(core_tap.user).to eq("Homebrew") diff --git a/Library/Homebrew/test/unpack_strategy_spec.rb b/Library/Homebrew/test/unpack_strategy_spec.rb index 7218aa6f468e15..2794f9f4889585 100644 --- a/Library/Homebrew/test/unpack_strategy_spec.rb +++ b/Library/Homebrew/test/unpack_strategy_spec.rb @@ -83,7 +83,7 @@ end it "does not pass down the basename of the archive" do - strategy.extract_nestedly(to: unpack_dir, basename: basename) + strategy.extract_nestedly(to: unpack_dir, basename:) expect(unpack_dir/"file.txt").to be_a_file end end diff --git a/Library/Homebrew/test/untap_spec.rb b/Library/Homebrew/test/untap_spec.rb new file mode 100644 index 00000000000000..e88f3d27f68e7a --- /dev/null +++ b/Library/Homebrew/test/untap_spec.rb @@ -0,0 +1,126 @@ +# frozen_string_literal: true + +require "untap" + +RSpec.describe Homebrew::Untap do + describe ".installed_formulae_for", :integration_test do + shared_examples "finds installed formulae in tap" do + def load_formula(name:, with_formula_file: false, mock_install: false) + formula = if with_formula_file + path = setup_test_formula(name, tap:) + Formulary.factory(path) + else + formula(name, tap:) do + url "https://brew.sh/#{name}-1.0.tgz" + end + end + + if mock_install + keg_path = HOMEBREW_CELLAR/name/"1.2.3" + keg_path.mkpath + + tab_path = keg_path/Tab::FILENAME + tab_path.write <<~JSON + { + "source": { + "tap": "#{tap}" + } + } + JSON + end + + formula + end + + let!(:currently_installed_formula) do + load_formula(name: "current_install", with_formula_file: true, mock_install: true) + end + + before do + # Formula that is available from a tap but not installed. + load_formula(name: "no_install", with_formula_file: true) + + # Formula that was installed from a tap but is no longer available from that tap. + load_formula(name: "legacy_install", mock_install: true) + + tap.clear_cache + end + + it "returns the expected formulae" do + expect(described_class.installed_formulae_for(tap:).map(&:full_name)) + .to eq([currently_installed_formula.full_name]) + end + end + + context "with core tap" do + let(:tap) { CoreTap.instance } + + include_examples "finds installed formulae in tap" + end + + context "with non-core tap" do + let(:tap) { Tap.fetch("homebrew", "foo") } + + before do + tap.formula_dir.mkpath + end + + include_examples "finds installed formulae in tap" + end + end + + describe ".installed_casks_for", :cask do + shared_examples "finds installed casks in tap" do + def load_cask(token:, with_cask_file: false, mock_install: false) + cask_loader = Cask::CaskLoader::FromContentLoader.new(<<~RUBY, tap:) + cask '#{token}' do + version "1.2.3" + sha256 :no_check + + url 'https://brew.sh/' + end + RUBY + + cask = cask_loader.load(config: nil) + + if with_cask_file + cask_path = tap.cask_dir/"#{token}.rb" + cask_path.parent.mkpath + cask_path.write cask.source + end + + InstallHelper.install_with_caskfile(cask) if mock_install + + cask + end + + let!(:currently_installed_cask) do + load_cask(token: "current_install", with_cask_file: true, mock_install: true) + end + + before do + # Cask that is available from a tap but not installed. + load_cask(token: "no_install", with_cask_file: true) + + # Cask that was installed from a tap but is no longer available from that tap. + load_cask(token: "legacy_install", mock_install: true) + end + + it "returns the expected casks" do + expect(described_class.installed_casks_for(tap:)).to eq([currently_installed_cask]) + end + end + + context "with core cask tap" do + let(:tap) { CoreCaskTap.instance } + + include_examples "finds installed casks in tap" + end + + context "with non-core cask tap" do + let(:tap) { Tap.fetch("homebrew", "foo") } + + include_examples "finds installed casks in tap" + end + end +end diff --git a/Library/Homebrew/test/utils/analytics_spec.rb b/Library/Homebrew/test/utils/analytics_spec.rb index dc2100336f3870..baaebc895bf05d 100644 --- a/Library/Homebrew/test/utils/analytics_spec.rb +++ b/Library/Homebrew/test/utils/analytics_spec.rb @@ -8,47 +8,47 @@ described_class.clear_cache end - describe "::default_tags_influx" do + describe "::default_package_tags" do let(:ci) { ", CI" if ENV["CI"] } it "returns OS_VERSION and prefix when HOMEBREW_PREFIX is a custom prefix on intel" do expect(Homebrew).to receive(:default_prefix?).and_return(false).at_least(:once) - expect(described_class.default_tags_influx).to have_key(:prefix) - expect(described_class.default_tags_influx[:prefix]).to eq "custom-prefix" + expect(described_class.default_package_tags).to have_key(:prefix) + expect(described_class.default_package_tags[:prefix]).to eq "custom-prefix" end it "returns OS_VERSION, ARM and prefix when HOMEBREW_PREFIX is a custom prefix on arm" do expect(Homebrew).to receive(:default_prefix?).and_return(false).at_least(:once) - expect(described_class.default_tags_influx).to have_key(:arch) - expect(described_class.default_tags_influx[:arch]).to eq HOMEBREW_PHYSICAL_PROCESSOR - expect(described_class.default_tags_influx).to have_key(:prefix) - expect(described_class.default_tags_influx[:prefix]).to eq "custom-prefix" + expect(described_class.default_package_tags).to have_key(:arch) + expect(described_class.default_package_tags[:arch]).to eq HOMEBREW_PHYSICAL_PROCESSOR + expect(described_class.default_package_tags).to have_key(:prefix) + expect(described_class.default_package_tags[:prefix]).to eq "custom-prefix" end it "returns OS_VERSION, Rosetta and prefix when HOMEBREW_PREFIX is a custom prefix on Rosetta", :needs_macos do expect(Homebrew).to receive(:default_prefix?).and_return(false).at_least(:once) - expect(described_class.default_tags_influx).to have_key(:prefix) - expect(described_class.default_tags_influx[:prefix]).to eq "custom-prefix" + expect(described_class.default_package_tags).to have_key(:prefix) + expect(described_class.default_package_tags[:prefix]).to eq "custom-prefix" end it "does not include prefix when HOMEBREW_PREFIX is the default prefix" do expect(Homebrew).to receive(:default_prefix?).and_return(true).at_least(:once) - expect(described_class.default_tags_influx).to have_key(:prefix) - expect(described_class.default_tags_influx[:prefix]).to eq HOMEBREW_PREFIX.to_s + expect(described_class.default_package_tags).to have_key(:prefix) + expect(described_class.default_package_tags[:prefix]).to eq HOMEBREW_PREFIX.to_s end it "includes CI when ENV['CI'] is set" do ENV["CI"] = "1" - expect(described_class.default_tags_influx).to have_key(:ci) + expect(described_class.default_package_tags).to have_key(:ci) end it "includes developer when ENV['HOMEBREW_DEVELOPER'] is set" do expect(Homebrew::EnvConfig).to receive(:developer?).and_return(true) - expect(described_class.default_tags_influx).to have_key(:developer) + expect(described_class.default_package_tags).to have_key(:developer) end end - describe "::report_event" do + describe "::report_package_event" do let(:f) { formula { url "foo-1.0" } } let(:package_name) { f.name } let(:tap_name) { f.tap.name } @@ -59,15 +59,15 @@ it "returns nil when HOMEBREW_NO_ANALYTICS is true" do ENV["HOMEBREW_NO_ANALYTICS"] = "true" expect(described_class).not_to receive(:report_influx) - described_class.report_event(:install, package_name: package_name, tap_name: tap_name, - on_request: on_request, options: options) + described_class.report_package_event(:install, package_name:, tap_name:, + on_request:, options:) end it "returns nil when HOMEBREW_NO_ANALYTICS_THIS_RUN is true" do ENV["HOMEBREW_NO_ANALYTICS_THIS_RUN"] = "true" expect(described_class).not_to receive(:report_influx) - described_class.report_event(:install, package_name: package_name, tap_name: tap_name, - on_request: on_request, options: options) + described_class.report_package_event(:install, package_name:, tap_name:, + on_request:, options:) end it "returns nil when HOMEBREW_ANALYTICS_DEBUG is true" do @@ -76,8 +76,8 @@ ENV["HOMEBREW_ANALYTICS_DEBUG"] = "true" expect(described_class).to receive(:report_influx) - described_class.report_event(:install, package_name: package_name, tap_name: tap_name, - on_request: on_request, options: options) + described_class.report_package_event(:install, package_name:, tap_name:, + on_request:, options:) end end @@ -85,16 +85,16 @@ ENV.delete("HOMEBREW_NO_ANALYTICS_THIS_RUN") ENV.delete("HOMEBREW_NO_ANALYTICS") ENV["HOMEBREW_ANALYTICS_DEBUG"] = "true" - expect(described_class).to receive(:report_influx).with(:install, hash_including(package_name: package_name, - on_request: on_request)).once - described_class.report_event(:install, package_name: package_name, tap_name: tap_name, - on_request: on_request, options: options) + expect(described_class).to receive(:report_influx).with(:install, hash_including(on_request:), + hash_including(package: package_name)).once + described_class.report_package_event(:install, package_name:, tap_name:, + on_request:, options:) end end describe "::report_influx" do let(:f) { formula { url "foo-1.0" } } - let(:package_name) { f.name } + let(:package) { f.name } let(:tap_name) { f.tap.name } let(:on_request) { false } let(:options) { "--HEAD" } @@ -104,8 +104,7 @@ ENV.delete("HOMEBREW_NO_ANALYTICS") ENV["HOMEBREW_ANALYTICS_DEBUG"] = "true" expect(described_class).to receive(:deferred_curl).once - described_class.report_influx(:install, package_name: package_name, tap_name: tap_name, on_request: on_request, -options: options) + described_class.report_influx(:install, { on_request: }, { package:, tap_name: }) end end @@ -116,13 +115,13 @@ it "reports event if BuildError raised for a formula with a public remote repository" do allow_any_instance_of(Tap).to receive(:custom_remote?).and_return(false) - expect(described_class).to respond_to(:report_event) + expect(described_class).to respond_to(:report_package_event) described_class.report_build_error(err) end it "does not report event if BuildError raised for a formula with a private remote repository" do allow_any_instance_of(Tap).to receive(:private?).and_return(true) - expect(described_class).not_to receive(:report_event) + expect(described_class).not_to receive(:report_package_event) described_class.report_build_error(err) end end @@ -132,7 +131,7 @@ let(:f) { instance_double(Formula, name: "foo", path: "blah", tap: nil) } it "does not report event if BuildError is raised" do - expect(described_class).not_to receive(:report_event) + expect(described_class).not_to receive(:report_package_event) described_class.report_build_error(err) end end @@ -143,7 +142,7 @@ it "does not report event if BuildError is raised" do allow_any_instance_of(Pathname).to receive(:directory?).and_return(false) - expect(described_class).not_to receive(:report_event) + expect(described_class).not_to receive(:report_package_event) described_class.report_build_error(err) end end diff --git a/Library/Homebrew/test/utils/bottles/bottles_spec.rb b/Library/Homebrew/test/utils/bottles/bottles_spec.rb index 6a46d30ccd679e..c2299804980ed8 100644 --- a/Library/Homebrew/test/utils/bottles/bottles_spec.rb +++ b/Library/Homebrew/test/utils/bottles/bottles_spec.rb @@ -19,7 +19,7 @@ before do # setup a testball1 dep_name = "testball1" - dep_path = CoreTap.new.new_formula_path(dep_name) + dep_path = CoreTap.instance.new_formula_path(dep_name) dep_path.write <<~RUBY class #{Formulary.class_s(dep_name)} < Formula url "testball1" @@ -30,7 +30,7 @@ class #{Formulary.class_s(dep_name)} < Formula # setup a testball2, that depends on testball1 formula_name = "testball2" - formula_path = CoreTap.new.new_formula_path(formula_name) + formula_path = CoreTap.instance.new_formula_path(formula_name) formula_path.write <<~RUBY class #{Formulary.class_s(formula_name)} < Formula url "testball2" diff --git a/Library/Homebrew/test/utils/gzip_spec.rb b/Library/Homebrew/test/utils/gzip_spec.rb index 9412f756b07e0e..59540a1675df40 100644 --- a/Library/Homebrew/test/utils/gzip_spec.rb +++ b/Library/Homebrew/test/utils/gzip_spec.rb @@ -16,8 +16,8 @@ File.write(somefile, file_content) mkdir path/"subdir" - expect(described_class.compress_with_options(somefile, mtime: mtime, orig_name: orig_name, -output: output)).to eq(output) + expect(described_class.compress_with_options(somefile, mtime:, orig_name:, +output:)).to eq(output) expect(Digest::SHA256.hexdigest(File.read(output))).to eq(expected_checksum) end end @@ -63,7 +63,7 @@ files = (0..2).map { |n| path/"somefile#{n}" } files.each { |f| File.write(f, "Hello world") } - results = described_class.compress(*files, mtime: mtime) + results = described_class.compress(*files, mtime:) 3.times do |n| expect(results[n].to_s).to eq("#{files[n]}.gz") expect(Digest::SHA256.hexdigest(File.read(results[n]))).to eq(expected_checksums[n]) diff --git a/Library/Homebrew/test_runner_formula.rb b/Library/Homebrew/test_runner_formula.rb index 2c5c0d275520a7..e3c3c987d6889b 100644 --- a/Library/Homebrew/test_runner_formula.rb +++ b/Library/Homebrew/test_runner_formula.rb @@ -100,10 +100,10 @@ def dependents(platform:, arch:, macos_version:) os = macos_version || platform arch = SIMULATE_SYSTEM_SYMBOLS.fetch(arch) - Homebrew::SimulateSystem.with os: os, arch: arch do + Homebrew::SimulateSystem.with(os:, arch:) do Formula.public_send(formula_selector) .select { |candidate_f| candidate_f.deps.map(&:name).include?(name) } - .map { |f| TestRunnerFormula.new(f, eval_all: eval_all) } + .map { |f| TestRunnerFormula.new(f, eval_all:) } .freeze end end diff --git a/Library/Homebrew/uninstall.rb b/Library/Homebrew/uninstall.rb index 73578c5ce288f6..b3e807b6009782 100644 --- a/Library/Homebrew/uninstall.rb +++ b/Library/Homebrew/uninstall.rb @@ -10,9 +10,9 @@ module Homebrew module Uninstall def self.uninstall_kegs(kegs_by_rack, casks: [], force: false, ignore_dependencies: false, named_args: []) handle_unsatisfied_dependents(kegs_by_rack, - casks: casks, - ignore_dependencies: ignore_dependencies, - named_args: named_args) + casks:, + ignore_dependencies:, + named_args:) return if Homebrew.failed? kegs_by_rack.each do |rack, kegs| @@ -99,19 +99,19 @@ def self.handle_unsatisfied_dependents(kegs_by_rack, casks: [], ignore_dependenc return if ignore_dependencies all_kegs = kegs_by_rack.values.flatten(1) - check_for_dependents(all_kegs, casks: casks, named_args: named_args) + check_for_dependents(all_kegs, casks:, named_args:) rescue MethodDeprecatedError # Silently ignore deprecations when uninstalling. nil end def self.check_for_dependents(kegs, casks: [], named_args: []) - return false unless (result = InstalledDependents.find_some_installed_dependents(kegs, casks: casks)) + return false unless (result = InstalledDependents.find_some_installed_dependents(kegs, casks:)) if Homebrew::EnvConfig.developer? - DeveloperDependentsMessage.new(*result, named_args: named_args).output + DeveloperDependentsMessage.new(*result, named_args:).output else - NondeveloperDependentsMessage.new(*result, named_args: named_args).output + NondeveloperDependentsMessage.new(*result, named_args:).output end true diff --git a/Library/Homebrew/unlink.rb b/Library/Homebrew/unlink.rb index 45880161f0c4ff..73ce64081690d0 100644 --- a/Library/Homebrew/unlink.rb +++ b/Library/Homebrew/unlink.rb @@ -11,12 +11,12 @@ def self.unlink_versioned_formulae(formula, verbose: false) .filter_map(&:any_installed_keg) .select(&:directory?) .each do |keg| - unlink(keg, verbose: verbose) + unlink(keg, verbose:) end end def self.unlink(keg, dry_run: false, verbose: false) - options = { dry_run: dry_run, verbose: verbose } + options = { dry_run:, verbose: } keg.lock do print "Unlinking #{keg}... " diff --git a/Library/Homebrew/unpack_strategy.rb b/Library/Homebrew/unpack_strategy.rb index a464deb6e86062..3ce46060d3317b 100644 --- a/Library/Homebrew/unpack_strategy.rb +++ b/Library/Homebrew/unpack_strategy.rb @@ -87,7 +87,7 @@ def self.detect(path, prioritize_extension: false, type: nil, ref_type: nil, ref strategy ||= Uncompressed - strategy.new(path, ref_type: ref_type, ref: ref, merge_xattrs: merge_xattrs) + strategy.new(path, ref_type:, ref:, merge_xattrs:) end attr_reader :path, :merge_xattrs @@ -113,7 +113,7 @@ def extract(to: nil, basename: nil, verbose: false) basename ||= path.basename unpack_dir = Pathname(to || Dir.pwd).expand_path unpack_dir.mkpath - extract_to_dir(unpack_dir, basename: Pathname(basename), verbose: verbose) + extract_to_dir(unpack_dir, basename: Pathname(basename), verbose:) end sig { @@ -128,14 +128,14 @@ def extract_nestedly(to: nil, basename: nil, verbose: false, prioritize_extensio Dir.mktmpdir("homebrew-unpack", HOMEBREW_TEMP) do |tmp_unpack_dir| tmp_unpack_dir = Pathname(tmp_unpack_dir) - extract(to: tmp_unpack_dir, basename: basename, verbose: verbose) + extract(to: tmp_unpack_dir, basename:, verbose:) children = tmp_unpack_dir.children if children.size == 1 && !children.fetch(0).directory? - s = UnpackStrategy.detect(children.first, prioritize_extension: prioritize_extension) + s = UnpackStrategy.detect(children.first, prioritize_extension:) - s.extract_nestedly(to: to, verbose: verbose, prioritize_extension: prioritize_extension) + s.extract_nestedly(to:, verbose:, prioritize_extension:) next end @@ -144,10 +144,10 @@ def extract_nestedly(to: nil, basename: nil, verbose: false, prioritize_extensio each_directory(tmp_unpack_dir) do |path| next if path.writable? - FileUtils.chmod "u+w", path, verbose: verbose + FileUtils.chmod "u+w", path, verbose: end - Directory.new(tmp_unpack_dir).extract(to: to, verbose: verbose) + Directory.new(tmp_unpack_dir).extract(to:, verbose:) end end diff --git a/Library/Homebrew/unpack_strategy/air.rb b/Library/Homebrew/unpack_strategy/air.rb index ca0137e872f795..c4a6ba601a8b5b 100644 --- a/Library/Homebrew/unpack_strategy/air.rb +++ b/Library/Homebrew/unpack_strategy/air.rb @@ -31,7 +31,7 @@ def dependencies def extract_to_dir(unpack_dir, basename:, verbose:) system_command! AIR_APPLICATION_INSTALLER, args: ["-silent", "-location", unpack_dir, path], - verbose: verbose + verbose: end end end diff --git a/Library/Homebrew/unpack_strategy/bzip2.rb b/Library/Homebrew/unpack_strategy/bzip2.rb index 26eeaa784e3a89..af1248c466f539 100644 --- a/Library/Homebrew/unpack_strategy/bzip2.rb +++ b/Library/Homebrew/unpack_strategy/bzip2.rb @@ -23,7 +23,7 @@ def extract_to_dir(unpack_dir, basename:, verbose:) quiet_flags = verbose ? [] : ["-q"] system_command! "bunzip2", args: [*quiet_flags, unpack_dir/basename], - verbose: verbose + verbose: end end end diff --git a/Library/Homebrew/unpack_strategy/cab.rb b/Library/Homebrew/unpack_strategy/cab.rb index a7038df4d0082d..af73d82fdd008a 100644 --- a/Library/Homebrew/unpack_strategy/cab.rb +++ b/Library/Homebrew/unpack_strategy/cab.rb @@ -20,7 +20,7 @@ def extract_to_dir(unpack_dir, basename:, verbose:) system_command! "cabextract", args: ["-d", unpack_dir, "--", path], env: { "PATH" => PATH.new(Formula["cabextract"].opt_bin, ENV.fetch("PATH")) }, - verbose: verbose + verbose: end def dependencies diff --git a/Library/Homebrew/unpack_strategy/directory.rb b/Library/Homebrew/unpack_strategy/directory.rb index 4a36198426d1e1..90b5ade18e7722 100644 --- a/Library/Homebrew/unpack_strategy/directory.rb +++ b/Library/Homebrew/unpack_strategy/directory.rb @@ -23,7 +23,7 @@ def extract_to_dir(unpack_dir, basename:, verbose:) system_command! "cp", args: ["-pR", (child.directory? && !child.symlink?) ? "#{child}/." : child, unpack_dir/child.basename], - verbose: verbose + verbose: end end end diff --git a/Library/Homebrew/unpack_strategy/dmg.rb b/Library/Homebrew/unpack_strategy/dmg.rb index 0251c726bf1b37..c207e58edd08f0 100644 --- a/Library/Homebrew/unpack_strategy/dmg.rb +++ b/Library/Homebrew/unpack_strategy/dmg.rb @@ -91,7 +91,7 @@ def eject(verbose: false) "diskutil", args: ["info", "-plist", path], print_stderr: false, - verbose: verbose, + verbose:, ) # For HFS, just use @@ -105,13 +105,13 @@ def eject(verbose: false) system_command! "diskutil", args: ["eject", eject_path], print_stderr: false, - verbose: verbose + verbose: end else system_command! "diskutil", args: ["unmount", "force", path], print_stderr: false, - verbose: verbose + verbose: end rescue ErrorDuringExecution => e raise e if (tries -= 1).zero? @@ -144,12 +144,12 @@ def extract_to_dir(unpack_dir, basename:, verbose:) system_command! "mkbom", args: ["-s", "-i", filelist.path, "--", bomfile.path], - verbose: verbose + verbose: end - system_command! "ditto", + system_command!("ditto", args: ["--bom", bomfile.path, "--", path, unpack_dir], - verbose: verbose + verbose:) FileUtils.chmod "u+w", Pathname.glob(unpack_dir/"**/*", File::FNM_DOTMATCH).reject(&:symlink?) end @@ -171,11 +171,11 @@ def self.can_extract?(path) sig { override.params(unpack_dir: Pathname, basename: Pathname, verbose: T::Boolean).returns(T.untyped) } def extract_to_dir(unpack_dir, basename:, verbose:) - mount(verbose: verbose) do |mounts| + mount(verbose:) do |mounts| raise "No mounts found in '#{path}'; perhaps this is a bad disk image?" if mounts.empty? mounts.each do |mount| - mount.extract(to: unpack_dir, verbose: verbose) + mount.extract(to: unpack_dir, verbose:) end end end @@ -192,7 +192,7 @@ def mount(verbose: false) ], input: "qn\n", print_stderr: false, - verbose: verbose, + verbose:, ) # If mounting without agreeing to EULA succeeded, there is none. @@ -208,7 +208,7 @@ def mount(verbose: false) args: [ "convert", *quiet_flag, "-format", "UDTO", "-o", cdr_path, path ], - verbose: verbose, + verbose:, ) with_eula = system_command!( @@ -217,7 +217,7 @@ def mount(verbose: false) "attach", "-plist", "-nobrowse", "-readonly", "-mountrandom", mount_dir, cdr_path ], - verbose: verbose, + verbose:, ) if verbose && !(eula_text = without_eula.stdout).empty? @@ -239,7 +239,7 @@ def mount(verbose: false) yield mounts ensure mounts.each do |mount| - mount.eject(verbose: verbose) + mount.eject(verbose:) end end end diff --git a/Library/Homebrew/unpack_strategy/fossil.rb b/Library/Homebrew/unpack_strategy/fossil.rb index beeeae8f9b2635..1e2dcc00a8871a 100644 --- a/Library/Homebrew/unpack_strategy/fossil.rb +++ b/Library/Homebrew/unpack_strategy/fossil.rb @@ -36,7 +36,7 @@ def extract_to_dir(unpack_dir, basename:, verbose:) args: ["open", path, *args], chdir: unpack_dir, env: { "PATH" => PATH.new(Formula["fossil"].opt_bin, ENV.fetch("PATH")) }, - verbose: verbose + verbose: end end end diff --git a/Library/Homebrew/unpack_strategy/generic_unar.rb b/Library/Homebrew/unpack_strategy/generic_unar.rb index c537f5efca98c4..0aee0ce3ac347a 100644 --- a/Library/Homebrew/unpack_strategy/generic_unar.rb +++ b/Library/Homebrew/unpack_strategy/generic_unar.rb @@ -29,7 +29,7 @@ def extract_to_dir(unpack_dir, basename:, verbose:) "-output-directory", unpack_dir, "--", path ], env: { "PATH" => PATH.new(Formula["unar"].opt_bin, ENV.fetch("PATH")) }, - verbose: verbose + verbose: end end end diff --git a/Library/Homebrew/unpack_strategy/gzip.rb b/Library/Homebrew/unpack_strategy/gzip.rb index 22bdf338816870..2ece0befdc4568 100644 --- a/Library/Homebrew/unpack_strategy/gzip.rb +++ b/Library/Homebrew/unpack_strategy/gzip.rb @@ -23,7 +23,7 @@ def extract_to_dir(unpack_dir, basename:, verbose:) quiet_flags = verbose ? [] : ["-q"] system_command! "gunzip", args: [*quiet_flags, "-N", "--", unpack_dir/basename], - verbose: verbose + verbose: end end end diff --git a/Library/Homebrew/unpack_strategy/lha.rb b/Library/Homebrew/unpack_strategy/lha.rb index ee26437eaa5eea..1da3021ad70d4d 100644 --- a/Library/Homebrew/unpack_strategy/lha.rb +++ b/Library/Homebrew/unpack_strategy/lha.rb @@ -26,7 +26,7 @@ def extract_to_dir(unpack_dir, basename:, verbose:) system_command! "lha", args: ["xq2w=#{unpack_dir}", path], env: { "PATH" => PATH.new(Formula["lha"].opt_bin, ENV.fetch("PATH")) }, - verbose: verbose + verbose: end end end diff --git a/Library/Homebrew/unpack_strategy/lzip.rb b/Library/Homebrew/unpack_strategy/lzip.rb index 8925de24e33532..668aa4fdcfc18b 100644 --- a/Library/Homebrew/unpack_strategy/lzip.rb +++ b/Library/Homebrew/unpack_strategy/lzip.rb @@ -28,7 +28,7 @@ def extract_to_dir(unpack_dir, basename:, verbose:) system_command! "lzip", args: ["-d", *quiet_flags, unpack_dir/basename], env: { "PATH" => PATH.new(Formula["lzip"].opt_bin, ENV.fetch("PATH")) }, - verbose: verbose + verbose: end end end diff --git a/Library/Homebrew/unpack_strategy/lzma.rb b/Library/Homebrew/unpack_strategy/lzma.rb index 11e7bdc6645ae6..d529e2de4c4f35 100644 --- a/Library/Homebrew/unpack_strategy/lzma.rb +++ b/Library/Homebrew/unpack_strategy/lzma.rb @@ -28,7 +28,7 @@ def extract_to_dir(unpack_dir, basename:, verbose:) system_command! "unlzma", args: [*quiet_flags, "--", unpack_dir/basename], env: { "PATH" => PATH.new(Formula["xz"].opt_bin, ENV.fetch("PATH")) }, - verbose: verbose + verbose: end end end diff --git a/Library/Homebrew/unpack_strategy/mercurial.rb b/Library/Homebrew/unpack_strategy/mercurial.rb index 72d954793325ca..c4a77d4d0df0fc 100644 --- a/Library/Homebrew/unpack_strategy/mercurial.rb +++ b/Library/Homebrew/unpack_strategy/mercurial.rb @@ -16,7 +16,7 @@ def extract_to_dir(unpack_dir, basename:, verbose:) system_command! "hg", args: ["--cwd", path, "archive", "--subrepos", "-y", "-t", "files", unpack_dir], env: { "PATH" => PATH.new(Formula["mercurial"].opt_bin, ENV.fetch("PATH")) }, - verbose: verbose + verbose: end end end diff --git a/Library/Homebrew/unpack_strategy/p7zip.rb b/Library/Homebrew/unpack_strategy/p7zip.rb index fb32908f2ded46..19e0154491d597 100644 --- a/Library/Homebrew/unpack_strategy/p7zip.rb +++ b/Library/Homebrew/unpack_strategy/p7zip.rb @@ -26,7 +26,7 @@ def extract_to_dir(unpack_dir, basename:, verbose:) system_command! "7zr", args: ["x", "-y", "-bd", "-bso0", path, "-o#{unpack_dir}"], env: { "PATH" => PATH.new(Formula["p7zip"].opt_bin, ENV.fetch("PATH")) }, - verbose: verbose + verbose: end end end diff --git a/Library/Homebrew/unpack_strategy/pax.rb b/Library/Homebrew/unpack_strategy/pax.rb index cd16295c5b89ce..9a47b9d1d531b8 100644 --- a/Library/Homebrew/unpack_strategy/pax.rb +++ b/Library/Homebrew/unpack_strategy/pax.rb @@ -22,7 +22,7 @@ def extract_to_dir(unpack_dir, basename:, verbose:) system_command! "pax", args: ["-rf", path], chdir: unpack_dir, - verbose: verbose + verbose: end end end diff --git a/Library/Homebrew/unpack_strategy/rar.rb b/Library/Homebrew/unpack_strategy/rar.rb index 81ba9d495b0560..289da9134c480b 100644 --- a/Library/Homebrew/unpack_strategy/rar.rb +++ b/Library/Homebrew/unpack_strategy/rar.rb @@ -26,7 +26,7 @@ def extract_to_dir(unpack_dir, basename:, verbose:) system_command! "bsdtar", args: ["x", "-f", path, "-C", unpack_dir], env: { "PATH" => PATH.new(Formula["libarchive"].opt_bin, ENV.fetch("PATH")) }, - verbose: verbose + verbose: end end end diff --git a/Library/Homebrew/unpack_strategy/subversion.rb b/Library/Homebrew/unpack_strategy/subversion.rb index 4097f13610ef58..7ba74fa5e0f0bd 100644 --- a/Library/Homebrew/unpack_strategy/subversion.rb +++ b/Library/Homebrew/unpack_strategy/subversion.rb @@ -16,7 +16,7 @@ def extract_to_dir(unpack_dir, basename:, verbose:) system_command! "svn", args: ["export", "--force", ".", unpack_dir], chdir: path.to_s, - verbose: verbose + verbose: end end end diff --git a/Library/Homebrew/unpack_strategy/tar.rb b/Library/Homebrew/unpack_strategy/tar.rb index 3062f5a12245d3..53ff36715cbf04 100644 --- a/Library/Homebrew/unpack_strategy/tar.rb +++ b/Library/Homebrew/unpack_strategy/tar.rb @@ -48,7 +48,7 @@ def extract_to_dir(unpack_dir, basename:, verbose:) args: ["--extract", "--no-same-owner", "--file", tar_path, "--directory", unpack_dir], - verbose: verbose + verbose: end end @@ -56,7 +56,7 @@ def extract_to_dir(unpack_dir, basename:, verbose:) params(extractor: T.any(T.class_of(Xz), T.class_of(Zstd)), dir: Pathname, verbose: T::Boolean).returns(Pathname) } def subextract(extractor, dir, verbose) - extractor.new(path).extract(to: dir, verbose: verbose) + extractor.new(path).extract(to: dir, verbose:) T.must(dir.children.first) end end diff --git a/Library/Homebrew/unpack_strategy/uncompressed.rb b/Library/Homebrew/unpack_strategy/uncompressed.rb index 6cb24becaaa017..4d4e6896fa75b2 100644 --- a/Library/Homebrew/unpack_strategy/uncompressed.rb +++ b/Library/Homebrew/unpack_strategy/uncompressed.rb @@ -15,14 +15,14 @@ class Uncompressed ).returns(T.untyped) } def extract_nestedly(to: nil, basename: nil, verbose: false, prioritize_extension: false) - extract(to: to, basename: basename, verbose: verbose) + extract(to:, basename:, verbose:) end private sig { override.params(unpack_dir: Pathname, basename: Pathname, verbose: T::Boolean).returns(T.untyped) } def extract_to_dir(unpack_dir, basename:, verbose: false) - FileUtils.cp path, unpack_dir/basename, preserve: true, verbose: verbose + FileUtils.cp path, unpack_dir/basename, preserve: true, verbose: end end end diff --git a/Library/Homebrew/unpack_strategy/xar.rb b/Library/Homebrew/unpack_strategy/xar.rb index e1f0649ccb1f61..f473d35c790991 100644 --- a/Library/Homebrew/unpack_strategy/xar.rb +++ b/Library/Homebrew/unpack_strategy/xar.rb @@ -21,7 +21,7 @@ def self.can_extract?(path) def extract_to_dir(unpack_dir, basename:, verbose:) system_command! "xar", args: ["-x", "-f", path, "-C", unpack_dir], - verbose: verbose + verbose: end end end diff --git a/Library/Homebrew/unpack_strategy/xz.rb b/Library/Homebrew/unpack_strategy/xz.rb index be6b7ca55fc494..7ac0ceb4e6c387 100644 --- a/Library/Homebrew/unpack_strategy/xz.rb +++ b/Library/Homebrew/unpack_strategy/xz.rb @@ -28,7 +28,7 @@ def extract_to_dir(unpack_dir, basename:, verbose:) system_command! "unxz", args: [*quiet_flags, "-T0", "--", unpack_dir/basename], env: { "PATH" => PATH.new(Formula["xz"].opt_bin, ENV.fetch("PATH")) }, - verbose: verbose + verbose: end end end diff --git a/Library/Homebrew/unpack_strategy/zip.rb b/Library/Homebrew/unpack_strategy/zip.rb index c4c5fd301ed4fc..dc4d6d350b5b9c 100644 --- a/Library/Homebrew/unpack_strategy/zip.rb +++ b/Library/Homebrew/unpack_strategy/zip.rb @@ -36,7 +36,7 @@ def extract_to_dir(unpack_dir, basename:, verbose:) result = system_command! "unzip", args: [*quiet_flags, "-o", path, "-d", unpack_dir], env: { "PATH" => PATH.new(unzip&.opt_bin, ENV.fetch("PATH")) }, - verbose: verbose, + verbose:, print_stderr: false FileUtils.rm_rf unpack_dir/"__MACOSX" diff --git a/Library/Homebrew/unpack_strategy/zstd.rb b/Library/Homebrew/unpack_strategy/zstd.rb index 0e519604721545..f8cdacb0abec32 100644 --- a/Library/Homebrew/unpack_strategy/zstd.rb +++ b/Library/Homebrew/unpack_strategy/zstd.rb @@ -28,7 +28,7 @@ def extract_to_dir(unpack_dir, basename:, verbose:) system_command! "unzstd", args: [*quiet_flags, "-T0", "--rm", "--", unpack_dir/basename], env: { "PATH" => PATH.new(Formula["zstd"].opt_bin, ENV.fetch("PATH")) }, - verbose: verbose + verbose: end end end diff --git a/Library/Homebrew/untap.rb b/Library/Homebrew/untap.rb new file mode 100644 index 00000000000000..3a856f2a9109c6 --- /dev/null +++ b/Library/Homebrew/untap.rb @@ -0,0 +1,60 @@ +# typed: true +# frozen_string_literal: true + +require "extend/cachable" + +module Homebrew + # Helpers for the `brew untap` command. + # @api private + module Untap + extend Cachable + + # All installed formulae currently available in a tap by formula full name. + sig { params(tap: Tap).returns(T::Array[Formula]) } + def self.installed_formulae_for(tap:) + tap.formula_names.filter_map do |formula_name| + next unless installed_formulae_names.include?(T.must(formula_name.split("/").last)) + + formula = begin + Formulary.factory(formula_name) + rescue FormulaUnavailableError + # Don't blow up because of a single unavailable formula. + next + end + + # Can't use Formula#any_version_installed? because it doesn't consider + # taps correctly. + formula if formula.installed_kegs.any? { |keg| keg.tab.tap == tap } + end + end + + sig { returns(T::Set[String]) } + def self.installed_formulae_names + cache[:installed_formulae_names] ||= Formula.installed_formula_names.to_set.freeze + end + private_class_method :installed_formulae_names + + # All installed casks currently available in a tap by cask full name. + sig { params(tap: Tap).returns(T::Array[Cask::Cask]) } + def self.installed_casks_for(tap:) + tap.cask_tokens.filter_map do |cask_token| + next unless installed_cask_tokens.include?(T.must(cask_token.split("/").last)) + + cask = begin + Cask::CaskLoader.load(cask_token) + rescue Cask::CaskUnavailableError + # Don't blow up because of a single unavailable cask. + next + end + + cask if cask.installed? + end + end + + sig { returns(T::Set[String]) } + def self.installed_cask_tokens + cache[:installed_cask_tokens] ||= Cask::Caskroom.tokens.to_set.freeze + end + private_class_method :installed_cask_tokens + end +end diff --git a/Library/Homebrew/upgrade.rb b/Library/Homebrew/upgrade.rb index 5fc1ea71e810d7..8116728fd0ed8a 100644 --- a/Library/Homebrew/upgrade.rb +++ b/Library/Homebrew/upgrade.rb @@ -27,6 +27,7 @@ def upgrade_formulae( keep_tmp: false, debug_symbols: false, force: false, + overwrite: false, debug: false, quiet: false, verbose: false @@ -53,21 +54,22 @@ def upgrade_formulae( end formula_installers = formulae_to_install.filter_map do |formula| - Migrator.migrate_if_needed(formula, force: force, dry_run: dry_run) + Migrator.migrate_if_needed(formula, force:, dry_run:) begin fi = create_formula_installer( formula, - flags: flags, - installed_on_request: installed_on_request, - force_bottle: force_bottle, - build_from_source_formulae: build_from_source_formulae, - interactive: interactive, - keep_tmp: keep_tmp, - debug_symbols: debug_symbols, - force: force, - debug: debug, - quiet: quiet, - verbose: verbose, + flags:, + installed_on_request:, + force_bottle:, + build_from_source_formulae:, + interactive:, + keep_tmp:, + debug_symbols:, + force:, + overwrite:, + debug:, + quiet:, + verbose:, ) unless dry_run fi.prelude @@ -117,8 +119,8 @@ def upgrade_formulae( end formula_installers.each do |fi| - upgrade_formula(fi, dry_run: dry_run, verbose: verbose) - Cleanup.install_formula_clean!(fi.formula, dry_run: dry_run) + upgrade_formula(fi, dry_run:, verbose:) + Cleanup.install_formula_clean!(fi.formula, dry_run:) end end @@ -150,6 +152,7 @@ def create_formula_installer( keep_tmp: false, debug_symbols: false, force: false, + overwrite: false, debug: false, quiet: false, verbose: false @@ -173,20 +176,21 @@ def create_formula_installer( FormulaInstaller.new( formula, **{ - options: options, + options:, link_keg: keg_had_linked_opt ? keg_was_linked : nil, installed_as_dependency: tab&.installed_as_dependency, installed_on_request: installed_on_request || tab&.installed_on_request, build_bottle: tab&.built_bottle?, - force_bottle: force_bottle, - build_from_source_formulae: build_from_source_formulae, - interactive: interactive, - keep_tmp: keep_tmp, - debug_symbols: debug_symbols, - force: force, - debug: debug, - quiet: quiet, - verbose: verbose, + force_bottle:, + build_from_source_formulae:, + interactive:, + keep_tmp:, + debug_symbols:, + force:, + overwrite:, + debug:, + quiet:, + verbose:, }.compact, ) end @@ -209,7 +213,7 @@ def upgrade_formula(formula_installer, dry_run: false, verbose: false) install_formula(formula_installer, upgrade: true) rescue BuildError => e - e.dump(verbose: verbose) + e.dump(verbose:) puts Homebrew.failed = true end @@ -366,18 +370,18 @@ def check_installed_dependents( unless dry_run upgrade_formulae( upgradeable_dependents, - flags: flags, - installed_on_request: installed_on_request, - force_bottle: force_bottle, - build_from_source_formulae: build_from_source_formulae, + flags:, + installed_on_request:, + force_bottle:, + build_from_source_formulae:, dependents: true, - interactive: interactive, - keep_tmp: keep_tmp, - debug_symbols: debug_symbols, - force: force, - debug: debug, - quiet: quiet, - verbose: verbose, + interactive:, + keep_tmp:, + debug_symbols:, + force:, + debug:, + quiet:, + verbose:, ) end @@ -436,16 +440,16 @@ def check_installed_dependents( reinstallable_broken_dependents.each do |formula| Homebrew.reinstall_formula( formula, - flags: flags, - force_bottle: force_bottle, + flags:, + force_bottle:, build_from_source_formulae: build_from_source_formulae + [formula.full_name], - interactive: interactive, - keep_tmp: keep_tmp, - debug_symbols: debug_symbols, - force: force, - debug: debug, - quiet: quiet, - verbose: verbose, + interactive:, + keep_tmp:, + debug_symbols:, + force:, + debug:, + quiet:, + verbose:, ) rescue FormulaInstallationAlreadyAttemptedError # We already attempted to reinstall f as part of the dependency tree of @@ -454,7 +458,7 @@ def check_installed_dependents( rescue CannotInstallFormulaError, DownloadError => e ofail e rescue BuildError => e - e.dump(verbose: verbose) + e.dump(verbose:) puts Homebrew.failed = true end diff --git a/Library/Homebrew/utils.rb b/Library/Homebrew/utils.rb index 9d2fd24455c3e6..4d06ee05b563cb 100644 --- a/Library/Homebrew/utils.rb +++ b/Library/Homebrew/utils.rb @@ -80,7 +80,7 @@ def self.inject_dump_stats!(the_module, pattern) at_exit do col_width = [$times.keys.map(&:size).max.to_i + 2, 15].max $times.sort_by { |_k, v| v }.each do |method, time| - puts format("%-#{col_width}s %