From d8b0a130f10d724b409ad25c44c36d05405486e9 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Sat, 2 Jul 2022 10:09:25 +0200 Subject: [PATCH 001/138] Minor documentation changes --- Library/Homebrew/livecheck.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Library/Homebrew/livecheck.rb b/Library/Homebrew/livecheck.rb index 52a76e8425..3098673d66 100644 --- a/Library/Homebrew/livecheck.rb +++ b/Library/Homebrew/livecheck.rb @@ -1,7 +1,7 @@ # typed: true # frozen_string_literal: true -# The {Livecheck} class implements the DSL methods used in a formula's or cask's +# The {Livecheck} class implements the DSL methods used in a formula's, cask's or resource's # `livecheck` block and stores related instance variables. Most of these methods # also return the related instance variable when no argument is provided. # @@ -11,13 +11,13 @@ class Livecheck extend Forwardable - # A very brief description of why the formula/cask is skipped (e.g. `No longer + # A very brief description of why the formula/cask/resource is skipped (e.g. `No longer # developed or maintained`). # @return [String, nil] attr_reader :skip_msg - def initialize(formula_or_cask) - @formula_or_cask = formula_or_cask + def initialize(package_or_resource) + @package_or_resource = package_or_resource @referenced_cask_name = nil @referenced_formula_name = nil @regex = nil From e1098765f64662b5bca40fd5e1d36de4827afacb Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Sat, 2 Jul 2022 10:20:11 +0200 Subject: [PATCH 002/138] Minor fix for `brew style` --- Library/Homebrew/test/resource_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Library/Homebrew/test/resource_spec.rb b/Library/Homebrew/test/resource_spec.rb index 9758b376b9..ed34c294ed 100644 --- a/Library/Homebrew/test/resource_spec.rb +++ b/Library/Homebrew/test/resource_spec.rb @@ -6,7 +6,7 @@ require "livecheck" describe Resource do subject(:resource) { described_class.new("test") } - + let(:livecheck_resource) { described_class.new do url "https://brew.sh/test-0.0.1.tgz" From 04981d5387d97956101f85b69edc6cf87368c899 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Sat, 2 Jul 2022 10:09:25 +0200 Subject: [PATCH 003/138] Minor documentation changes --- Library/Homebrew/livecheck.rb | 26 ++++++++++++++------------ Library/Homebrew/test/resource_spec.rb | 2 +- 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/Library/Homebrew/livecheck.rb b/Library/Homebrew/livecheck.rb index 52a76e8425..66abd5142f 100644 --- a/Library/Homebrew/livecheck.rb +++ b/Library/Homebrew/livecheck.rb @@ -1,9 +1,10 @@ # typed: true # frozen_string_literal: true -# The {Livecheck} class implements the DSL methods used in a formula's or cask's -# `livecheck` block and stores related instance variables. Most of these methods -# also return the related instance variable when no argument is provided. +# The {Livecheck} class implements the DSL methods used in a formula's, cask's +# or resource's `livecheck` block and stores related instance variables. Most +# of these methods also return the related instance variable when no argument +# is provided. # # This information is used by the `brew livecheck` command to control its # behavior. Example `livecheck` blocks can be found in the @@ -11,13 +12,13 @@ class Livecheck extend Forwardable - # A very brief description of why the formula/cask is skipped (e.g. `No longer - # developed or maintained`). + # A very brief description of why the formula/cask/resource is skipped (e.g. + # `No longer developed or maintained`). # @return [String, nil] attr_reader :skip_msg - def initialize(formula_or_cask) - @formula_or_cask = formula_or_cask + def initialize(package_or_resource) + @package_or_resource = package_or_resource @referenced_cask_name = nil @referenced_formula_name = nil @regex = nil @@ -81,8 +82,9 @@ class Livecheck # Sets the `@skip` instance variable to `true` and sets the `@skip_msg` # instance variable if a `String` is provided. `@skip` is used to indicate - # that the formula/cask should be skipped and the `skip_msg` very briefly - # describes why it is skipped (e.g. "No longer developed or maintained"). + # that the formula/cask/resource should be skipped and the `skip_msg` very + # briefly describes why it is skipped (e.g. "No longer developed or + # maintained"). # # @param skip_msg [String] string describing why the formula/cask is skipped # @return [Boolean] @@ -96,7 +98,7 @@ class Livecheck @skip = true end - # Should `livecheck` skip this formula/cask? + # Should `livecheck` skip this formula/cask/resource? def skip? @skip end @@ -126,7 +128,7 @@ class Livecheck # Sets the `@url` instance variable to the provided argument or returns the # `@url` instance variable when no argument is provided. The argument can be # a `String` (a URL) or a supported `Symbol` corresponding to a URL in the - # formula/cask (e.g. `:stable`, `:homepage`, `:head`, `:url`). + # formula/cask/resource (e.g. `:stable`, `:homepage`, `:head`, `:url`). # @param val [String, Symbol] URL to check for version information # @return [String, nil] def url(val = nil) @@ -140,7 +142,7 @@ class Livecheck end end - delegate version: :@formula_or_cask + delegate version: :@package_or_resource private :version # Returns a `Hash` of all instance variable values. diff --git a/Library/Homebrew/test/resource_spec.rb b/Library/Homebrew/test/resource_spec.rb index 9758b376b9..ed34c294ed 100644 --- a/Library/Homebrew/test/resource_spec.rb +++ b/Library/Homebrew/test/resource_spec.rb @@ -6,7 +6,7 @@ require "livecheck" describe Resource do subject(:resource) { described_class.new("test") } - + let(:livecheck_resource) { described_class.new do url "https://brew.sh/test-0.0.1.tgz" From 7156c95b825c79b4e42ffe8f3ab4cea8a6bee402 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Sun, 17 Jul 2022 12:45:29 +0200 Subject: [PATCH 004/138] Added `--resources` option in livecheck cmd --- Library/Homebrew/dev-cmd/livecheck.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Library/Homebrew/dev-cmd/livecheck.rb b/Library/Homebrew/dev-cmd/livecheck.rb index 0028cc83aa..c183656fda 100644 --- a/Library/Homebrew/dev-cmd/livecheck.rb +++ b/Library/Homebrew/dev-cmd/livecheck.rb @@ -35,6 +35,8 @@ module Homebrew description: "Show the latest version only if it's newer than the formula/cask." switch "--json", description: "Output information in JSON format." + switch "-r", "--resources", + description: "Check resources with livecheck blocks." switch "-q", "--quiet", description: "Suppress warnings, don't print a progress bar for JSON output." switch "--formula", "--formulae", From 59165ed3ec78466b0536f347dcbeb60cde7587cc Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Sun, 17 Jul 2022 12:47:20 +0200 Subject: [PATCH 005/138] Get all resources in all formulae --- Library/Homebrew/dev-cmd/livecheck.rb | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/Library/Homebrew/dev-cmd/livecheck.rb b/Library/Homebrew/dev-cmd/livecheck.rb index c183656fda..29541377df 100644 --- a/Library/Homebrew/dev-cmd/livecheck.rb +++ b/Library/Homebrew/dev-cmd/livecheck.rb @@ -69,6 +69,14 @@ module Homebrew formulae = args.cask? ? [] : Formula.installed casks = args.formula? ? [] : Cask::Caskroom.casks formulae + casks + elsif args.resources? + resources = Formula.all do |formula| + formula.resources.any do |resource| + if resource.livecheckable? + p resource + end + end + end elsif args.all? formulae = args.cask? ? [] : Formula.all casks = args.formula? ? [] : Cask::Cask.all @@ -95,6 +103,11 @@ module Homebrew else raise UsageError, "A watchlist file is required when no arguments are given." end + p formulae_and_casks_to_check.class + p formulae_and_casks_to_check.length + p formulae_and_casks_to_check[0].class + p formulae_and_casks_to_check[0] + formulae_and_casks_to_check = formulae_and_casks_to_check.sort_by do |formula_or_cask| formula_or_cask.respond_to?(:token) ? formula_or_cask.token : formula_or_cask.name end @@ -111,6 +124,6 @@ module Homebrew verbose: args.verbose?, }.compact - Livecheck.run_checks(formulae_and_casks_to_check, **options) + # Livecheck.run_checks(formulae_and_casks_to_check, **options) end end From 8ef6118ba06a5ae45b11681829cd925e424f92a8 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Sun, 17 Jul 2022 13:02:22 +0200 Subject: [PATCH 006/138] Work in progress: Fetch all resources with livecheck block --- Library/Homebrew/dev-cmd/livecheck.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Library/Homebrew/dev-cmd/livecheck.rb b/Library/Homebrew/dev-cmd/livecheck.rb index 29541377df..bd2e177211 100644 --- a/Library/Homebrew/dev-cmd/livecheck.rb +++ b/Library/Homebrew/dev-cmd/livecheck.rb @@ -73,10 +73,12 @@ module Homebrew resources = Formula.all do |formula| formula.resources.any do |resource| if resource.livecheckable? - p resource + resource end end + # formula.resources.filter? { |resource| !resource.livecheckable? } end + resources elsif args.all? formulae = args.cask? ? [] : Formula.all casks = args.formula? ? [] : Cask::Cask.all From dba5754c9fbd44611f80d50380a29de1e60b43df Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Mon, 18 Jul 2022 14:03:40 +0200 Subject: [PATCH 007/138] Filter out resources with livecheck block: Work in progress --- Library/Homebrew/dev-cmd/livecheck.rb | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Library/Homebrew/dev-cmd/livecheck.rb b/Library/Homebrew/dev-cmd/livecheck.rb index bd2e177211..29a08e44d6 100644 --- a/Library/Homebrew/dev-cmd/livecheck.rb +++ b/Library/Homebrew/dev-cmd/livecheck.rb @@ -70,8 +70,9 @@ module Homebrew casks = args.formula? ? [] : Cask::Caskroom.casks formulae + casks elsif args.resources? - resources = Formula.all do |formula| - formula.resources.any do |resource| + formulae = Formula.all + resources = formulae do |formula| + formula.resources.each do |resource| if resource.livecheckable? resource end @@ -105,6 +106,7 @@ module Homebrew else raise UsageError, "A watchlist file is required when no arguments are given." end + p formulae_and_casks_to_check.class p formulae_and_casks_to_check.length p formulae_and_casks_to_check[0].class From ad1a9b5970fd9186b40aa0ba2ffe0582b319f6d5 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Mon, 18 Jul 2022 14:07:33 +0200 Subject: [PATCH 008/138] Fetched all formulas with livecheckable resources --- Library/Homebrew/dev-cmd/livecheck.rb | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/Library/Homebrew/dev-cmd/livecheck.rb b/Library/Homebrew/dev-cmd/livecheck.rb index 29a08e44d6..e8fa8bfcb4 100644 --- a/Library/Homebrew/dev-cmd/livecheck.rb +++ b/Library/Homebrew/dev-cmd/livecheck.rb @@ -70,16 +70,8 @@ module Homebrew casks = args.formula? ? [] : Cask::Caskroom.casks formulae + casks elsif args.resources? - formulae = Formula.all - resources = formulae do |formula| - formula.resources.each do |resource| - if resource.livecheckable? - resource - end - end - # formula.resources.filter? { |resource| !resource.livecheckable? } - end - resources + livecheckable_resources = Formula.all.select { |formula| formula.resources.any? { |resource| resource.livecheckable? } } + livecheckable_resources elsif args.all? formulae = args.cask? ? [] : Formula.all casks = args.formula? ? [] : Cask::Cask.all From 82057003a7b548346291eb55d127617e35306289 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Mon, 18 Jul 2022 14:36:27 +0200 Subject: [PATCH 009/138] Selected all formulas with livecheckable resources --- Library/Homebrew/dev-cmd/livecheck.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Library/Homebrew/dev-cmd/livecheck.rb b/Library/Homebrew/dev-cmd/livecheck.rb index e8fa8bfcb4..c38f5be411 100644 --- a/Library/Homebrew/dev-cmd/livecheck.rb +++ b/Library/Homebrew/dev-cmd/livecheck.rb @@ -70,7 +70,9 @@ module Homebrew casks = args.formula? ? [] : Cask::Caskroom.casks formulae + casks elsif args.resources? - livecheckable_resources = Formula.all.select { |formula| formula.resources.any? { |resource| resource.livecheckable? } } + formula_with_livecheckable_resources = Formula.all.select { |formula| formula.resources.any? { |resource| resource.livecheckable? } } + livecheckable_resources = formula_with_livecheckable_resources.map { |formula| formula.resources } + # livecheckable_resources = formula_with_livecheckable_resources.map { |formula| formula.resources.filter { |resource| resource.livecheckable? } } livecheckable_resources elsif args.all? formulae = args.cask? ? [] : Formula.all From f8320c89edf5c416cfe4ac88ad102177b519c4ac Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Mon, 18 Jul 2022 14:42:43 +0200 Subject: [PATCH 010/138] Selected all livecheckable resources --- Library/Homebrew/dev-cmd/livecheck.rb | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Library/Homebrew/dev-cmd/livecheck.rb b/Library/Homebrew/dev-cmd/livecheck.rb index c38f5be411..c34ef48b7d 100644 --- a/Library/Homebrew/dev-cmd/livecheck.rb +++ b/Library/Homebrew/dev-cmd/livecheck.rb @@ -71,8 +71,7 @@ module Homebrew formulae + casks elsif args.resources? formula_with_livecheckable_resources = Formula.all.select { |formula| formula.resources.any? { |resource| resource.livecheckable? } } - livecheckable_resources = formula_with_livecheckable_resources.map { |formula| formula.resources } - # livecheckable_resources = formula_with_livecheckable_resources.map { |formula| formula.resources.filter { |resource| resource.livecheckable? } } + livecheckable_resources = formula_with_livecheckable_resources.map { |formula| formula.resources }.flatten.filter{ |resource| resource.livecheckable? } livecheckable_resources elsif args.all? formulae = args.cask? ? [] : Formula.all @@ -104,7 +103,7 @@ module Homebrew p formulae_and_casks_to_check.class p formulae_and_casks_to_check.length p formulae_and_casks_to_check[0].class - p formulae_and_casks_to_check[0] + # p formulae_and_casks_to_check[0] formulae_and_casks_to_check = formulae_and_casks_to_check.sort_by do |formula_or_cask| formula_or_cask.respond_to?(:token) ? formula_or_cask.token : formula_or_cask.name From 2d231a34785d9e452f2ba7f80b4f536c924eb782 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Mon, 18 Jul 2022 14:49:32 +0200 Subject: [PATCH 011/138] More compact way to get livecheckable resources --- .gitignore | 2 +- .vscode/settings.json | 4 +++- Library/Homebrew/dev-cmd/livecheck.rb | 5 ++--- Library/Taps/homebrew/homebrew-core | 1 + 4 files changed, 7 insertions(+), 5 deletions(-) create mode 160000 Library/Taps/homebrew/homebrew-core diff --git a/.gitignore b/.gitignore index 8f52acf25c..76d5c48355 100644 --- a/.gitignore +++ b/.gitignore @@ -17,7 +17,7 @@ /Library/Homebrew/test/junit /Library/Homebrew/test/fs_leak_log /Library/Homebrew/vendor/portable-ruby -/Library/Taps +#/Library/Taps /Library/PinnedTaps /Library/Homebrew/.byebug_history /Library/Homebrew/sorbet/rbi/hidden-definitions/errors.txt diff --git a/.vscode/settings.json b/.vscode/settings.json index 865fc53af2..fe8a066e21 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -23,5 +23,7 @@ "editor.codeActionsOnSave": { "source.fixAll.shellcheck": true, } - } + }, + "git.mergeEditor": true, + "merge-conflict.autoNavigateNextConflict.enabled": true } diff --git a/Library/Homebrew/dev-cmd/livecheck.rb b/Library/Homebrew/dev-cmd/livecheck.rb index c34ef48b7d..ff1bbfa65b 100644 --- a/Library/Homebrew/dev-cmd/livecheck.rb +++ b/Library/Homebrew/dev-cmd/livecheck.rb @@ -70,8 +70,7 @@ module Homebrew casks = args.formula? ? [] : Cask::Caskroom.casks formulae + casks elsif args.resources? - formula_with_livecheckable_resources = Formula.all.select { |formula| formula.resources.any? { |resource| resource.livecheckable? } } - livecheckable_resources = formula_with_livecheckable_resources.map { |formula| formula.resources }.flatten.filter{ |resource| resource.livecheckable? } + livecheckable_resources = Formula.all.map { |formula| formula.resources }.flatten.filter{ |resource| resource.livecheckable? } livecheckable_resources elsif args.all? formulae = args.cask? ? [] : Formula.all @@ -121,6 +120,6 @@ module Homebrew verbose: args.verbose?, }.compact - # Livecheck.run_checks(formulae_and_casks_to_check, **options) + Livecheck.run_checks(formulae_and_casks_to_check, **options) end end diff --git a/Library/Taps/homebrew/homebrew-core b/Library/Taps/homebrew/homebrew-core new file mode 160000 index 0000000000..88b2623dd6 --- /dev/null +++ b/Library/Taps/homebrew/homebrew-core @@ -0,0 +1 @@ +Subproject commit 88b2623dd6ff0dec391029b1f43107438935f4b7 From 4aa3cc6c972b681aa22f03ab719a9a98ad3ae7d9 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Mon, 18 Jul 2022 15:03:05 +0200 Subject: [PATCH 012/138] Minor --- Library/Homebrew/dev-cmd/livecheck.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Library/Homebrew/dev-cmd/livecheck.rb b/Library/Homebrew/dev-cmd/livecheck.rb index ff1bbfa65b..84b9c24a70 100644 --- a/Library/Homebrew/dev-cmd/livecheck.rb +++ b/Library/Homebrew/dev-cmd/livecheck.rb @@ -102,7 +102,7 @@ module Homebrew p formulae_and_casks_to_check.class p formulae_and_casks_to_check.length p formulae_and_casks_to_check[0].class - # p formulae_and_casks_to_check[0] + p formulae_and_casks_to_check.map { |d| d.name } formulae_and_casks_to_check = formulae_and_casks_to_check.sort_by do |formula_or_cask| formula_or_cask.respond_to?(:token) ? formula_or_cask.token : formula_or_cask.name @@ -120,6 +120,6 @@ module Homebrew verbose: args.verbose?, }.compact - Livecheck.run_checks(formulae_and_casks_to_check, **options) + # Livecheck.run_checks(formulae_and_casks_to_check, **options) end end From 0ee69e2c6351aa8f1dc0e2bcba3c084e7b5e5825 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Thu, 21 Jul 2022 20:02:15 +0200 Subject: [PATCH 013/138] Refractoring for livecheckable resources --- Library/Homebrew/dev-cmd/livecheck.rb | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/Library/Homebrew/dev-cmd/livecheck.rb b/Library/Homebrew/dev-cmd/livecheck.rb index 84b9c24a70..41e8b6e8ff 100644 --- a/Library/Homebrew/dev-cmd/livecheck.rb +++ b/Library/Homebrew/dev-cmd/livecheck.rb @@ -60,7 +60,7 @@ module Homebrew puts Homebrew::EnvConfig.livecheck_watchlist if Homebrew::EnvConfig.livecheck_watchlist.present? end - formulae_and_casks_to_check = if args.tap + package_and_resource_to_check = if args.tap tap = Tap.fetch(args.tap) formulae = args.cask? ? [] : tap.formula_files.map { |path| Formulary.factory(path) } casks = args.formula? ? [] : tap.cask_files.map { |path| Cask::CaskLoader.load(path) } @@ -82,7 +82,7 @@ module Homebrew elsif args.cask? args.named.to_casks else - args.named.to_formulae_and_casks + args.named.to_package_and_resource end elsif File.exist?(WATCHLIST_PATH) begin @@ -91,7 +91,7 @@ module Homebrew .map(&:strip) named_args = T.unsafe(CLI::NamedArgs).new(*names, parent: args) - named_args.to_formulae_and_casks(ignore_unavailable: true) + named_args.to_package_and_resource(ignore_unavailable: true) rescue Errno::ENOENT => e onoe e end @@ -99,16 +99,16 @@ module Homebrew raise UsageError, "A watchlist file is required when no arguments are given." end - p formulae_and_casks_to_check.class - p formulae_and_casks_to_check.length - p formulae_and_casks_to_check[0].class - p formulae_and_casks_to_check.map { |d| d.name } + p package_and_resource_to_check.class + p package_and_resource_to_check.length + p package_and_resource_to_check[0].class + p package_and_resource_to_check.map { |d| d.name } - formulae_and_casks_to_check = formulae_and_casks_to_check.sort_by do |formula_or_cask| - formula_or_cask.respond_to?(:token) ? formula_or_cask.token : formula_or_cask.name + package_and_resource_to_check = package_and_resource_to_check.sort_by do |package_or_resource| + package_or_resource.respond_to?(:token) ? package_or_resource.token : package_or_resource.name end - raise UsageError, "No formulae or casks to check." if formulae_and_casks_to_check.blank? + raise UsageError, "No formulae or casks to check." if package_and_resource_to_check.blank? options = { json: args.json?, @@ -120,6 +120,6 @@ module Homebrew verbose: args.verbose?, }.compact - # Livecheck.run_checks(formulae_and_casks_to_check, **options) + Livecheck.run_checks(package_and_resource_to_check[1..3], **options) end end From 7575170a0b63c0cb05f43580500a95fd1a332c4a Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Thu, 21 Jul 2022 20:02:54 +0200 Subject: [PATCH 014/138] Work in progress for livecheckable resources --- Library/Homebrew/livecheck/livecheck.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index bdc25c3371..50f4229385 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -159,7 +159,7 @@ module Homebrew # `formulae_and_casks_to_check` array and prints the results. sig { params( - formulae_and_casks_to_check: T::Array[T.any(Formula, Cask::Cask)], + formulae_and_casks_to_check: T::Array[T.any(Formula, Cask::Cask, Resource)], full_name: T::Boolean, handle_name_conflict: T::Boolean, json: T::Boolean, From ebf52091eb372171f529aff3324b6eb3af59c9c5 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Sun, 24 Jul 2022 14:14:10 +0200 Subject: [PATCH 015/138] Check only formulas with resources --- Library/Homebrew/dev-cmd/livecheck.rb | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Library/Homebrew/dev-cmd/livecheck.rb b/Library/Homebrew/dev-cmd/livecheck.rb index 41e8b6e8ff..6c55f7e8d3 100644 --- a/Library/Homebrew/dev-cmd/livecheck.rb +++ b/Library/Homebrew/dev-cmd/livecheck.rb @@ -70,8 +70,8 @@ module Homebrew casks = args.formula? ? [] : Cask::Caskroom.casks formulae + casks elsif args.resources? - livecheckable_resources = Formula.all.map { |formula| formula.resources }.flatten.filter{ |resource| resource.livecheckable? } - livecheckable_resources + formula_with_resources = Formula.all.select { |formula| formula.resources.any? } + formula_with_resources elsif args.all? formulae = args.cask? ? [] : Formula.all casks = args.formula? ? [] : Cask::Cask.all @@ -99,10 +99,10 @@ module Homebrew raise UsageError, "A watchlist file is required when no arguments are given." end - p package_and_resource_to_check.class - p package_and_resource_to_check.length - p package_and_resource_to_check[0].class - p package_and_resource_to_check.map { |d| d.name } + # p package_and_resource_to_check.class + # p package_and_resource_to_check.length + # p package_and_resource_to_check[0].class + # p package_and_resource_to_check.map { |d| d.name } package_and_resource_to_check = package_and_resource_to_check.sort_by do |package_or_resource| package_or_resource.respond_to?(:token) ? package_or_resource.token : package_or_resource.name From 9708a850d98b6f53f59dd6cea52d6c5994a7192a Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Sun, 24 Jul 2022 14:15:38 +0200 Subject: [PATCH 016/138] Merged with master --- .../lib/sorbet-runtime.rb | 116 ++ .../lib/types/_types.rb | 316 +++++ .../lib/types/abstract_utils.rb | 50 + .../lib/types/boolean.rb | 8 + .../lib/types/compatibility_patches.rb | 93 ++ .../lib/types/configuration.rb | 591 ++++++++ .../lib/types/enum.rb | 377 ++++++ .../lib/types/generic.rb | 22 + .../lib/types/helpers.rb | 58 + .../lib/types/interface_wrapper.rb | 158 +++ .../lib/types/non_forcing_constants.rb | 65 + .../lib/types/private/abstract/data.rb | 36 + .../lib/types/private/abstract/declare.rb | 53 + .../lib/types/private/abstract/hooks.rb | 42 + .../lib/types/private/abstract/validate.rb | 128 ++ .../lib/types/private/casts.rb | 41 + .../lib/types/private/class_utils.rb | 110 ++ .../lib/types/private/compiler.rb | 24 + .../lib/types/private/decl_state.rb | 30 + .../lib/types/private/final.rb | 50 + .../lib/types/private/methods/_methods.rb | 581 ++++++++ .../types/private/methods/call_validation.rb | 221 +++ .../private/methods/call_validation_2_6.rb | 1203 +++++++++++++++++ .../private/methods/call_validation_2_7.rb | 1203 +++++++++++++++++ .../lib/types/private/methods/decl_builder.rb | 232 ++++ .../lib/types/private/methods/modes.rb | 28 + .../lib/types/private/methods/signature.rb | 225 +++ .../private/methods/signature_validation.rb | 225 +++ .../lib/types/private/mixins/mixins.rb | 27 + .../lib/types/private/retry.rb | 10 + .../lib/types/private/runtime_levels.rb | 62 + .../lib/types/private/sealed.rb | 91 ++ .../lib/types/private/types/not_typed.rb | 23 + .../lib/types/private/types/string_holder.rb | 26 + .../lib/types/private/types/type_alias.rb | 31 + .../lib/types/private/types/void.rb | 34 + .../lib/types/props/_props.rb | 169 +++ .../lib/types/props/constructor.rb | 40 + .../lib/types/props/custom_type.rb | 108 ++ .../lib/types/props/decorator.rb | 669 +++++++++ .../lib/types/props/errors.rb | 8 + .../types/props/generated_code_validation.rb | 277 ++++ .../props/has_lazily_specialized_methods.rb | 140 ++ .../lib/types/props/optional.rb | 89 ++ .../lib/types/props/plugin.rb | 37 + .../lib/types/props/pretty_printable.rb | 107 ++ .../lib/types/props/private/apply_default.rb | 170 +++ .../props/private/deserializer_generator.rb | 160 +++ .../lib/types/props/private/parser.rb | 32 + .../types/props/private/serde_transform.rb | 186 +++ .../props/private/serializer_generator.rb | 76 ++ .../lib/types/props/private/setter_factory.rb | 197 +++ .../lib/types/props/serializable.rb | 374 +++++ .../lib/types/props/type_validation.rb | 111 ++ .../lib/types/props/utils.rb | 59 + .../lib/types/props/weak_constructor.rb | 67 + .../sorbet-runtime-0.5.10132/lib/types/sig.rb | 30 + .../lib/types/struct.rb | 18 + .../lib/types/types/attached_class.rb | 37 + .../lib/types/types/base.rb | 172 +++ .../lib/types/types/class_of.rb | 40 + .../lib/types/types/enum.rb | 40 + .../lib/types/types/fixed_array.rb | 86 ++ .../lib/types/types/fixed_hash.rb | 74 + .../lib/types/types/intersection.rb | 42 + .../lib/types/types/noreturn.rb | 29 + .../lib/types/types/proc.rb | 51 + .../lib/types/types/self_type.rb | 35 + .../lib/types/types/simple.rb | 94 ++ .../lib/types/types/t_enum.rb | 38 + .../lib/types/types/type_member.rb | 7 + .../lib/types/types/type_parameter.rb | 23 + .../lib/types/types/type_template.rb | 7 + .../lib/types/types/type_variable.rb | 34 + .../lib/types/types/typed_array.rb | 39 + .../lib/types/types/typed_enumerable.rb | 176 +++ .../lib/types/types/typed_enumerator.rb | 41 + .../lib/types/types/typed_enumerator_lazy.rb | 41 + .../lib/types/types/typed_hash.rb | 48 + .../lib/types/types/typed_range.rb | 31 + .../lib/types/types/typed_set.rb | 53 + .../lib/types/types/union.rb | 91 ++ .../lib/types/types/untyped.rb | 29 + .../lib/types/utils.rb | 209 +++ 84 files changed, 11281 insertions(+) create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/sorbet-runtime.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/_types.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/abstract_utils.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/boolean.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/compatibility_patches.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/configuration.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/enum.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/generic.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/helpers.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/interface_wrapper.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/non_forcing_constants.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/abstract/data.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/abstract/declare.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/abstract/hooks.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/abstract/validate.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/casts.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/class_utils.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/compiler.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/decl_state.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/final.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/_methods.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/call_validation.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/call_validation_2_6.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/call_validation_2_7.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/decl_builder.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/modes.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/signature.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/signature_validation.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/mixins/mixins.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/retry.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/runtime_levels.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/sealed.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/types/not_typed.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/types/string_holder.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/types/type_alias.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/types/void.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/_props.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/constructor.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/custom_type.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/decorator.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/errors.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/generated_code_validation.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/has_lazily_specialized_methods.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/optional.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/plugin.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/pretty_printable.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/private/apply_default.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/private/deserializer_generator.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/private/parser.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/private/serde_transform.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/private/serializer_generator.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/private/setter_factory.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/serializable.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/type_validation.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/utils.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/weak_constructor.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/sig.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/struct.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/attached_class.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/base.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/class_of.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/enum.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/fixed_array.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/fixed_hash.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/intersection.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/noreturn.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/proc.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/self_type.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/simple.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/t_enum.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/type_member.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/type_parameter.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/type_template.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/type_variable.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/typed_array.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/typed_enumerable.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/typed_enumerator.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/typed_enumerator_lazy.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/typed_hash.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/typed_range.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/typed_set.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/union.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/untyped.rb create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/utils.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/sorbet-runtime.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/sorbet-runtime.rb new file mode 100644 index 0000000000..c2ad5678d0 --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/sorbet-runtime.rb @@ -0,0 +1,116 @@ +# frozen_string_literal: true +# typed: true + +# This file is hand-crafted to encode the dependencies. They load the whole type +# system since there is such a high chance of it being used, using an autoloader +# wouldn't buy us any startup time saving. + +# Namespaces without any implementation +module T; end +module T::Helpers; end +module T::Private; end +module T::Private::Abstract; end +module T::Private::Types; end + +# Each section is a group that I believe need a fixed ordering. There is also +# an ordering between groups. + +# These are pre-reqs for almost everything in here. +require_relative 'types/configuration' +require_relative 'types/_types' +require_relative 'types/private/decl_state' +require_relative 'types/private/class_utils' +require_relative 'types/private/runtime_levels' +require_relative 'types/private/methods/_methods' +require_relative 'types/sig' +require_relative 'types/helpers' +require_relative 'types/private/final' +require_relative 'types/private/sealed' + +# The types themselves. First base classes +require_relative 'types/types/base' +require_relative 'types/types/typed_enumerable' +# Everything else +require_relative 'types/types/class_of' +require_relative 'types/types/enum' +require_relative 'types/types/fixed_array' +require_relative 'types/types/fixed_hash' +require_relative 'types/types/intersection' +require_relative 'types/types/noreturn' +require_relative 'types/types/proc' +require_relative 'types/types/attached_class' +require_relative 'types/types/self_type' +require_relative 'types/types/simple' +require_relative 'types/types/t_enum' +require_relative 'types/types/type_parameter' +require_relative 'types/types/typed_array' +require_relative 'types/types/typed_enumerator' +require_relative 'types/types/typed_enumerator_lazy' +require_relative 'types/types/typed_hash' +require_relative 'types/types/typed_range' +require_relative 'types/types/typed_set' +require_relative 'types/types/union' +require_relative 'types/types/untyped' +require_relative 'types/private/types/not_typed' +require_relative 'types/private/types/void' +require_relative 'types/private/types/string_holder' +require_relative 'types/private/types/type_alias' + +require_relative 'types/types/type_variable' +require_relative 'types/types/type_member' +require_relative 'types/types/type_template' + +# Call validation +require_relative 'types/private/methods/modes' +require_relative 'types/private/methods/call_validation' + +# Signature validation +require_relative 'types/private/methods/signature_validation' +require_relative 'types/abstract_utils' +require_relative 'types/private/abstract/validate' + +# Catch all. Sort of built by `cd extn; find types -type f | grep -v test | sort` +require_relative 'types/generic' +require_relative 'types/interface_wrapper' +require_relative 'types/private/abstract/declare' +require_relative 'types/private/abstract/hooks' +require_relative 'types/private/casts' +require_relative 'types/private/methods/decl_builder' +require_relative 'types/private/methods/signature' +require_relative 'types/private/retry' +require_relative 'types/utils' +require_relative 'types/boolean' + +# Props dependencies +require_relative 'types/private/abstract/data' +require_relative 'types/private/mixins/mixins' +require_relative 'types/props/_props' +require_relative 'types/props/custom_type' +require_relative 'types/props/decorator' +require_relative 'types/props/errors' +require_relative 'types/props/plugin' +require_relative 'types/props/utils' +require_relative 'types/enum' +# Props that run sigs statically so have to be after all the others :( +require_relative 'types/props/private/setter_factory' +require_relative 'types/props/private/apply_default' +require_relative 'types/props/has_lazily_specialized_methods' +require_relative 'types/props/optional' +require_relative 'types/props/weak_constructor' +require_relative 'types/props/constructor' +require_relative 'types/props/pretty_printable' +require_relative 'types/props/private/serde_transform' +require_relative 'types/props/private/deserializer_generator' +require_relative 'types/props/private/serializer_generator' +require_relative 'types/props/serializable' +require_relative 'types/props/type_validation' +require_relative 'types/props/private/parser' +require_relative 'types/props/generated_code_validation' + +require_relative 'types/struct' +require_relative 'types/non_forcing_constants' + +require_relative 'types/compatibility_patches' + +# Sorbet Compiler support module +require_relative 'types/private/compiler' diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/_types.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/_types.rb new file mode 100644 index 0000000000..20a0e641e0 --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/_types.rb @@ -0,0 +1,316 @@ +# frozen_string_literal: true +# typed: true +# This is where we define the shortcuts, so we can't use them here + +# _____ +# |_ _| _ _ __ ___ ___ +# | || | | | '_ \ / _ \/ __| +# | || |_| | |_) | __/\__ \ +# |_| \__, | .__/ \___||___/ +# |___/|_| +# +# Docs at https://sorbet.org/docs/sigs +# +# Types that you can pass to `sig`: +# +# - a Ruby class +# +# - [, , ...] -- to specify a "tuple"; a fixed-size array with known types for each member +# +# - {key: , key2: , ...} -- to speicfy a "shape"; a fixed-size hash +# with known keys and type values +# +# - Any of the `T.foo` methods below + +module T + # T.any(, , ...) -- matches any of the types listed + def self.any(type_a, type_b, *types) + type_a = T::Utils.coerce(type_a) + type_b = T::Utils.coerce(type_b) + types = types.map {|t| T::Utils.coerce(t)} if !types.empty? + T::Types::Union::Private::Pool.union_of_types(type_a, type_b, types) + end + + # Shorthand for T.any(type, NilClass) + def self.nilable(type) + T::Types::Union::Private::Pool.union_of_types(T::Utils.coerce(type), T::Utils::Nilable::NIL_TYPE) + end + + # Matches any object. In the static checker, T.untyped allows any + # method calls or operations. + def self.untyped + T::Types::Untyped::Private::INSTANCE + end + + # Indicates a function never returns (e.g. "Kernel#raise") + def self.noreturn + T::Types::NoReturn::Private::INSTANCE + end + + # T.all(, , ...) -- matches an object that has all of the types listed + def self.all(type_a, type_b, *types) + T::Types::Intersection.new([type_a, type_b] + types) + end + + # Matches any of the listed values + # @deprecated Use T::Enum instead. + def self.deprecated_enum(values) + T::Types::Enum.new(values) + end + + # Creates a proc type + def self.proc + T::Private::Methods.start_proc + end + + # Matches `self`: + def self.self_type + T::Types::SelfType::Private::INSTANCE + end + + # Matches the instance type in a singleton-class context + def self.attached_class + T::Types::AttachedClassType::Private::INSTANCE + end + + # Matches any class that subclasses or includes the provided class + # or module + def self.class_of(klass) + T::Types::ClassOf.new(klass) + end + + ## END OF THE METHODS TO PASS TO `sig`. + + # Constructs a type alias. Used to create a short name for a larger type. In Ruby this returns a + # wrapper that contains a proc that is evaluated to get the underlying type. This syntax however + # is needed for support by the static checker. + # + # @example + # NilableString = T.type_alias {T.nilable(String)} + # + # sig {params(arg: NilableString, default: String).returns(String)} + # def or_else(arg, default) + # arg || default + # end + # + # The name of the type alias is not preserved; Error messages will + # be printed with reference to the underlying type. + # + # TODO Remove `type` parameter. This was left in to make life easier while migrating. + def self.type_alias(type=nil, &blk) + if blk + T::Private::Types::TypeAlias.new(blk) + else + T::Utils.coerce(type) + end + end + + # References a type parameter which was previously defined with + # `type_parameters`. + # + # This is used for generic methods. + # + # @example + # sig + # .type_parameters(:U) + # .params( + # blk: T.proc.params(arg0: Elem).returns(T.type_parameter(:U)), + # ) + # .returns(T::Array[T.type_parameter(:U)]) + # def map(&blk); end + def self.type_parameter(name) + T::Types::TypeParameter.new(name) + end + + # Tells the typechecker that `value` is of type `type`. Use this to get additional checking after + # an expression that the typechecker is unable to analyze. If `checked` is true, raises an + # exception at runtime if the value doesn't match the type. + # + # Compared to `T.let`, `T.cast` is _trusted_ by static system. + def self.cast(value, type, checked: true) + return value unless checked + + Private::Casts.cast(value, type, cast_method: "T.cast") + end + + # Tells the typechecker to declare a variable of type `type`. Use + # like: + # + # seconds = T.let(0.0, Float) + # + # Compared to `T.cast`, `T.let` is _checked_ by static system. + # + # If `checked` is true, raises an exception at runtime if the value + # doesn't match the type. + def self.let(value, type, checked: true) + return value unless checked + + Private::Casts.cast(value, type, cast_method: "T.let") + end + + # Tells the type checker to treat `self` in the current block as `type`. + # Useful for blocks that are captured and executed later with instance_exec. + # Use like: + # + # seconds = lambda do + # T.bind(self, NewBinding) + # ... + # end + # + # `T.bind` behaves like `T.cast` in that it is assumed to be true statically. + # + # If `checked` is true, raises an exception at runtime if the value + # doesn't match the type (this is the default). + def self.bind(value, type, checked: true) + return value unless checked + + Private::Casts.cast(value, type, cast_method: "T.bind") + end + + # Tells the typechecker to ensure that `value` is of type `type` (if not, the typechecker will + # fail). Use this for debugging typechecking errors, or to ensure that type information is + # statically known and being checked appropriately. If `checked` is true, raises an exception at + # runtime if the value doesn't match the type. + def self.assert_type!(value, type, checked: true) + return value unless checked + + Private::Casts.cast(value, type, cast_method: "T.assert_type!") + end + + # For the static type checker, strips all type information from a value + # and returns the same value, but statically-typed as `T.untyped`. + # Can be used to tell the static checker to "trust you" by discarding type information + # you know to be incorrect. Use with care! + # (This has no effect at runtime.) + # + # We can't actually write this sig because we ourselves are inside + # the `T::` module and doing this would create a bootstrapping + # cycle. However, we also don't actually need to do so; An untyped + # identity method works just as well here. + # + # `sig {params(value: T.untyped).returns(T.untyped)}` + def self.unsafe(value) + value + end + + # A convenience method to `raise` when the argument is `nil` and return it + # otherwise. + # + # Intended to be used as: + # + # needs_foo(T.must(maybe_gives_foo)) + # + # Equivalent to: + # + # foo = maybe_gives_foo + # raise "nil" if foo.nil? + # needs_foo(foo) + # + # Intended to be used to promise sorbet that a given nilable value happens + # to contain a non-nil value at this point. + # + # `sig {params(arg: T.nilable(A)).returns(A)}` + def self.must(arg) + return arg if arg + return arg if arg == false + + begin + raise TypeError.new("Passed `nil` into T.must") + rescue TypeError => e # raise into rescue to ensure e.backtrace is populated + T::Configuration.inline_type_error_handler(e, {kind: 'T.must', value: arg, type: nil}) + end + end + + # A way to ask Sorbet to show what type it thinks an expression has. + # This can be useful for debugging and checking assumptions. + # In the runtime, merely returns the value passed in. + def self.reveal_type(value) + value + end + + # A way to ask Sorbet to prove that a certain branch of control flow never + # happens. Commonly used to assert that a case or if statement exhausts all + # possible cases. + def self.absurd(value) + msg = "Control flow reached T.absurd." + + case value + when Kernel + msg += " Got value: #{value}" + end + + begin + raise TypeError.new(msg) + rescue TypeError => e # raise into rescue to ensure e.backtrace is populated + T::Configuration.inline_type_error_handler(e, {kind: 'T.absurd', value: value, type: nil}) + end + end + + ### Generic classes ### + + module Array + def self.[](type) + if type.is_a?(T::Types::Untyped) + T::Types::TypedArray::Untyped.new + else + T::Types::TypedArray.new(type) + end + end + end + + module Hash + def self.[](keys, values) + if keys.is_a?(T::Types::Untyped) && values.is_a?(T::Types::Untyped) + T::Types::TypedHash::Untyped.new + else + T::Types::TypedHash.new(keys: keys, values: values) + end + end + end + + module Enumerable + def self.[](type) + if type.is_a?(T::Types::Untyped) + T::Types::TypedEnumerable::Untyped.new + else + T::Types::TypedEnumerable.new(type) + end + end + end + + module Enumerator + def self.[](type) + if type.is_a?(T::Types::Untyped) + T::Types::TypedEnumerator::Untyped.new + else + T::Types::TypedEnumerator.new(type) + end + end + + module Lazy + def self.[](type) + if type.is_a?(T::Types::Untyped) + T::Types::TypedEnumeratorLazy::Untyped.new + else + T::Types::TypedEnumeratorLazy.new(type) + end + end + end + end + + module Range + def self.[](type) + T::Types::TypedRange.new(type) + end + end + + module Set + def self.[](type) + if type.is_a?(T::Types::Untyped) + T::Types::TypedSet::Untyped.new + else + T::Types::TypedSet.new(type) + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/abstract_utils.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/abstract_utils.rb new file mode 100644 index 0000000000..721bd4e0a7 --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/abstract_utils.rb @@ -0,0 +1,50 @@ +# frozen_string_literal: true +# typed: true + +module T::AbstractUtils + Methods = T::Private::Methods + + # Returns whether a module is declared as abstract. After the module is finished being declared, + # this is equivalent to whether it has any abstract methods that haven't been implemented + # (because we validate that and raise an error otherwise). + # + # Note that checking `mod.is_a?(Abstract::Hooks)` is not a safe substitute for this method; when + # a class extends `Abstract::Hooks`, all of its subclasses, including the eventual concrete + # ones, will still have `Abstract::Hooks` as an ancestor. + def self.abstract_module?(mod) + !T::Private::Abstract::Data.get(mod, :abstract_type).nil? + end + + def self.abstract_method?(method) + signature = Methods.signature_for_method(method) + signature&.mode == Methods::Modes.abstract + end + + # Given a module, returns the set of methods declared as abstract (in itself or ancestors) + # that have not been implemented. + def self.abstract_methods_for(mod) + declared_methods = declared_abstract_methods_for(mod) + declared_methods.select do |declared_method| + actual_method = mod.instance_method(declared_method.name) + # Note that in the case where an abstract method is overridden by another abstract method, + # this method will return them both. This is intentional to ensure we validate the final + # implementation against all declarations of an abstract method (they might not all have the + # same signature). + abstract_method?(actual_method) + end + end + + # Given a module, returns the set of methods declared as abstract (in itself or ancestors) + # regardless of whether they have been implemented. + def self.declared_abstract_methods_for(mod) + methods = [] + mod.ancestors.each do |ancestor| + ancestor_methods = ancestor.private_instance_methods(false) + ancestor.instance_methods(false) + ancestor_methods.each do |method_name| + method = ancestor.instance_method(method_name) + methods << method if abstract_method?(method) + end + end + methods + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/boolean.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/boolean.rb new file mode 100644 index 0000000000..8763d8707d --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/boolean.rb @@ -0,0 +1,8 @@ +# typed: strict +# frozen_string_literal: true + +module T + # T::Boolean is a type alias helper for the common `T.any(TrueClass, FalseClass)`. + # Defined separately from _types.rb because it has a dependency on T::Types::Union. + Boolean = T.type_alias {T.any(TrueClass, FalseClass)} +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/compatibility_patches.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/compatibility_patches.rb new file mode 100644 index 0000000000..070b182aae --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/compatibility_patches.rb @@ -0,0 +1,93 @@ +# frozen_string_literal: true +# typed: ignore + +# Work around an interaction bug with sorbet-runtime and rspec-mocks, +# which occurs when using message expectations (*_any_instance_of, +# expect, allow) and and_call_original. +# +# When a sig is defined, sorbet-runtime will replace the sigged method +# with a wrapper that, upon first invocation, re-wraps the method with a faster +# implementation. +# +# When expect_any_instance_of is used, rspec stores a reference to the first wrapper, +# to be restored later. +# +# The first wrapper is invoked as part of the test and sorbet-runtime replaces +# the method definition with the second wrapper. +# +# But when mocks are cleaned up, rspec restores back to the first wrapper. +# Upon subsequent invocations, the first wrapper is called, and sorbet-runtime +# throws a runtime error, since this is an unexpected state. +# +# We work around this by forcing re-wrapping before rspec stores a reference +# to the method. +if defined? ::RSpec::Mocks + module T + module CompatibilityPatches + module RSpecCompatibility + module RecorderExtensions + def observe!(method_name) + method = @klass.instance_method(method_name.to_sym) + T::Private::Methods.maybe_run_sig_block_for_method(method) + super(method_name) + end + end + ::RSpec::Mocks::AnyInstance::Recorder.prepend(RecorderExtensions) if defined?(::RSpec::Mocks::AnyInstance::Recorder) + + module MethodDoubleExtensions + def initialize(object, method_name, proxy) + if ::Kernel.instance_method(:respond_to?).bind(object).call(method_name, true) + method = ::RSpec::Support.method_handle_for(object, method_name) + T::Private::Methods.maybe_run_sig_block_for_method(method) + end + super(object, method_name, proxy) + end + end + ::RSpec::Mocks::MethodDouble.prepend(MethodDoubleExtensions) if defined?(::RSpec::Mocks::MethodDouble) + end + end + end +end + +# Work around for sorbet-runtime wrapped methods. +# +# When a sig is defined, sorbet-runtime will replace the sigged method +# with a wrapper. Those wrapper methods look like `foo(*args, &blk)` +# so that wrappers can handle and pass on all the arguments supplied. +# +# However, that creates a problem with runtime reflection on the methods, +# since when a sigged method is introspected, it will always return its +# `arity` as `-1`, its `parameters` as `[[:rest, :args], [:block, :blk]]`, +# and its `source_location` as `[, ]`. +# +# This might be a problem for some applications that rely on getting the +# correct information from these methods. +# +# This compatibility module, when prepended to the `Method` class, would fix +# the return values of `arity`, `parameters` and `source_location`. +# +# @example +# require 'sorbet-runtime' +# ::Method.prepend(T::CompatibilityPatches::MethodExtensions) +module T + module CompatibilityPatches + module MethodExtensions + def arity + arity = super + return arity if arity != -1 || self.is_a?(Proc) + sig = T::Private::Methods.signature_for_method(self) + sig ? sig.method.arity : arity + end + + def source_location + sig = T::Private::Methods.signature_for_method(self) + sig ? sig.method.source_location : super + end + + def parameters + sig = T::Private::Methods.signature_for_method(self) + sig ? sig.method.parameters : super + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/configuration.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/configuration.rb new file mode 100644 index 0000000000..c012b6e8b6 --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/configuration.rb @@ -0,0 +1,591 @@ +# typed: true +# frozen_string_literal: true + +module T::Configuration + # Cache this comparisonn to avoid two allocations all over the place. + AT_LEAST_RUBY_2_7 = Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.7') + + # Announces to Sorbet that we are currently in a test environment, so it + # should treat any sigs which are marked `.checked(:tests)` as if they were + # just a normal sig. + # + # If this method is not called, sigs marked `.checked(:tests)` will not be + # checked. In fact, such methods won't even be wrapped--the runtime will put + # back the original method. + # + # Note: Due to the way sigs are evaluated and methods are wrapped, this + # method MUST be called before any code calls `sig`. This method raises if + # it has been called too late. + def self.enable_checking_for_sigs_marked_checked_tests + T::Private::RuntimeLevels.enable_checking_in_tests + end + + # Announce to Sorbet that we would like the final checks to be enabled when + # including and extending modules. Iff this is not called, then the following + # example will not raise an error. + # + # ```ruby + # module M + # extend T::Sig + # sig(:final) {void} + # def foo; end + # end + # class C + # include M + # def foo; end + # end + # ``` + def self.enable_final_checks_on_hooks + T::Private::Methods.set_final_checks_on_hooks(true) + end + + # Undo the effects of a previous call to + # `enable_final_checks_on_hooks`. + def self.reset_final_checks_on_hooks + T::Private::Methods.set_final_checks_on_hooks(false) + end + + @include_value_in_type_errors = true + # Whether to include values in TypeError messages. + # + # Including values is useful for debugging, but can potentially leak + # sensitive information to logs. + # + # @return [T::Boolean] + def self.include_value_in_type_errors? + @include_value_in_type_errors + end + + # Configure if type errors excludes the value of the problematic type. + # + # The default is to include values in type errors: + # TypeError: Expected type Integer, got String with value "foo" + # + # When values are excluded from type errors: + # TypeError: Expected type Integer, got String + def self.exclude_value_in_type_errors + @include_value_in_type_errors = false + end + + # Opposite of exclude_value_in_type_errors. + # (Including values in type errors is the default) + def self.include_value_in_type_errors + @include_value_in_type_errors = true + end + + # Whether VM-defined prop serialization/deserialization routines can be enabled. + # + # @return [T::Boolean] + def self.can_enable_vm_prop_serde? + T::Props::Private::DeserializerGenerator.respond_to?(:generate2) + end + + @use_vm_prop_serde = false + # Whether to use VM-defined prop serialization/deserialization routines. + # + # The default is to use runtime codegen inside sorbet-runtime itself. + # + # @return [T::Boolean] + def self.use_vm_prop_serde? + @use_vm_prop_serde || false + end + + # Enable using VM-defined prop serialization/deserialization routines. + # + # This method is likely to break things outside of Stripe's systems. + def self.enable_vm_prop_serde + if !can_enable_vm_prop_serde? + hard_assert_handler('Ruby VM is not setup to use VM-defined prop serde') + end + @use_vm_prop_serde = true + end + + # Disable using VM-defined prop serialization/deserialization routines. + def self.disable_vm_prop_serde + @use_vm_prop_serde = false + end + + # Configure the default checked level for a sig with no explicit `.checked` + # builder. When unset, the default checked level is `:always`. + # + # Note: setting this option is potentially dangerous! Sorbet can't check all + # code statically. The runtime checks complement the checks that Sorbet does + # statically, so that methods don't have to guard themselves from being + # called incorrectly by untyped code. + # + # @param [:never, :compiled, :tests, :always] default_checked_level + def self.default_checked_level=(default_checked_level) + T::Private::RuntimeLevels.default_checked_level = default_checked_level + end + + @inline_type_error_handler = nil + # Set a handler to handle `TypeError`s raised by any in-line type assertions, + # including `T.must`, `T.let`, `T.cast`, and `T.assert_type!`. + # + # By default, any `TypeError`s detected by this gem will be raised. Setting + # inline_type_error_handler to an object that implements :call (e.g. proc or + # lambda) allows users to customize the behavior when a `TypeError` is + # raised on any inline type assertion. + # + # @param [Lambda, Proc, Object, nil] value Proc that handles the error (pass + # nil to reset to default behavior) + # + # Parameters passed to value.call: + # + # @param [TypeError] error TypeError that was raised + # @param [Hash] opts A hash containing contextual information on the error: + # @option opts [String] :kind One of: + # ['T.cast', 'T.let', 'T.bind', 'T.assert_type!', 'T.must', 'T.absurd'] + # @option opts [Object, nil] :type Expected param/return value type + # @option opts [Object] :value Actual param/return value + # + # @example + # T::Configuration.inline_type_error_handler = lambda do |error, opts| + # puts error.message + # end + def self.inline_type_error_handler=(value) + validate_lambda_given!(value) + @inline_type_error_handler = value + end + + private_class_method def self.inline_type_error_handler_default(error, opts) + raise error + end + + def self.inline_type_error_handler(error, opts={}) + if @inline_type_error_handler + # Backwards compatibility before `inline_type_error_handler` took a second arg + if @inline_type_error_handler.arity == 1 + @inline_type_error_handler.call(error) + else + @inline_type_error_handler.call(error, opts) + end + else + inline_type_error_handler_default(error, opts) + end + nil + end + + @sig_builder_error_handler = nil + # Set a handler to handle errors that occur when the builder methods in the + # body of a sig are executed. The sig builder methods are inside a proc so + # that they can be lazily evaluated the first time the method being sig'd is + # called. + # + # By default, improper use of the builder methods within the body of a sig + # cause an ArgumentError to be raised. Setting sig_builder_error_handler to an + # object that implements :call (e.g. proc or lambda) allows users to + # customize the behavior when a sig can't be built for some reason. + # + # @param [Lambda, Proc, Object, nil] value Proc that handles the error (pass + # nil to reset to default behavior) + # + # Parameters passed to value.call: + # + # @param [StandardError] error The error that was raised + # @param [Thread::Backtrace::Location] location Location of the error + # + # @example + # T::Configuration.sig_builder_error_handler = lambda do |error, location| + # puts error.message + # end + def self.sig_builder_error_handler=(value) + validate_lambda_given!(value) + @sig_builder_error_handler = value + end + + private_class_method def self.sig_builder_error_handler_default(error, location) + raise ArgumentError.new("#{location.path}:#{location.lineno}: Error interpreting `sig`:\n #{error.message}\n\n") + end + + def self.sig_builder_error_handler(error, location) + if @sig_builder_error_handler + @sig_builder_error_handler.call(error, location) + else + sig_builder_error_handler_default(error, location) + end + nil + end + + @sig_validation_error_handler = nil + # Set a handler to handle sig validation errors. + # + # Sig validation errors include things like abstract checks, override checks, + # and type compatibility of arguments. They happen after a sig has been + # successfully built, but the built sig is incompatible with other sigs in + # some way. + # + # By default, sig validation errors cause an exception to be raised. + # Setting sig_validation_error_handler to an object that implements :call + # (e.g. proc or lambda) allows users to customize the behavior when a method + # signature's build fails. + # + # @param [Lambda, Proc, Object, nil] value Proc that handles the error (pass + # nil to reset to default behavior) + # + # Parameters passed to value.call: + # + # @param [StandardError] error The error that was raised + # @param [Hash] opts A hash containing contextual information on the error: + # @option opts [Method, UnboundMethod] :method Method on which the signature build failed + # @option opts [T::Private::Methods::Declaration] :declaration Method + # signature declaration struct + # @option opts [T::Private::Methods::Signature, nil] :signature Signature + # that failed (nil if sig build failed before Signature initialization) + # @option opts [T::Private::Methods::Signature, nil] :super_signature Super + # method's signature (nil if method is not an override or super method + # does not have a method signature) + # + # @example + # T::Configuration.sig_validation_error_handler = lambda do |error, opts| + # puts error.message + # end + def self.sig_validation_error_handler=(value) + validate_lambda_given!(value) + @sig_validation_error_handler = value + end + + private_class_method def self.sig_validation_error_handler_default(error, opts) + raise error + end + + def self.sig_validation_error_handler(error, opts={}) + if @sig_validation_error_handler + @sig_validation_error_handler.call(error, opts) + else + sig_validation_error_handler_default(error, opts) + end + nil + end + + @call_validation_error_handler = nil + # Set a handler for type errors that result from calling a method. + # + # By default, errors from calling a method cause an exception to be raised. + # Setting call_validation_error_handler to an object that implements :call + # (e.g. proc or lambda) allows users to customize the behavior when a method + # is called with invalid parameters, or returns an invalid value. + # + # @param [Lambda, Proc, Object, nil] value Proc that handles the error + # report (pass nil to reset to default behavior) + # + # Parameters passed to value.call: + # + # @param [T::Private::Methods::Signature] signature Signature that failed + # @param [Hash] opts A hash containing contextual information on the error: + # @option opts [String] :message Error message + # @option opts [String] :kind One of: + # ['Parameter', 'Block parameter', 'Return value'] + # @option opts [Symbol] :name Param or block param name (nil for return + # value) + # @option opts [Object] :type Expected param/return value type + # @option opts [Object] :value Actual param/return value + # @option opts [Thread::Backtrace::Location] :location Location of the + # caller + # + # @example + # T::Configuration.call_validation_error_handler = lambda do |signature, opts| + # puts opts[:message] + # end + def self.call_validation_error_handler=(value) + validate_lambda_given!(value) + @call_validation_error_handler = value + end + + private_class_method def self.call_validation_error_handler_default(signature, opts) + raise TypeError.new(opts[:pretty_message]) + end + + def self.call_validation_error_handler(signature, opts={}) + if @call_validation_error_handler + @call_validation_error_handler.call(signature, opts) + else + call_validation_error_handler_default(signature, opts) + end + nil + end + + @log_info_handler = nil + # Set a handler for logging + # + # @param [Lambda, Proc, Object, nil] value Proc that handles the error + # report (pass nil to reset to default behavior) + # + # Parameters passed to value.call: + # + # @param [String] str Message to be logged + # @param [Hash] extra A hash containing additional parameters to be passed along to the logger. + # + # @example + # T::Configuration.log_info_handler = lambda do |str, extra| + # puts "#{str}, context: #{extra}" + # end + def self.log_info_handler=(value) + validate_lambda_given!(value) + @log_info_handler = value + end + + private_class_method def self.log_info_handler_default(str, extra) + puts "#{str}, extra: #{extra}" + end + + def self.log_info_handler(str, extra) + if @log_info_handler + @log_info_handler.call(str, extra) + else + log_info_handler_default(str, extra) + end + end + + @soft_assert_handler = nil + # Set a handler for soft assertions + # + # These generally shouldn't stop execution of the program, but rather inform + # some party of the assertion to action on later. + # + # @param [Lambda, Proc, Object, nil] value Proc that handles the error + # report (pass nil to reset to default behavior) + # + # Parameters passed to value.call: + # + # @param [String] str Assertion message + # @param [Hash] extra A hash containing additional parameters to be passed along to the handler. + # + # @example + # T::Configuration.soft_assert_handler = lambda do |str, extra| + # puts "#{str}, context: #{extra}" + # end + def self.soft_assert_handler=(value) + validate_lambda_given!(value) + @soft_assert_handler = value + end + + private_class_method def self.soft_assert_handler_default(str, extra) + puts "#{str}, extra: #{extra}" + end + + def self.soft_assert_handler(str, extra) + if @soft_assert_handler + @soft_assert_handler.call(str, extra) + else + soft_assert_handler_default(str, extra) + end + end + + @hard_assert_handler = nil + # Set a handler for hard assertions + # + # These generally should stop execution of the program, and optionally inform + # some party of the assertion. + # + # @param [Lambda, Proc, Object, nil] value Proc that handles the error + # report (pass nil to reset to default behavior) + # + # Parameters passed to value.call: + # + # @param [String] str Assertion message + # @param [Hash] extra A hash containing additional parameters to be passed along to the handler. + # + # @example + # T::Configuration.hard_assert_handler = lambda do |str, extra| + # raise "#{str}, context: #{extra}" + # end + def self.hard_assert_handler=(value) + validate_lambda_given!(value) + @hard_assert_handler = value + end + + private_class_method def self.hard_assert_handler_default(str, _) + raise str + end + + def self.hard_assert_handler(str, extra={}) + if @hard_assert_handler + @hard_assert_handler.call(str, extra) + else + hard_assert_handler_default(str, extra) + end + end + + @scalar_types = nil + # Set a list of class strings that are to be considered scalar. + # (pass nil to reset to default behavior) + # + # @param [String] values Class name. + # + # @example + # T::Configuration.scalar_types = ["NilClass", "TrueClass", "FalseClass", ...] + def self.scalar_types=(values) + if values.nil? + @scalar_types = values + else + bad_values = values.reject {|v| v.class == String} + unless bad_values.empty? + raise ArgumentError.new("Provided values must all be class name strings.") + end + + @scalar_types = values.each_with_object({}) {|x, acc| acc[x] = true}.freeze + end + end + + @default_scalar_types = { + "NilClass" => true, + "TrueClass" => true, + "FalseClass" => true, + "Integer" => true, + "Float" => true, + "String" => true, + "Symbol" => true, + "Time" => true, + "T::Enum" => true, + }.freeze + + def self.scalar_types + @scalar_types || @default_scalar_types + end + + # Guard against overrides of `name` or `to_s` + MODULE_NAME = Module.instance_method(:name) + private_constant :MODULE_NAME + + @default_module_name_mangler = if T::Configuration::AT_LEAST_RUBY_2_7 + ->(type) {MODULE_NAME.bind_call(type)} + else + ->(type) {MODULE_NAME.bind(type).call} + end + + @module_name_mangler = nil + + def self.module_name_mangler + @module_name_mangler || @default_module_name_mangler + end + + # Set to override the default behavior for converting types + # to names in generated code. Used by the runtime implementation + # associated with `--stripe-packages` mode. + # + # @param [Lambda, Proc, nil] handler Proc that converts a type (Class/Module) + # to a String (pass nil to reset to default behavior) + def self.module_name_mangler=(handler) + @module_name_mangler = handler + end + + @sensitivity_and_pii_handler = nil + # Set to a PII handler function. This will be called with the `sensitivity:` + # annotations on things that use `T::Props` and can modify them ahead-of-time. + # + # @param [Lambda, Proc, nil] handler Proc that takes a hash mapping symbols to the + # prop values. Pass nil to avoid changing `sensitivity:` annotations. + def self.normalize_sensitivity_and_pii_handler=(handler) + @sensitivity_and_pii_handler = handler + end + + def self.normalize_sensitivity_and_pii_handler + @sensitivity_and_pii_handler + end + + @redaction_handler = nil + # Set to a redaction handling function. This will be called when the + # `_redacted` version of a prop reader is used. By default this is set to + # `nil` and will raise an exception when the redacted version of a prop is + # accessed. + # + # @param [Lambda, Proc, nil] handler Proc that converts a value into its + # redacted version according to the spec passed as the second argument. + def self.redaction_handler=(handler) + @redaction_handler = handler + end + + def self.redaction_handler + @redaction_handler + end + + @class_owner_finder = nil + # Set to a function which can get the 'owner' of a class. This is + # used in reporting deserialization errors + # + # @param [Lambda, Proc, nil] handler Proc that takes a class and + # produces its owner, or `nil` if it does not have one. + def self.class_owner_finder=(handler) + @class_owner_finder = handler + end + + def self.class_owner_finder + @class_owner_finder + end + + # Temporarily disable ruby warnings while executing the given block. This is + # useful when doing something that would normally cause a warning to be + # emitted in Ruby verbose mode ($VERBOSE = true). + # + # @yield + # + def self.without_ruby_warnings + if $VERBOSE + begin + original_verbose = $VERBOSE + $VERBOSE = false + yield + ensure + $VERBOSE = original_verbose + end + else + yield + end + end + + @legacy_t_enum_migration_mode = false + def self.enable_legacy_t_enum_migration_mode + @legacy_t_enum_migration_mode = true + end + def self.disable_legacy_t_enum_migration_mode + @legacy_t_enum_migration_mode = false + end + def self.legacy_t_enum_migration_mode? + @legacy_t_enum_migration_mode || false + end + + @prop_freeze_handler = ->(instance, prop_name) {} + + def self.prop_freeze_handler=(handler) + @prop_freeze_handler = handler + end + + def self.prop_freeze_handler + @prop_freeze_handler + end + + @sealed_violation_whitelist = nil + # @param [Array] sealed_violation_whitelist An array of Regexp to validate + # whether inheriting /including a sealed module outside the defining module + # should be allowed. Useful to whitelist benign violations, like shim files + # generated for an autoloader. + def self.sealed_violation_whitelist=(sealed_violation_whitelist) + if !@sealed_violation_whitelist.nil? + raise ArgumentError.new("Cannot overwrite sealed_violation_whitelist after setting it") + end + + case sealed_violation_whitelist + when Array + sealed_violation_whitelist.each do |x| + case x + when Regexp then nil + else raise TypeError.new("sealed_violation_whitelist accepts an Array of Regexp") + end + end + else + raise TypeError.new("sealed_violation_whitelist= accepts an Array of Regexp") + end + + @sealed_violation_whitelist = sealed_violation_whitelist + end + def self.sealed_violation_whitelist + @sealed_violation_whitelist + end + + private_class_method def self.validate_lambda_given!(value) + if !value.nil? && !value.respond_to?(:call) + raise ArgumentError.new("Provided value must respond to :call") + end + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/enum.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/enum.rb new file mode 100644 index 0000000000..c2de09abaf --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/enum.rb @@ -0,0 +1,377 @@ +# frozen_string_literal: true +# typed: strict + +# Enumerations allow for type-safe declarations of a fixed set of values. +# +# Every value is a singleton instance of the class (i.e. `Suit::SPADE.is_a?(Suit) == true`). +# +# Each value has a corresponding serialized value. By default this is the constant's name converted +# to lowercase (e.g. `Suit::Club.serialize == 'club'`); however a custom value may be passed to the +# constructor. Enum will `freeze` the serialized value. +# +# @example Declaring an Enum: +# class Suit < T::Enum +# enums do +# CLUB = new +# SPADE = new +# DIAMOND = new +# HEART = new +# end +# end +# +# @example Custom serialization value: +# class Status < T::Enum +# enums do +# READY = new('rdy') +# ... +# end +# end +# +# @example Accessing values: +# Suit::SPADE +# +# @example Converting from serialized value to enum instance: +# Suit.deserialize('club') == Suit::CLUB +# +# @example Using enums in type signatures: +# sig {params(suit: Suit).returns(Boolean)} +# def is_red?(suit); ...; end +# +# WARNING: Enum instances are singletons that are shared among all their users. Their internals +# should be kept immutable to avoid unpredictable action at a distance. +class T::Enum + extend T::Sig + extend T::Props::CustomType + + # TODO(jez) Might want to restrict this, or make subclasses provide this type + SerializedVal = T.type_alias {T.untyped} + private_constant :SerializedVal + + ### Enum class methods ### + sig {returns(T::Array[T.attached_class])} + def self.values + if @values.nil? + raise "Attempting to access values of #{self.class} before it has been initialized." \ + " Enums are not initialized until the 'enums do' block they are defined in has finished running." + end + @values + end + + # This exists for compatibility with the interface of `Hash` & mostly to support + # the HashEachMethods Rubocop. + sig {params(blk: T.nilable(T.proc.params(arg0: T.attached_class).void)).returns(T.any(T::Enumerator[T.attached_class], T::Array[T.attached_class]))} + def self.each_value(&blk) + if blk + values.each(&blk) + else + values.each + end + end + + # Convert from serialized value to enum instance + # + # Note: It would have been nice to make this method final before people started overriding it. + # Note: Failed CriticalMethodsNoRuntimeTypingTest + sig {params(serialized_val: SerializedVal).returns(T.nilable(T.attached_class)).checked(:never)} + def self.try_deserialize(serialized_val) + if @mapping.nil? + raise "Attempting to access serialization map of #{self.class} before it has been initialized." \ + " Enums are not initialized until the 'enums do' block they are defined in has finished running." + end + @mapping[serialized_val] + end + + # Convert from serialized value to enum instance. + # + # Note: It would have been nice to make this method final before people started overriding it. + # Note: Failed CriticalMethodsNoRuntimeTypingTest + # + # @return [self] + # @raise [KeyError] if serialized value does not match any instance. + sig {overridable.params(serialized_val: SerializedVal).returns(T.attached_class).checked(:never)} + def self.from_serialized(serialized_val) + res = try_deserialize(serialized_val) + if res.nil? + raise KeyError.new("Enum #{self} key not found: #{serialized_val.inspect}") + end + res + end + + # Note: It would have been nice to make this method final before people started overriding it. + # @return [Boolean] Does the given serialized value correspond with any of this enum's values. + sig {overridable.params(serialized_val: SerializedVal).returns(T::Boolean).checked(:never)} + def self.has_serialized?(serialized_val) + if @mapping.nil? + raise "Attempting to access serialization map of #{self.class} before it has been initialized." \ + " Enums are not initialized until the 'enums do' block they are defined in has finished running." + end + @mapping.include?(serialized_val) + end + + # Note: Failed CriticalMethodsNoRuntimeTypingTest + sig {override.params(instance: T.nilable(T::Enum)).returns(SerializedVal).checked(:never)} + def self.serialize(instance) + # This is needed otherwise if a Chalk::ODM::Document with a property of the shape + # T::Hash[T.nilable(MyEnum), Integer] and a value that looks like {nil => 0} is + # serialized, we throw the error on L102. + return nil if instance.nil? + + if self == T::Enum + raise "Cannot call T::Enum.serialize directly. You must call on a specific child class." + end + if instance.class != self + raise "Cannot call #serialize on a value that is not an instance of #{self}." + end + instance.serialize + end + + # Note: Failed CriticalMethodsNoRuntimeTypingTest + sig {override.params(mongo_value: SerializedVal).returns(T.attached_class).checked(:never)} + def self.deserialize(mongo_value) + if self == T::Enum + raise "Cannot call T::Enum.deserialize directly. You must call on a specific child class." + end + self.from_serialized(mongo_value) + end + + ### Enum instance methods ### + + sig {returns(T.self_type)} + def dup + self + end + + sig {returns(T.self_type).checked(:tests)} + def clone + self + end + + # Note: Failed CriticalMethodsNoRuntimeTypingTest + sig {returns(SerializedVal).checked(:never)} + def serialize + assert_bound! + @serialized_val + end + + sig {params(args: T.untyped).returns(T.untyped)} + def to_json(*args) + serialize.to_json(*args) + end + + sig {params(args: T.untyped).returns(T.untyped)} + def as_json(*args) + serialized_val = serialize + return serialized_val unless serialized_val.respond_to?(:as_json) + serialized_val.as_json(*args) + end + + sig {returns(String)} + def to_s + inspect + end + + sig {returns(String)} + def inspect + "#<#{self.class.name}::#{@const_name || '__UNINITIALIZED__'}>" + end + + sig {params(other: BasicObject).returns(T.nilable(Integer))} + def <=>(other) + case other + when self.class + self.serialize <=> other.serialize + else + nil + end + end + + # NB: Do not call this method. This exists to allow for a safe migration path in places where enum + # values are compared directly against string values. + # + # Ruby's string has a weird quirk where `'my_string' == obj` calls obj.==('my_string') if obj + # responds to the `to_str` method. It does not actually call `to_str` however. + # + # See https://ruby-doc.org/core-2.4.0/String.html#method-i-3D-3D + sig {returns(String)} + def to_str + msg = 'Implicit conversion of Enum instances to strings is not allowed. Call #serialize instead.' + if T::Configuration.legacy_t_enum_migration_mode? + T::Configuration.soft_assert_handler( + msg, + storytime: {class: self.class.name}, + ) + serialize.to_s + else + raise NoMethodError.new(msg) + end + end + + sig {params(other: BasicObject).returns(T::Boolean).checked(:never)} + def ==(other) + case other + when String + if T::Configuration.legacy_t_enum_migration_mode? + comparison_assertion_failed(:==, other) + self.serialize == other + else + false + end + else + super(other) + end + end + + sig {params(other: BasicObject).returns(T::Boolean).checked(:never)} + def ===(other) + case other + when String + if T::Configuration.legacy_t_enum_migration_mode? + comparison_assertion_failed(:===, other) + self.serialize == other + else + false + end + else + super(other) + end + end + + sig {params(method: Symbol, other: T.untyped).void} + private def comparison_assertion_failed(method, other) + T::Configuration.soft_assert_handler( + 'Enum to string comparison not allowed. Compare to the Enum instance directly instead. See go/enum-migration', + storytime: { + class: self.class.name, + self: self.inspect, + other: other, + other_class: other.class.name, + method: method, + } + ) + end + + ### Private implementation ### + + sig {params(serialized_val: SerializedVal).void} + def initialize(serialized_val=nil) + raise 'T::Enum is abstract' if self.class == T::Enum + if !self.class.started_initializing? + raise "Must instantiate all enum values of #{self.class} inside 'enums do'." + end + if self.class.fully_initialized? + raise "Cannot instantiate a new enum value of #{self.class} after it has been initialized." + end + + serialized_val = serialized_val.frozen? ? serialized_val : serialized_val.dup.freeze + @serialized_val = T.let(serialized_val, T.nilable(SerializedVal)) + @const_name = T.let(nil, T.nilable(Symbol)) + self.class._register_instance(self) + end + + sig {returns(NilClass).checked(:never)} + private def assert_bound! + if @const_name.nil? + raise "Attempting to access Enum value on #{self.class} before it has been initialized." \ + " Enums are not initialized until the 'enums do' block they are defined in has finished running." + end + end + + sig {params(const_name: Symbol).void} + def _bind_name(const_name) + @const_name = const_name + @serialized_val = const_to_serialized_val(const_name) if @serialized_val.nil? + freeze + end + + sig {params(const_name: Symbol).returns(String)} + private def const_to_serialized_val(const_name) + # Historical note: We convert to lowercase names because the majority of existing calls to + # `make_accessible` were arrays of lowercase strings. Doing this conversion allowed for the + # least amount of repetition in migrated declarations. + -const_name.to_s.downcase.freeze + end + + sig {returns(T::Boolean)} + def self.started_initializing? + unless defined?(@started_initializing) + @started_initializing = T.let(false, T.nilable(T::Boolean)) + end + T.must(@started_initializing) + end + + sig {returns(T::Boolean)} + def self.fully_initialized? + unless defined?(@fully_initialized) + @fully_initialized = T.let(false, T.nilable(T::Boolean)) + end + T.must(@fully_initialized) + end + + # Maintains the order in which values are defined + sig {params(instance: T.untyped).void} + def self._register_instance(instance) + @values ||= [] + @values << T.cast(instance, T.attached_class) + end + + # Entrypoint for allowing people to register new enum values. + # All enum values must be defined within this block. + sig {params(blk: T.proc.void).void} + def self.enums(&blk) + raise "enums cannot be defined for T::Enum" if self == T::Enum + raise "Enum #{self} was already initialized" if fully_initialized? + raise "Enum #{self} is still initializing" if started_initializing? + + @started_initializing = true + + @values = T.let(nil, T.nilable(T::Array[T.attached_class])) + + yield + + @mapping = T.let(nil, T.nilable(T::Hash[SerializedVal, T.attached_class])) + @mapping = {} + + # Freeze the Enum class and bind the constant names into each of the instances. + self.constants(false).each do |const_name| + instance = self.const_get(const_name, false) + if !instance.is_a?(self) + raise "Invalid constant #{self}::#{const_name} on enum. " \ + "All constants defined for an enum must be instances itself (e.g. `Foo = new`)." + end + + instance._bind_name(const_name) + serialized = instance.serialize + if @mapping.include?(serialized) + raise "Enum values must have unique serializations. Value '#{serialized}' is repeated on #{self}." + end + @mapping[serialized] = instance + end + @values.freeze + @mapping.freeze + + orphaned_instances = T.must(@values) - @mapping.values + if !orphaned_instances.empty? + raise "Enum values must be assigned to constants: #{orphaned_instances.map {|v| v.instance_variable_get('@serialized_val')}}" + end + + @fully_initialized = true + end + + sig {params(child_class: Module).void} + def self.inherited(child_class) + super + + raise "Inheriting from children of T::Enum is prohibited" if self != T::Enum + end + + # Marshal support + sig {params(_level: Integer).returns(String)} + def _dump(_level) + Marshal.dump(serialize) + end + + sig {params(args: String).returns(T.attached_class)} + def self._load(args) + deserialize(Marshal.load(args)) # rubocop:disable Security/MarshalLoad + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/generic.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/generic.rb new file mode 100644 index 0000000000..58def7aa1a --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/generic.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true +# typed: true + +# Use as a mixin with extend (`extend T::Generic`). +module T::Generic + include T::Helpers + include Kernel + + ### Class/Module Helpers ### + + def [](*types) + self + end + + def type_member(variance=:invariant, &blk) + T::Types::TypeMember.new(variance) + end + + def type_template(variance=:invariant, &blk) + T::Types::TypeTemplate.new(variance) + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/helpers.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/helpers.rb new file mode 100644 index 0000000000..7f326e7384 --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/helpers.rb @@ -0,0 +1,58 @@ +# frozen_string_literal: true +# typed: true + +# Use as a mixin with extend (`extend T::Helpers`). +# Docs at https://sorbet.org/docs/ +module T::Helpers + extend T::Sig + + Private = T::Private + + ### Class/Module Helpers ### + + def abstract! + Private::Abstract::Declare.declare_abstract(self, type: :abstract) + end + + def interface! + Private::Abstract::Declare.declare_abstract(self, type: :interface) + end + + def final! + Private::Final.declare(self) + end + + def sealed! + Private::Sealed.declare(self, Kernel.caller(1..1)&.first&.split(':')&.first) + end + + # Causes a mixin to also mix in class methods from the named module. + # + # Nearly equivalent to + # + # def self.included(other) + # other.extend(mod) + # end + # + # Except that it is statically analyzed by sorbet. + def mixes_in_class_methods(mod, *mods) + Private::Mixins.declare_mixes_in_class_methods(self, [mod].concat(mods)) + end + + # Specify an inclusion or inheritance requirement for `self`. + # + # Example: + # + # module MyHelper + # extend T::Helpers + # + # requires_ancestor { Kernel } + # end + # + # class MyClass < BasicObject # error: `MyClass` must include `Kernel` (required by `MyHelper`) + # include MyHelper + # end + # + # TODO: implement the checks in sorbet-runtime. + def requires_ancestor(&block); end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/interface_wrapper.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/interface_wrapper.rb new file mode 100644 index 0000000000..82998667f7 --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/interface_wrapper.rb @@ -0,0 +1,158 @@ +# frozen_string_literal: true +# typed: false + +# Wraps an object, exposing only the methods defined on a given class/module. The idea is that, in +# the absence of a static type checker that would prevent you from calling non-Bar methods on a +# variable of type Bar, we can use these wrappers as a way of enforcing it at runtime. +# +# Once we ship static type checking, we should get rid of this entirely. +class T::InterfaceWrapper + extend T::Sig + + module Helpers + def wrap_instance(obj) + T::InterfaceWrapper.wrap_instance(obj, self) + end + + def wrap_instances(arr) + T::InterfaceWrapper.wrap_instances(arr, self) + end + end + + private_class_method :new # use `wrap_instance` + + def self.wrap_instance(obj, interface_mod) + wrapper = wrapped_dynamic_cast(obj, interface_mod) + if wrapper.nil? + raise "#{obj.class} cannot be cast to #{interface_mod}" + end + wrapper + end + + sig do + params( + arr: Array, + interface_mod: T.untyped + ) + .returns(Array) + end + def self.wrap_instances(arr, interface_mod) + arr.map {|instance| self.wrap_instance(instance, interface_mod)} + end + + def initialize(target_obj, interface_mod) + if target_obj.is_a?(T::InterfaceWrapper) + # wrapped_dynamic_cast should guarantee this never happens. + raise "Unexpected: wrapping a wrapper. Please report this bug at https://github.com/sorbet/sorbet/issues" + end + + if !target_obj.is_a?(interface_mod) + # wrapped_dynamic_cast should guarantee this never happens. + raise "Unexpected: `is_a?` failed. Please report this bug at https://github.com/sorbet/sorbet/issues" + end + + if target_obj.class == interface_mod + # wrapped_dynamic_cast should guarantee this never happens. + raise "Unexpected: exact class match. Please report this bug at https://github.com/sorbet/sorbet/issues" + end + + @target_obj = target_obj + @interface_mod = interface_mod + self_methods = self.class.self_methods + + # If perf becomes an issue, we can define these on an anonymous subclass, and keep a cache + # so we only need to do it once per unique `interface_mod` + T::Utils.methods_excluding_object(interface_mod).each do |method_name| + if self_methods.include?(method_name) + raise "interface_mod has a method that conflicts with #{self.class}: #{method_name}" + end + + define_singleton_method(method_name) do |*args, &blk| + target_obj.send(method_name, *args, &blk) + end + + if target_obj.singleton_class.public_method_defined?(method_name) + # no-op, it's already public + elsif target_obj.singleton_class.protected_method_defined?(method_name) + singleton_class.send(:protected, method_name) + elsif target_obj.singleton_class.private_method_defined?(method_name) + singleton_class.send(:private, method_name) + else + raise "This should never happen. Report this bug at https://github.com/sorbet/sorbet/issues" + end + end + end + + def kind_of?(other) + is_a?(other) + end + + def is_a?(other) + if !other.is_a?(Module) + raise TypeError.new("class or module required") + end + + # This makes is_a? return true for T::InterfaceWrapper (and its ancestors), + # as well as for @interface_mod and its ancestors. + self.class <= other || @interface_mod <= other + end + + # Prefixed because we're polluting the namespace of the interface we're wrapping, and we don't + # want anyone else (besides dynamic_cast) calling it. + def __target_obj_DO_NOT_USE # rubocop:disable Naming/MethodName + @target_obj + end + + # Prefixed because we're polluting the namespace of the interface we're wrapping, and we don't + # want anyone else (besides wrapped_dynamic_cast) calling it. + def __interface_mod_DO_NOT_USE # rubocop:disable Naming/MethodName + @interface_mod + end + + # "Cast" an object to another type. If `obj` is an InterfaceWrapper, returns the the wrapped + # object if that matches `type`. Otherwise, returns `obj` if it matches `type`. Otherwise, + # returns nil. + # + # @param obj [Object] object to cast + # @param mod [Module] type to cast `obj` to + # + # @example + # if (impl = T::InterfaceWrapper.dynamic_cast(iface, MyImplementation)) + # impl.do_things + # end + def self.dynamic_cast(obj, mod) + if obj.is_a?(T::InterfaceWrapper) + target_obj = obj.__target_obj_DO_NOT_USE + target_obj.is_a?(mod) ? target_obj : nil + elsif obj.is_a?(mod) + obj + else + nil + end + end + + # Like dynamic_cast, but puts the result in its own wrapper if necessary. + # + # @param obj [Object] object to cast + # @param mod [Module] type to cast `obj` to + def self.wrapped_dynamic_cast(obj, mod) + # Avoid unwrapping and creating an equivalent wrapper. + if obj.is_a?(T::InterfaceWrapper) && obj.__interface_mod_DO_NOT_USE == mod + return obj + end + + cast_obj = dynamic_cast(obj, mod) + if cast_obj.nil? + nil + elsif cast_obj.class == mod + # Nothing to wrap, they want the full class + cast_obj + else + new(cast_obj, mod) + end + end + + def self.self_methods + @self_methods ||= self.instance_methods(false).to_set + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/non_forcing_constants.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/non_forcing_constants.rb new file mode 100644 index 0000000000..96445357cb --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/non_forcing_constants.rb @@ -0,0 +1,65 @@ +# frozen_string_literal: true +# typed: strict + +module T::NonForcingConstants + # NOTE: This method is documented on the RBI in Sorbet's payload, so that it + # shows up in the hover/completion documentation via LSP. + T::Sig::WithoutRuntime.sig {params(val: BasicObject, klass: String, package: T.nilable(String)).returns(T::Boolean)} + def self.non_forcing_is_a?(val, klass, package: nil) + method_name = "T::NonForcingConstants.non_forcing_is_a?" + if klass.empty? + raise ArgumentError.new("The string given to `#{method_name}` must not be empty") + end + + # We don't treat packages differently at runtime, but the static + # type-checker still needs to have the package and constant + # separated out. This just re-assembles the string as needed + if !package.nil? + klass = "::#{package}::#{klass}" + end + + current_klass = T.let(nil, T.nilable(Module)) + current_prefix = T.let(nil, T.nilable(String)) + + parts = klass.split('::') + parts.each do |part| + if current_klass.nil? + # First iteration + if part != "" && package.nil? + # if we've supplied a package, we're probably running in + # package mode, which means absolute references are + # meaningless + raise ArgumentError.new("The string given to `#{method_name}` must be an absolute constant reference that starts with `::`") + end + + current_klass = Object + current_prefix = '' + + # if this had a :: prefix, then there's no more loading to + # do---skip to the next one + next if part == "" + end + + if current_klass.autoload?(part) + # There's an autoload registered for that constant, which means it's not + # yet loaded. `value` can't be an instance of something not yet loaded. + return false + end + + # Sorbet guarantees that the string is an absolutely resolved name. + search_inheritance_chain = false + if !current_klass.const_defined?(part, search_inheritance_chain) + return false + end + + current_klass = current_klass.const_get(part) + current_prefix = "#{current_prefix}::#{part}" + + if !Module.===(current_klass) + raise ArgumentError.new("#{current_prefix} is not a class or module") + end + end + + current_klass.===(val) + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/abstract/data.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/abstract/data.rb new file mode 100644 index 0000000000..2692858ddf --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/abstract/data.rb @@ -0,0 +1,36 @@ +# frozen_string_literal: true +# typed: true + +# We need to associate data with abstract modules. We could add instance methods to them that +# access ivars, but those methods will unnecessarily pollute the module namespace, and they'd +# have access to other private state and methods that they don't actually need. We also need to +# associate data with arbitrary classes/modules that implement abstract mixins, where we don't +# control the interface at all. So, we access data via these `get` and `set` methods. +# +# Using instance_variable_get/set here is gross, but the alternative is to use a hash keyed on +# `mod`, and we can't trust that arbitrary modules can be added to those, because there are lurky +# modules that override the `hash` method with something completely broken. +module T::Private::Abstract::Data + def self.get(mod, key) + mod.instance_variable_get("@opus_abstract__#{key}") if key?(mod, key) + end + + def self.set(mod, key, value) + mod.instance_variable_set("@opus_abstract__#{key}", value) + end + + def self.key?(mod, key) + mod.instance_variable_defined?("@opus_abstract__#{key}") + end + + # Works like `setdefault` in Python. If key has already been set, return its value. If not, + # insert `key` with a value of `default` and return `default`. + def self.set_default(mod, key, default) + if self.key?(mod, key) + self.get(mod, key) + else + self.set(mod, key, default) + default + end + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/abstract/declare.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/abstract/declare.rb new file mode 100644 index 0000000000..ce8ddf9531 --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/abstract/declare.rb @@ -0,0 +1,53 @@ +# frozen_string_literal: true +# typed: true + +module T::Private::Abstract::Declare + Abstract = T::Private::Abstract + AbstractUtils = T::AbstractUtils + + def self.declare_abstract(mod, type:) + if AbstractUtils.abstract_module?(mod) + raise "#{mod} is already declared as abstract" + end + if T::Private::Final.final_module?(mod) + raise "#{mod} was already declared as final and cannot be declared as abstract" + end + + Abstract::Data.set(mod, :can_have_abstract_methods, true) + Abstract::Data.set(mod.singleton_class, :can_have_abstract_methods, true) + Abstract::Data.set(mod, :abstract_type, type) + + mod.extend(Abstract::Hooks) + mod.extend(T::InterfaceWrapper::Helpers) + + if mod.is_a?(Class) + if type == :interface + # Since `interface!` is just `abstract!` with some extra validation, we could technically + # allow this, but it's unclear there are good use cases, and it might be confusing. + raise "Classes can't be interfaces. Use `abstract!` instead of `interface!`." + end + + if mod.instance_method(:initialize).owner == mod + raise "You must call `abstract!` *before* defining an initialize method" + end + + # Don't need to silence warnings via without_ruby_warnings when calling + # define_method because of the guard above + + mod.send(:define_method, :initialize) do |*args, &blk| + if self.class == mod + raise "#{mod} is declared as abstract; it cannot be instantiated" + end + super(*args, &blk) + end + + # Ruby doesn not emit "method redefined" warnings for aliased methods + # (more robust than undef_method that would create a small window in which the method doesn't exist) + mod.send(:alias_method, :initialize, :initialize) + + if mod.respond_to?(:ruby2_keywords, true) + mod.send(:ruby2_keywords, :initialize) + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/abstract/hooks.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/abstract/hooks.rb new file mode 100644 index 0000000000..fae9593ae8 --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/abstract/hooks.rb @@ -0,0 +1,42 @@ +# frozen_string_literal: true +# typed: true + +module T::Private::Abstract::Hooks + # This will become the self.extend_object method on a module that extends Abstract::Hooks. + # It gets called when *that* module gets extended in another class/module (similar to the + # `extended` hook, but this gets calls before the ancestors of `other` get modified, which + # is important for our validation). + private def extend_object(other) + T::Private::Abstract::Data.set(self, :last_used_by, other) + super + end + + # This will become the self.append_features method on a module that extends Abstract::Hooks. + # It gets called when *that* module gets included in another class/module (similar to the + # `included` hook, but this gets calls before the ancestors of `other` get modified, which + # is important for our validation). + private def append_features(other) + T::Private::Abstract::Data.set(self, :last_used_by, other) + super + end + + # This will become the self.inherited method on a class that extends Abstract::Hooks. + # It gets called when *that* class gets inherited by another class. + private def inherited(other) + super + # `self` may not actually be abstract -- it could be a concrete class that inherited from an + # abstract class. We only need to check this in `inherited` because, for modules being included + # or extended, the concrete ones won't have these hooks at all. This is just an optimization. + return if !T::AbstractUtils.abstract_module?(self) + + T::Private::Abstract::Data.set(self, :last_used_by, other) + end + + # This will become the self.prepended method on a module that extends Abstract::Hooks. + # It will get called when *that* module gets prepended in another class/module. + private def prepended(other) + # Prepending abstract methods is weird. You'd only be able to override them via other prepended + # modules, or in subclasses. Punt until we have a use case. + Kernel.raise "Prepending abstract mixins is not currently supported." + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/abstract/validate.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/abstract/validate.rb new file mode 100644 index 0000000000..ba0b57775c --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/abstract/validate.rb @@ -0,0 +1,128 @@ +# frozen_string_literal: true +# typed: true + +module T::Private::Abstract::Validate + Abstract = T::Private::Abstract + AbstractUtils = T::AbstractUtils + Methods = T::Private::Methods + SignatureValidation = T::Private::Methods::SignatureValidation + + def self.validate_abstract_module(mod) + type = Abstract::Data.get(mod, :abstract_type) + validate_interface(mod) if type == :interface + end + + # Validates a class/module with an abstract class/module as an ancestor. This must be called + # after all methods on `mod` have been defined. + def self.validate_subclass(mod) + can_have_abstract_methods = !T::Private::Abstract::Data.get(mod, :can_have_abstract_methods) + unimplemented_methods = [] + + T::AbstractUtils.declared_abstract_methods_for(mod).each do |abstract_method| + implementation_method = mod.instance_method(abstract_method.name) + if AbstractUtils.abstract_method?(implementation_method) + # Note that when we end up here, implementation_method might not be the same as + # abstract_method; the latter could've been overridden by another abstract method. In either + # case, if we have a concrete definition in an ancestor, that will end up as the effective + # implementation (see CallValidation.wrap_method_if_needed), so that's what we'll validate + # against. + implementation_method = T.unsafe(nil) + mod.ancestors.each do |ancestor| + if ancestor.instance_methods.include?(abstract_method.name) + method = ancestor.instance_method(abstract_method.name) + T::Private::Methods.maybe_run_sig_block_for_method(method) + if !T::AbstractUtils.abstract_method?(method) + implementation_method = method + break + end + end + end + if !implementation_method + # There's no implementation + if can_have_abstract_methods + unimplemented_methods << describe_method(abstract_method) + end + next # Nothing to validate + end + end + + implementation_signature = Methods.signature_for_method(implementation_method) + # When a signature exists and the method is defined directly on `mod`, we skip the validation + # here, because it will have already been done when the method was defined (by + # T::Private::Methods._on_method_added). + next if implementation_signature&.owner == mod + + # We validate the remaining cases here: (a) methods defined directly on `mod` without a + # signature and (b) methods from ancestors (note that these ancestors can come before or + # after the abstract module in the inheritance chain -- the former coming from + # walking `mod.ancestors` above). + abstract_signature = Methods.signature_for_method(abstract_method) + # We allow implementation methods to be defined without a signature. + # In that case, get its untyped signature. + implementation_signature ||= Methods::Signature.new_untyped( + method: implementation_method, + mode: Methods::Modes.override + ) + SignatureValidation.validate_override_shape(implementation_signature, abstract_signature) + SignatureValidation.validate_override_types(implementation_signature, abstract_signature) + end + + method_type = mod.singleton_class? ? "class" : "instance" + if !unimplemented_methods.empty? + raise "Missing implementation for abstract #{method_type} method(s) in #{mod}:\n" \ + "#{unimplemented_methods.join("\n")}\n" \ + "If #{mod} is meant to be an abstract class/module, you can call " \ + "`abstract!` or `interface!`. Otherwise, you must implement the method(s)." + end + end + + private_class_method def self.validate_interface_all_abstract(mod, method_names) + violations = method_names.map do |method_name| + method = mod.instance_method(method_name) + if !AbstractUtils.abstract_method?(method) + describe_method(method, show_owner: false) + end + end.compact + + if !violations.empty? + raise "`#{mod}` is declared as an interface, but the following methods are not declared " \ + "with `abstract`:\n#{violations.join("\n")}" + end + end + + private_class_method def self.validate_interface(mod) + interface_methods = T::Utils.methods_excluding_object(mod) + validate_interface_all_abstract(mod, interface_methods) + validate_interface_all_public(mod, interface_methods) + end + + private_class_method def self.validate_interface_all_public(mod, method_names) + violations = method_names.map do |method_name| + if !mod.public_method_defined?(method_name) + describe_method(mod.instance_method(method_name), show_owner: false) + end + end.compact + + if !violations.empty? + raise "All methods on an interface must be public. If you intend to have non-public " \ + "methods, declare your class/module using `abstract!` instead of `interface!`. " \ + "The following methods on `#{mod}` are not public: \n#{violations.join("\n")}" + end + end + + private_class_method def self.describe_method(method, show_owner: true) + loc = if method.source_location + method.source_location.join(':') + else + "" + end + + owner = if show_owner + " declared in #{method.owner}" + else + "" + end + + " * `#{method.name}`#{owner} at #{loc}" + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/casts.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/casts.rb new file mode 100644 index 0000000000..f771090814 --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/casts.rb @@ -0,0 +1,41 @@ +# frozen_string_literal: true +# typed: false + +module T::Private + module Casts + def self.cast(value, type, cast_method:) + begin + error = T::Utils.coerce(type).error_message_for_obj(value) + return value unless error + + caller_loc = T.must(caller_locations(2..2)).first + + suffix = "Caller: #{T.must(caller_loc).path}:#{T.must(caller_loc).lineno}" + + raise TypeError.new("#{cast_method}: #{error}\n#{suffix}") + rescue TypeError => e # raise into rescue to ensure e.backtrace is populated + T::Configuration.inline_type_error_handler(e, {kind: cast_method, value: value, type: type}) + value + end + end + + # there's a lot of shared logic with the above one, but factoring + # it out like this makes it easier to hopefully one day delete + # this one + def self.cast_recursive(value, type, cast_method:) + begin + error = T::Utils.coerce(type).error_message_for_obj_recursive(value) + return value unless error + + caller_loc = T.must(caller_locations(2..2)).first + + suffix = "Caller: #{T.must(caller_loc).path}:#{T.must(caller_loc).lineno}" + + raise TypeError.new("#{cast_method}: #{error}\n#{suffix}") + rescue TypeError => e # raise into rescue to ensure e.backtrace is populated + T::Configuration.inline_type_error_handler(e, {kind: cast_method, value: value, type: type}) + value + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/class_utils.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/class_utils.rb new file mode 100644 index 0000000000..269b70cbee --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/class_utils.rb @@ -0,0 +1,110 @@ +# frozen_string_literal: true +# typed: false + +# Cut down version of Chalk::Tools::ClassUtils with only :replace_method functionality. +# Extracted to a separate namespace so the type system can be used standalone. +module T::Private::ClassUtils + class ReplacedMethod + def initialize(mod, old_method, new_method, overwritten, visibility) + if old_method.name != new_method.name + raise "Method names must match. old=#{old_method.name} new=#{new_method.name}" + end + @mod = mod + @old_method = old_method + @new_method = new_method + @overwritten = overwritten + @name = old_method.name + @visibility = visibility + @restored = false + end + + def restore + # The check below would also catch this, but this makes the failure mode much clearer + if @restored + raise "Method '#{@name}' on '#{@mod}' was already restored" + end + + if @mod.instance_method(@name) != @new_method + raise "Trying to restore #{@mod}##{@name} but the method has changed since the call to replace_method" + end + + @restored = true + + if @overwritten + # The original method was overwritten. Overwrite again to restore it. + T::Configuration.without_ruby_warnings do + @mod.send(:define_method, @old_method.name, @old_method) + end + else + # The original method was in an ancestor. Restore it by removing the overriding method. + @mod.send(:remove_method, @old_method.name) + end + + # Restore the visibility. Note that we need to do this even when we call remove_method + # above, because the module may have set custom visibility for a method it inherited. + @mod.send(@visibility, @old_method.name) + + nil + end + + def bind(obj) + @old_method.bind(obj) + end + + def to_s + @old_method.to_s + end + end + + # `name` must be an instance method (for class methods, pass in mod.singleton_class) + private_class_method def self.visibility_method_name(mod, name) + if mod.public_method_defined?(name) + :public + elsif mod.protected_method_defined?(name) + :protected + elsif mod.private_method_defined?(name) + :private + else + raise NameError.new("undefined method `#{name}` for `#{mod}`") + end + end + + # Replaces a method, either by overwriting it (if it is defined directly on `mod`) or by + # overriding it (if it is defined by one of mod's ancestors). Returns a ReplacedMethod instance + # on which you can call `bind(...).call(...)` to call the original method, or `restore` to + # restore the original method (by overwriting or removing the override). + def self.replace_method(mod, name, &blk) + original_method = mod.instance_method(name) + original_visibility = visibility_method_name(mod, name) + original_owner = original_method.owner + + mod.ancestors.each do |ancestor| + break if ancestor == mod + if ancestor == original_owner + # If we get here, that means the method we're trying to replace exists on a *prepended* + # mixin, which means in order to supersede it, we'd need to create a method on a new + # module that we'd prepend before `ancestor`. The problem with that approach is there'd + # be no way to remove that new module after prepending it, so we'd be left with these + # empty anonymous modules in the ancestor chain after calling `restore`. + # + # That's not necessarily a deal breaker, but for now, we're keeping it as unsupported. + raise "You're trying to replace `#{name}` on `#{mod}`, but that method exists in a " \ + "prepended module (#{ancestor}), which we don't currently support." + end + end + + overwritten = original_owner == mod + T::Configuration.without_ruby_warnings do + T::Private::DeclState.current.without_on_method_added do + mod.send(:define_method, name, &blk) + if blk.arity < 0 && mod.respond_to?(:ruby2_keywords, true) + mod.send(:ruby2_keywords, name) + end + end + end + mod.send(original_visibility, name) + new_method = mod.instance_method(name) + + ReplacedMethod.new(mod, original_method, new_method, overwritten, original_visibility) + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/compiler.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/compiler.rb new file mode 100644 index 0000000000..fed86b40f3 --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/compiler.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true +# typed: true + +module T::Private + module Compiler + # If this code ever runs, the caller is running interpreted (or the + # compiler didn't see the call to `running_compiled?` statically.) + # + # The Sorbet Compiler replaces calls to this method unconditionally (no + # runtime guards) to return `true` when compiling a file. + def self.running_compiled? + false + end + + # Returns `nil` because the compiler isn't running. + # + # The Sorbet Compiler replaces calls to this method unconditionally (no + # runtime guards) to return a String showing the Sorbet Compiler's version + # string. + def self.compiler_version + nil + end + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/decl_state.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/decl_state.rb new file mode 100644 index 0000000000..8eeae57e4c --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/decl_state.rb @@ -0,0 +1,30 @@ +# frozen_string_literal: true +# typed: true + +class T::Private::DeclState + def self.current + Thread.current[:opus_types__decl_state] ||= self.new + end + + def self.current=(other) + Thread.current[:opus_types__decl_state] = other + end + + attr_accessor :active_declaration + attr_accessor :skip_on_method_added + + def reset! + self.active_declaration = nil + end + + def without_on_method_added + begin + # explicit 'self' is needed here + old_value = self.skip_on_method_added + self.skip_on_method_added = true + yield + ensure + self.skip_on_method_added = old_value + end + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/final.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/final.rb new file mode 100644 index 0000000000..9ca747248e --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/final.rb @@ -0,0 +1,50 @@ +# frozen_string_literal: true +# typed: false + +module T::Private::Final + module NoInherit + def inherited(arg) + super(arg) + raise "#{self} was declared as final and cannot be inherited" + end + end + + module NoIncludeExtend + def included(arg) + super(arg) + raise "#{self} was declared as final and cannot be included" + end + + def extended(arg) + super(arg) + raise "#{self} was declared as final and cannot be extended" + end + end + + def self.declare(mod) + if !mod.is_a?(Module) + raise "#{mod} is not a class or module and cannot be declared as final with `final!`" + end + if final_module?(mod) + raise "#{mod} was already declared as final and cannot be re-declared as final" + end + if T::AbstractUtils.abstract_module?(mod) + raise "#{mod} was already declared as abstract and cannot be declared as final" + end + if T::Private::Sealed.sealed_module?(mod) + raise "#{mod} was already declared as sealed and cannot be declared as final" + end + mod.extend(mod.is_a?(Class) ? NoInherit : NoIncludeExtend) + mark_as_final_module(mod) + mark_as_final_module(mod.singleton_class) + T::Private::Methods.install_hooks(mod) + end + + def self.final_module?(mod) + mod.instance_variable_defined?(:@sorbet_final_module) + end + + private_class_method def self.mark_as_final_module(mod) + mod.instance_variable_set(:@sorbet_final_module, true) + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/_methods.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/_methods.rb new file mode 100644 index 0000000000..1720892a95 --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/_methods.rb @@ -0,0 +1,581 @@ +# frozen_string_literal: true +# typed: false + +module T::Private::Methods + @installed_hooks = {} + @signatures_by_method = {} + @sig_wrappers = {} + @sigs_that_raised = {} + # stores method names that were declared final without regard for where. + # enables early rejection of names that we know can't induce final method violations. + @was_ever_final_names = {} + # maps from a module's object_id to the set of final methods declared in that module. + # we also overload entries slightly: if the value is nil, that means that the + # module has final methods somewhere along its ancestor chain, but does not itself + # have any final methods. + # + # we need the latter information to know whether we need to check along the ancestor + # chain for final method violations. we need the former information because we + # care about exactly where a final method is defined (e.g. including the same module + # twice is permitted). we could do this with two tables, but it seems slightly + # cleaner with a single table. + # Effectively T::Hash[Module, T.nilable(Set))] + @modules_with_final = Hash.new {|hash, key| hash[key] = nil} + # this stores the old [included, extended] hooks for Module and inherited hook for Class that we override when + # enabling final checks for when those hooks are called. the 'hooks' here don't have anything to do with the 'hooks' + # in installed_hooks. + @old_hooks = nil + + ARG_NOT_PROVIDED = Object.new + PROC_TYPE = Object.new + + DeclarationBlock = Struct.new(:mod, :loc, :blk, :final, :raw) + + def self.declare_sig(mod, loc, arg, &blk) + T::Private::DeclState.current.active_declaration = _declare_sig_internal(mod, loc, arg, &blk) + + nil + end + + # See tests for how to use this. But you shouldn't be using this. + def self._declare_sig(mod, arg=nil, &blk) + _declare_sig_internal(mod, caller_locations(1, 1).first, arg, raw: true, &blk) + end + + private_class_method def self._declare_sig_internal(mod, loc, arg, raw: false, &blk) + install_hooks(mod) + + if T::Private::DeclState.current.active_declaration + T::Private::DeclState.current.reset! + raise "You called sig twice without declaring a method in between" + end + + if !arg.nil? && arg != :final + raise "Invalid argument to `sig`: #{arg}" + end + + DeclarationBlock.new(mod, loc, blk, arg == :final, raw) + end + + def self._with_declared_signature(mod, declblock, &blk) + # If declblock is provided, this code is equivalent to the check in + # _declare_sig_internal, above. + # If declblock is not provided and we have an active declaration, we are + # obviously doing something wrong. + if T::Private::DeclState.current.active_declaration + T::Private::DeclState.current.reset! + raise "You called sig twice without declaring a method in between" + end + if declblock + T::Private::DeclState.current.active_declaration = declblock + end + mod.module_exec(&blk) + end + + def self.start_proc + DeclBuilder.new(PROC_TYPE, false) + end + + def self.finalize_proc(decl) + decl.finalized = true + + if decl.mode != Modes.standard + raise "Procs cannot have override/abstract modifiers" + end + if decl.mod != PROC_TYPE + raise "You are passing a DeclBuilder as a type. Did you accidentally use `self` inside a `sig` block?" + end + if decl.returns == ARG_NOT_PROVIDED + raise "Procs must specify a return type" + end + if decl.on_failure != ARG_NOT_PROVIDED + raise "Procs cannot use .on_failure" + end + + if decl.params == ARG_NOT_PROVIDED + decl.params = {} + end + + T::Types::Proc.new(decl.params, decl.returns) + end + + # Returns the signature for a method whose definition was preceded by `sig`. + # + # @param method [UnboundMethod] + # @return [T::Private::Methods::Signature] + def self.signature_for_method(method) + signature_for_key(method_to_key(method)) + end + + private_class_method def self.signature_for_key(key) + maybe_run_sig_block_for_key(key) + + # If a subclass Sub inherits a method `foo` from Base, then + # Sub.instance_method(:foo) != Base.instance_method(:foo) even though they resolve to the + # same method. Similarly, Foo.method(:bar) != Foo.singleton_class.instance_method(:bar). + # So, we always do the look up by the method on the owner (Base in this example). + @signatures_by_method[key] + end + + # when target includes a module with instance methods source_method_names, ensure there is zero intersection between + # the final instance methods of target and source_method_names. so, for every m in source_method_names, check if there + # is already a method defined on one of target_ancestors with the same name that is final. + # + # we assume that source_method_names has already been filtered to only include method + # names that were declared final at one point. + def self._check_final_ancestors(target, target_ancestors, source_method_names, source) + source_ancestors = nil + # use reverse_each to check farther-up ancestors first, for better error messages. + target_ancestors.reverse_each do |ancestor| + final_methods = @modules_with_final.fetch(ancestor.object_id, nil) + # In this case, either ancestor didn't have any final methods anywhere in its + # ancestor chain, or ancestor did have final methods somewhere in its ancestor + # chain, but no final methods defined in ancestor itself. Either way, there + # are no final methods to check here, so we can move on to the next ancestor. + next unless final_methods + source_method_names.each do |method_name| + next unless final_methods.include?(method_name) + + # If we get here, we are defining a method that some ancestor declared as + # final. however, we permit a final method to be defined multiple + # times if it is the same final method being defined each time. + if source + if !source_ancestors + source_ancestors = source.ancestors + # filter out things without actual final methods just to make sure that + # the below checks (which should be uncommon) go as quickly as possible. + source_ancestors.select! do |a| + @modules_with_final.fetch(a.object_id, nil) + end + end + # final-ness means that there should be no more than one index for which + # the below block returns true. + defining_ancestor_idx = source_ancestors.index do |a| + @modules_with_final.fetch(a.object_id).include?(method_name) + end + next if defining_ancestor_idx && source_ancestors[defining_ancestor_idx] == ancestor + end + + definition_file, definition_line = T::Private::Methods.signature_for_method(ancestor.instance_method(method_name)).method.source_location + is_redefined = target == ancestor + caller_loc = caller_locations&.find {|l| !l.to_s.match?(%r{sorbet-runtime[^/]*/lib/})} + extra_info = "\n" + if caller_loc + extra_info = (is_redefined ? "Redefined" : "Overridden") + " here: #{caller_loc.path}:#{caller_loc.lineno}\n" + end + + error_message = "The method `#{method_name}` on #{ancestor} was declared as final and cannot be " + + (is_redefined ? "redefined" : "overridden in #{target}") + pretty_message = "#{error_message}\n" \ + "Made final here: #{definition_file}:#{definition_line}\n" \ + "#{extra_info}" + + begin + raise pretty_message + rescue => e + # sig_validation_error_handler raises by default; on the off chance that + # it doesn't raise, we need to ensure that the rest of signature building + # sees a consistent state. This sig failed to validate, so we should get + # rid of it. If we don't do this, errors of the form "You called sig + # twice without declaring a method in between" will non-deterministically + # crop up in tests. + T::Private::DeclState.current.reset! + T::Configuration.sig_validation_error_handler(e, {}) + end + end + end + end + + def self.add_module_with_final_method(mod, method_name, is_singleton_method) + m = is_singleton_method ? mod.singleton_class : mod + mid = m.object_id + methods = @modules_with_final[mid] + if methods.nil? + methods = {} + @modules_with_final[mid] = methods + end + methods[method_name] = true + nil + end + + def self.note_module_deals_with_final(mod) + # Side-effectfully initialize the value if it's not already there + @modules_with_final[mod.object_id] + @modules_with_final[mod.singleton_class.object_id] + end + + # Only public because it needs to get called below inside the replace_method blocks below. + def self._on_method_added(hook_mod, method_name, is_singleton_method: false) + if T::Private::DeclState.current.skip_on_method_added + return + end + + current_declaration = T::Private::DeclState.current.active_declaration + mod = is_singleton_method ? hook_mod.singleton_class : hook_mod + + if T::Private::Final.final_module?(mod) && (current_declaration.nil? || !current_declaration.final) + raise "#{mod} was declared as final but its method `#{method_name}` was not declared as final" + end + # Don't compute mod.ancestors if we don't need to bother checking final-ness. + if @was_ever_final_names.include?(method_name) && @modules_with_final.include?(mod.object_id) + _check_final_ancestors(mod, mod.ancestors, [method_name], nil) + # We need to fetch the active declaration again, as _check_final_ancestors + # may have reset it (see the comment in that method for details). + current_declaration = T::Private::DeclState.current.active_declaration + end + + if current_declaration.nil? + return + end + T::Private::DeclState.current.reset! + + if method_name == :method_added || method_name == :singleton_method_added + raise( + "Putting a `sig` on `#{method_name}` is not supported" \ + " (sorbet-runtime uses this method internally to perform `sig` validation logic)" + ) + end + + original_method = mod.instance_method(method_name) + sig_block = lambda do + T::Private::Methods.run_sig(hook_mod, method_name, original_method, current_declaration) + end + + # Always replace the original method with this wrapper, + # which is called only on the *first* invocation. + # This wrapper is very slow, so it will subsequently re-wrap with a much faster wrapper + # (or unwrap back to the original method). + key = method_owner_and_name_to_key(mod, method_name) + unless current_declaration.raw + T::Private::ClassUtils.replace_method(mod, method_name) do |*args, &blk| + method_sig = T::Private::Methods.maybe_run_sig_block_for_key(key) + method_sig ||= T::Private::Methods._handle_missing_method_signature( + self, + original_method, + __callee__, + ) + + # Should be the same logic as CallValidation.wrap_method_if_needed but we + # don't want that extra layer of indirection in the callstack + if method_sig.mode == T::Private::Methods::Modes.abstract + # We're in an interface method, keep going up the chain + if defined?(super) + super(*args, &blk) + else + raise NotImplementedError.new("The method `#{method_sig.method_name}` on #{mod} is declared as `abstract`. It does not have an implementation.") + end + # Note, this logic is duplicated (intentionally, for micro-perf) at `CallValidation.wrap_method_if_needed`, + # make sure to keep changes in sync. + elsif method_sig.check_level == :always || (method_sig.check_level == :tests && T::Private::RuntimeLevels.check_tests?) + CallValidation.validate_call(self, original_method, method_sig, args, blk) + elsif T::Configuration::AT_LEAST_RUBY_2_7 + original_method.bind_call(self, *args, &blk) + else + original_method.bind(self).call(*args, &blk) + end + end + end + + @sig_wrappers[key] = sig_block + if current_declaration.final + @was_ever_final_names[method_name] = true + # use hook_mod, not mod, because for example, we want class C to be marked as having final if we def C.foo as + # final. change this to mod to see some final_method tests fail. + note_module_deals_with_final(hook_mod) + add_module_with_final_method(hook_mod, method_name, is_singleton_method) + end + end + + def self._handle_missing_method_signature(receiver, original_method, callee) + method_sig = T::Private::Methods.signature_for_method(original_method) + if !method_sig + raise "`sig` not present for method `#{callee}` on #{receiver.inspect} but you're trying to run it anyways. " \ + "This should only be executed if you used `alias_method` to grab a handle to a method after `sig`ing it, but that clearly isn't what you are doing. " \ + "Maybe look to see if an exception was thrown in your `sig` lambda or somehow else your `sig` wasn't actually applied to the method." + end + + if receiver.class <= original_method.owner + receiving_class = receiver.class + elsif receiver.singleton_class <= original_method.owner + receiving_class = receiver.singleton_class + elsif receiver.is_a?(Module) && receiver <= original_method.owner + receiving_class = receiver + else + raise "#{receiver} is not related to #{original_method} - how did we get here?" + end + + # Check for a case where `alias` or `alias_method` was called for a + # method which had already had a `sig` applied. In that case, we want + # to avoid hitting this slow path again, by moving to a faster validator + # just like we did or will for the original method. + # + # If this isn't an `alias` or `alias_method` case, we're probably in the + # middle of some metaprogramming using a Method object, e.g. a pattern like + # `arr.map(&method(:foo))`. There's nothing really we can do to optimize + # that here. + receiving_method = receiving_class.instance_method(callee) + if receiving_method != original_method && receiving_method.original_name == original_method.name + aliasing_mod = receiving_method.owner + method_sig = method_sig.as_alias(callee) + unwrap_method(aliasing_mod, method_sig, original_method) + end + + method_sig + end + + # Executes the `sig` block, and converts the resulting Declaration + # to a Signature. + def self.run_sig(hook_mod, method_name, original_method, declaration_block) + current_declaration = + begin + run_builder(declaration_block) + rescue DeclBuilder::BuilderError => e + T::Configuration.sig_builder_error_handler(e, declaration_block.loc) + nil + end + + signature = + if current_declaration + build_sig(hook_mod, method_name, original_method, current_declaration, declaration_block.loc) + else + Signature.new_untyped(method: original_method) + end + + unwrap_method(signature.method.owner, signature, original_method) + signature + end + + def self.run_builder(declaration_block) + builder = DeclBuilder.new(declaration_block.mod, declaration_block.raw) + builder + .instance_exec(&declaration_block.blk) + .finalize! + .decl + end + + def self.build_sig(hook_mod, method_name, original_method, current_declaration, loc) + begin + # We allow `sig` in the current module's context (normal case) and + if hook_mod != current_declaration.mod && + # inside `class << self`, and + hook_mod.singleton_class != current_declaration.mod && + # on `self` at the top level of a file + current_declaration.mod != TOP_SELF + raise "A method (#{method_name}) is being added on a different class/module (#{hook_mod}) than the " \ + "last call to `sig` (#{current_declaration.mod}). Make sure each call " \ + "to `sig` is immediately followed by a method definition on the same " \ + "class/module." + end + + signature = Signature.new( + method: original_method, + method_name: method_name, + raw_arg_types: current_declaration.params, + raw_return_type: current_declaration.returns, + bind: current_declaration.bind, + mode: current_declaration.mode, + check_level: current_declaration.checked, + on_failure: current_declaration.on_failure, + override_allow_incompatible: current_declaration.override_allow_incompatible, + defined_raw: current_declaration.raw, + ) + + SignatureValidation.validate(signature) + signature + rescue => e + super_method = original_method&.super_method + super_signature = signature_for_method(super_method) if super_method + + T::Configuration.sig_validation_error_handler( + e, + method: original_method, + declaration: current_declaration, + signature: signature, + super_signature: super_signature + ) + + Signature.new_untyped(method: original_method) + end + end + + def self.unwrap_method(mod, signature, original_method) + maybe_wrapped_method = CallValidation.wrap_method_if_needed(mod, signature, original_method) + @signatures_by_method[method_to_key(maybe_wrapped_method)] = signature + end + + def self.has_sig_block_for_method(method) + has_sig_block_for_key(method_to_key(method)) + end + + private_class_method def self.has_sig_block_for_key(key) + @sig_wrappers.key?(key) + end + + def self.maybe_run_sig_block_for_method(method) + maybe_run_sig_block_for_key(method_to_key(method)) + end + + # Only public so that it can be accessed in the closure for _on_method_added + def self.maybe_run_sig_block_for_key(key) + run_sig_block_for_key(key) if has_sig_block_for_key(key) + end + + def self.run_sig_block_for_method(method) + run_sig_block_for_key(method_to_key(method)) + end + + private_class_method def self.run_sig_block_for_key(key) + blk = @sig_wrappers[key] + if !blk + sig = @signatures_by_method[key] + if sig + # We already ran the sig block, perhaps in another thread. + return sig + else + raise "No `sig` wrapper for #{key_to_method(key)}" + end + end + + begin + sig = blk.call + rescue + @sigs_that_raised[key] = true + raise + end + if @sigs_that_raised[key] + raise "A previous invocation of #{key_to_method(key)} raised, and the current one succeeded. Please don't do that." + end + + @sig_wrappers.delete(key) + sig + end + + def self.run_all_sig_blocks + loop do + break if @sig_wrappers.empty? + key, = @sig_wrappers.first + run_sig_block_for_key(key) + end + end + + def self.all_checked_tests_sigs + @signatures_by_method.values.select {|sig| sig.check_level == :tests} + end + + # the module target is adding the methods from the module source to itself. we need to check that for all instance + # methods M on source, M is not defined on any of target's ancestors. + def self._hook_impl(target, singleton_class, source) + # we do not need to call add_was_ever_final here, because we have already marked + # any such methods when source was originally defined. + if !@modules_with_final.include?(target.object_id) + if !@modules_with_final.include?(source.object_id) + return + end + note_module_deals_with_final(target) + install_hooks(target) + return + end + + methods = source.instance_methods + methods.select! do |method_name| + @was_ever_final_names.include?(method_name) + end + if methods.empty? + return + end + + target_ancestors = singleton_class ? target.singleton_class.ancestors : target.ancestors + _check_final_ancestors(target, target_ancestors, methods, source) + end + + def self.set_final_checks_on_hooks(enable) + is_enabled = !@old_hooks.nil? + if enable == is_enabled + return + end + if is_enabled + @old_hooks.each(&:restore) + @old_hooks = nil + else + old_included = T::Private::ClassUtils.replace_method(Module, :included) do |arg| + old_included.bind(self).call(arg) + ::T::Private::Methods._hook_impl(arg, false, self) + end + old_extended = T::Private::ClassUtils.replace_method(Module, :extended) do |arg| + old_extended.bind(self).call(arg) + ::T::Private::Methods._hook_impl(arg, true, self) + end + old_inherited = T::Private::ClassUtils.replace_method(Class, :inherited) do |arg| + old_inherited.bind(self).call(arg) + ::T::Private::Methods._hook_impl(arg, false, self) + end + @old_hooks = [old_included, old_extended, old_inherited] + end + end + + module MethodHooks + def method_added(name) + super(name) + ::T::Private::Methods._on_method_added(self, name, is_singleton_method: false) + end + end + + module SingletonMethodHooks + def singleton_method_added(name) + super(name) + ::T::Private::Methods._on_method_added(self, name, is_singleton_method: true) + end + end + + def self.install_hooks(mod) + return if @installed_hooks.include?(mod) + @installed_hooks[mod] = true + + if mod == TOP_SELF + # self at the top-level of a file is weirdly special in Ruby + # The Ruby VM on startup creates an `Object.new` and stashes it. + # Unlike when we're using sig inside a module, `self` is actually a + # normal object, not an instance of Module. + # + # Thus we can't ask things like mod.singleton_class? (since that's + # defined only on Module, not on Object) and even if we could, the places + # where we need to install the hooks are special. + mod.extend(SingletonMethodHooks) # def self.foo; end (at top level) + Object.extend(MethodHooks) # def foo; end (at top level) + return + end + + # See https://github.com/sorbet/sorbet/pull/3964 for an explanation of why this + # check (which theoretically should not be needed) is actually needed. + if !mod.is_a?(Module) + return + end + + if mod.singleton_class? + mod.include(SingletonMethodHooks) + else + mod.extend(MethodHooks) + end + mod.extend(SingletonMethodHooks) + end + + # use this directly if you don't want/need to box up the method into an object to pass to method_to_key. + private_class_method def self.method_owner_and_name_to_key(owner, name) + "#{owner.object_id}##{name}" + end + + private_class_method def self.method_to_key(method) + method_owner_and_name_to_key(method.owner, method.name) + end + + private_class_method def self.key_to_method(key) + id, name = key.split("#") + obj = ObjectSpace._id2ref(id.to_i) + obj.instance_method(name) + end +end + +# This has to be here, and can't be nested inside `T::Private::Methods`, +# because the value of `self` depends on lexical (nesting) scope, and we +# specifically need a reference to the file-level self, i.e. `main:Object` +T::Private::Methods::TOP_SELF = self diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/call_validation.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/call_validation.rb new file mode 100644 index 0000000000..1889daa991 --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/call_validation.rb @@ -0,0 +1,221 @@ +# frozen_string_literal: true +# typed: false + +module T::Private::Methods::CallValidation + CallValidation = T::Private::Methods::CallValidation + Modes = T::Private::Methods::Modes + + # Wraps a method with a layer of validation for the given type signature. + # This wrapper is meant to be fast, and is applied by a previous wrapper, + # which was placed by `_on_method_added`. + # + # @param method_sig [T::Private::Methods::Signature] + # @return [UnboundMethod] the new wrapper method (or the original one if we didn't wrap it) + def self.wrap_method_if_needed(mod, method_sig, original_method) + original_visibility = visibility_method_name(mod, method_sig.method_name) + if method_sig.mode == T::Private::Methods::Modes.abstract + T::Private::ClassUtils.replace_method(mod, method_sig.method_name) do |*args, &blk| + # TODO: write a cop to ensure that abstract methods have an empty body + # + # We allow abstract methods to be implemented by things further down the ancestor chain. + # So, if a super method exists, call it. + if defined?(super) + super(*args, &blk) + else + raise NotImplementedError.new( + "The method `#{method_sig.method_name}` on #{mod} is declared as `abstract`. It does not have an implementation." + ) + end + end + # Do nothing in this case; this method was not wrapped in _on_method_added. + elsif method_sig.defined_raw + # Note, this logic is duplicated (intentionally, for micro-perf) at `Methods._on_method_added`, + # make sure to keep changes in sync. + # This is a trapdoor point for each method: + # if a given method is wrapped, it stays wrapped; and if not, it's never wrapped. + # (Therefore, we need the `@wrapped_tests_with_validation` check in `T::RuntimeLevels`.) + elsif method_sig.check_level == :always || (method_sig.check_level == :tests && T::Private::RuntimeLevels.check_tests?) + create_validator_method(mod, original_method, method_sig, original_visibility) + else + T::Configuration.without_ruby_warnings do + # get all the shims out of the way and put back the original method + T::Private::DeclState.current.without_on_method_added do + mod.send(:define_method, method_sig.method_name, original_method) + end + mod.send(original_visibility, method_sig.method_name) + end + end + # Return the newly created method (or the original one if we didn't replace it) + mod.instance_method(method_sig.method_name) + end + + @is_allowed_to_have_fast_path = true + def self.is_allowed_to_have_fast_path + @is_allowed_to_have_fast_path + end + + def self.disable_fast_path + @is_allowed_to_have_fast_path = false + end + + def self.create_validator_method(mod, original_method, method_sig, original_visibility) + has_fixed_arity = method_sig.kwarg_types.empty? && !method_sig.has_rest && !method_sig.has_keyrest && + original_method.parameters.all? {|(kind, _name)| kind == :req} + ok_for_fast_path = has_fixed_arity && !method_sig.bind && method_sig.arg_types.length < 5 && is_allowed_to_have_fast_path + + all_args_are_simple = ok_for_fast_path && method_sig.arg_types.all? {|_name, type| type.is_a?(T::Types::Simple)} + simple_method = all_args_are_simple && method_sig.return_type.is_a?(T::Types::Simple) + simple_procedure = all_args_are_simple && method_sig.return_type.is_a?(T::Private::Types::Void) + + T::Configuration.without_ruby_warnings do + T::Private::DeclState.current.without_on_method_added do + if simple_method + create_validator_method_fast(mod, original_method, method_sig) + elsif simple_procedure + create_validator_procedure_fast(mod, original_method, method_sig) + elsif ok_for_fast_path && method_sig.return_type.is_a?(T::Private::Types::Void) + create_validator_procedure_medium(mod, original_method, method_sig) + elsif ok_for_fast_path + create_validator_method_medium(mod, original_method, method_sig) + else + create_validator_slow(mod, original_method, method_sig) + end + end + end + mod.send(original_visibility, method_sig.method_name) + end + + def self.create_validator_slow(mod, original_method, method_sig) + mod.send(:define_method, method_sig.method_name) do |*args, &blk| + CallValidation.validate_call(self, original_method, method_sig, args, blk) + end + if mod.respond_to?(:ruby2_keywords, true) + mod.send(:ruby2_keywords, method_sig.method_name) + end + end + + def self.validate_call(instance, original_method, method_sig, args, blk) + # This method is called for every `sig`. It's critical to keep it fast and + # reduce number of allocations that happen here. + + if method_sig.bind + message = method_sig.bind.error_message_for_obj(instance) + if message + CallValidation.report_error( + method_sig, + message, + 'Bind', + nil, + method_sig.bind, + instance + ) + end + end + + # NOTE: We don't bother validating for missing or extra kwargs; + # the method call itself will take care of that. + method_sig.each_args_value_type(args) do |name, arg, type| + message = type.error_message_for_obj(arg) + if message + CallValidation.report_error( + method_sig, + message, + 'Parameter', + name, + type, + arg, + caller_offset: 2 + ) + end + end + + if method_sig.block_type + message = method_sig.block_type.error_message_for_obj(blk) + if message + CallValidation.report_error( + method_sig, + message, + 'Block parameter', + method_sig.block_name, + method_sig.block_type, + blk + ) + end + end + + # The following line breaks are intentional to show nice pry message + + + + + + + + + + + # PRY note: + # this code is sig validation code. + # Please issue `finish` to step out of it + + return_value = T::Configuration::AT_LEAST_RUBY_2_7 ? original_method.bind_call(instance, *args, &blk) : original_method.bind(instance).call(*args, &blk) + + # The only type that is allowed to change the return value is `.void`. + # It ignores what you returned and changes it to be a private singleton. + if method_sig.return_type.is_a?(T::Private::Types::Void) + T::Private::Types::Void::VOID + else + message = method_sig.return_type.error_message_for_obj(return_value) + if message + CallValidation.report_error( + method_sig, + message, + 'Return value', + nil, + method_sig.return_type, + return_value, + ) + end + return_value + end + end + + def self.report_error(method_sig, error_message, kind, name, type, value, caller_offset: 0) + caller_loc = T.must(caller_locations(3 + caller_offset, 1))[0] + definition_file, definition_line = method_sig.method.source_location + + pretty_message = "#{kind}#{name ? " '#{name}'" : ''}: #{error_message}\n" \ + "Caller: #{caller_loc.path}:#{caller_loc.lineno}\n" \ + "Definition: #{definition_file}:#{definition_line}" + + T::Configuration.call_validation_error_handler( + method_sig, + message: error_message, + pretty_message: pretty_message, + kind: kind, + name: name, + type: type, + value: value, + location: caller_loc + ) + end + + # `name` must be an instance method (for class methods, pass in mod.singleton_class) + private_class_method def self.visibility_method_name(mod, name) + if mod.public_method_defined?(name) + :public + elsif mod.protected_method_defined?(name) + :protected + elsif mod.private_method_defined?(name) + :private + else + raise NameError.new("undefined method `#{name}` for `#{mod}`") + end + end +end + +if T::Configuration::AT_LEAST_RUBY_2_7 + require_relative './call_validation_2_7' +else + require_relative './call_validation_2_6' +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/call_validation_2_6.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/call_validation_2_6.rb new file mode 100644 index 0000000000..753580dc36 --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/call_validation_2_6.rb @@ -0,0 +1,1203 @@ +# frozen_string_literal: true +# typed: false + +# DO NOT EDIT. This file is autogenerated. To regenerate, run: +# +# bazel test //gems/sorbet-runtime:update_call_validation + +module T::Private::Methods::CallValidation + def self.create_validator_method_fast(mod, original_method, method_sig) + if method_sig.return_type.is_a?(T::Private::Types::Void) + raise 'Should have used create_validator_procedure_fast' + end + # trampoline to reduce stack frame size + if method_sig.arg_types.empty? + create_validator_method_fast0(mod, original_method, method_sig, method_sig.return_type.raw_type) + elsif method_sig.arg_types.length == 1 + create_validator_method_fast1(mod, original_method, method_sig, method_sig.return_type.raw_type, + method_sig.arg_types[0][1].raw_type) + elsif method_sig.arg_types.length == 2 + create_validator_method_fast2(mod, original_method, method_sig, method_sig.return_type.raw_type, + method_sig.arg_types[0][1].raw_type, + method_sig.arg_types[1][1].raw_type) + elsif method_sig.arg_types.length == 3 + create_validator_method_fast3(mod, original_method, method_sig, method_sig.return_type.raw_type, + method_sig.arg_types[0][1].raw_type, + method_sig.arg_types[1][1].raw_type, + method_sig.arg_types[2][1].raw_type) + elsif method_sig.arg_types.length == 4 + create_validator_method_fast4(mod, original_method, method_sig, method_sig.return_type.raw_type, + method_sig.arg_types[0][1].raw_type, + method_sig.arg_types[1][1].raw_type, + method_sig.arg_types[2][1].raw_type, + method_sig.arg_types[3][1].raw_type) + else + raise 'should not happen' + end + end + + def self.create_validator_method_fast0(mod, original_method, method_sig, return_type) + mod.send(:define_method, method_sig.method_name) do |&blk| + # This method is a manually sped-up version of more general code in `validate_call` + # The following line breaks are intentional to show nice pry message + + + + + + + + + + + # PRY note: + # this code is sig validation code. + # Please issue `finish` to step out of it + + return_value = original_method.bind(self).call(&blk) + unless return_value.is_a?(return_type) + message = method_sig.return_type.error_message_for_obj(return_value) + if message + CallValidation.report_error( + method_sig, + message, + 'Return value', + nil, + method_sig.return_type, + return_value, + caller_offset: -1 + ) + end + end + return_value + end + end + + def self.create_validator_method_fast1(mod, original_method, method_sig, return_type, arg0_type) + mod.send(:define_method, method_sig.method_name) do |arg0, &blk| + # This method is a manually sped-up version of more general code in `validate_call` + unless arg0.is_a?(arg0_type) + CallValidation.report_error( + method_sig, + method_sig.arg_types[0][1].error_message_for_obj(arg0), + 'Parameter', + method_sig.arg_types[0][0], + arg0_type, + arg0, + caller_offset: -1 + ) + end + + # The following line breaks are intentional to show nice pry message + + + + + + + + + + + # PRY note: + # this code is sig validation code. + # Please issue `finish` to step out of it + + return_value = original_method.bind(self).call(arg0, &blk) + unless return_value.is_a?(return_type) + message = method_sig.return_type.error_message_for_obj(return_value) + if message + CallValidation.report_error( + method_sig, + message, + 'Return value', + nil, + method_sig.return_type, + return_value, + caller_offset: -1 + ) + end + end + return_value + end + end + + def self.create_validator_method_fast2(mod, original_method, method_sig, return_type, arg0_type, arg1_type) + mod.send(:define_method, method_sig.method_name) do |arg0, arg1, &blk| + # This method is a manually sped-up version of more general code in `validate_call` + unless arg0.is_a?(arg0_type) + CallValidation.report_error( + method_sig, + method_sig.arg_types[0][1].error_message_for_obj(arg0), + 'Parameter', + method_sig.arg_types[0][0], + arg0_type, + arg0, + caller_offset: -1 + ) + end + + unless arg1.is_a?(arg1_type) + CallValidation.report_error( + method_sig, + method_sig.arg_types[1][1].error_message_for_obj(arg1), + 'Parameter', + method_sig.arg_types[1][0], + arg1_type, + arg1, + caller_offset: -1 + ) + end + + # The following line breaks are intentional to show nice pry message + + + + + + + + + + + # PRY note: + # this code is sig validation code. + # Please issue `finish` to step out of it + + return_value = original_method.bind(self).call(arg0, arg1, &blk) + unless return_value.is_a?(return_type) + message = method_sig.return_type.error_message_for_obj(return_value) + if message + CallValidation.report_error( + method_sig, + message, + 'Return value', + nil, + method_sig.return_type, + return_value, + caller_offset: -1 + ) + end + end + return_value + end + end + + def self.create_validator_method_fast3(mod, original_method, method_sig, return_type, arg0_type, arg1_type, arg2_type) + mod.send(:define_method, method_sig.method_name) do |arg0, arg1, arg2, &blk| + # This method is a manually sped-up version of more general code in `validate_call` + unless arg0.is_a?(arg0_type) + CallValidation.report_error( + method_sig, + method_sig.arg_types[0][1].error_message_for_obj(arg0), + 'Parameter', + method_sig.arg_types[0][0], + arg0_type, + arg0, + caller_offset: -1 + ) + end + + unless arg1.is_a?(arg1_type) + CallValidation.report_error( + method_sig, + method_sig.arg_types[1][1].error_message_for_obj(arg1), + 'Parameter', + method_sig.arg_types[1][0], + arg1_type, + arg1, + caller_offset: -1 + ) + end + + unless arg2.is_a?(arg2_type) + CallValidation.report_error( + method_sig, + method_sig.arg_types[2][1].error_message_for_obj(arg2), + 'Parameter', + method_sig.arg_types[2][0], + arg2_type, + arg2, + caller_offset: -1 + ) + end + + # The following line breaks are intentional to show nice pry message + + + + + + + + + + + # PRY note: + # this code is sig validation code. + # Please issue `finish` to step out of it + + return_value = original_method.bind(self).call(arg0, arg1, arg2, &blk) + unless return_value.is_a?(return_type) + message = method_sig.return_type.error_message_for_obj(return_value) + if message + CallValidation.report_error( + method_sig, + message, + 'Return value', + nil, + method_sig.return_type, + return_value, + caller_offset: -1 + ) + end + end + return_value + end + end + + def self.create_validator_method_fast4(mod, original_method, method_sig, return_type, arg0_type, arg1_type, arg2_type, arg3_type) + mod.send(:define_method, method_sig.method_name) do |arg0, arg1, arg2, arg3, &blk| + # This method is a manually sped-up version of more general code in `validate_call` + unless arg0.is_a?(arg0_type) + CallValidation.report_error( + method_sig, + method_sig.arg_types[0][1].error_message_for_obj(arg0), + 'Parameter', + method_sig.arg_types[0][0], + arg0_type, + arg0, + caller_offset: -1 + ) + end + + unless arg1.is_a?(arg1_type) + CallValidation.report_error( + method_sig, + method_sig.arg_types[1][1].error_message_for_obj(arg1), + 'Parameter', + method_sig.arg_types[1][0], + arg1_type, + arg1, + caller_offset: -1 + ) + end + + unless arg2.is_a?(arg2_type) + CallValidation.report_error( + method_sig, + method_sig.arg_types[2][1].error_message_for_obj(arg2), + 'Parameter', + method_sig.arg_types[2][0], + arg2_type, + arg2, + caller_offset: -1 + ) + end + + unless arg3.is_a?(arg3_type) + CallValidation.report_error( + method_sig, + method_sig.arg_types[3][1].error_message_for_obj(arg3), + 'Parameter', + method_sig.arg_types[3][0], + arg3_type, + arg3, + caller_offset: -1 + ) + end + + # The following line breaks are intentional to show nice pry message + + + + + + + + + + + # PRY note: + # this code is sig validation code. + # Please issue `finish` to step out of it + + return_value = original_method.bind(self).call(arg0, arg1, arg2, arg3, &blk) + unless return_value.is_a?(return_type) + message = method_sig.return_type.error_message_for_obj(return_value) + if message + CallValidation.report_error( + method_sig, + message, + 'Return value', + nil, + method_sig.return_type, + return_value, + caller_offset: -1 + ) + end + end + return_value + end + end + + def self.create_validator_procedure_fast(mod, original_method, method_sig) + # trampoline to reduce stack frame size + if method_sig.arg_types.empty? + create_validator_procedure_fast0(mod, original_method, method_sig) + elsif method_sig.arg_types.length == 1 + create_validator_procedure_fast1(mod, original_method, method_sig, + method_sig.arg_types[0][1].raw_type) + elsif method_sig.arg_types.length == 2 + create_validator_procedure_fast2(mod, original_method, method_sig, + method_sig.arg_types[0][1].raw_type, + method_sig.arg_types[1][1].raw_type) + elsif method_sig.arg_types.length == 3 + create_validator_procedure_fast3(mod, original_method, method_sig, + method_sig.arg_types[0][1].raw_type, + method_sig.arg_types[1][1].raw_type, + method_sig.arg_types[2][1].raw_type) + elsif method_sig.arg_types.length == 4 + create_validator_procedure_fast4(mod, original_method, method_sig, + method_sig.arg_types[0][1].raw_type, + method_sig.arg_types[1][1].raw_type, + method_sig.arg_types[2][1].raw_type, + method_sig.arg_types[3][1].raw_type) + else + raise 'should not happen' + end + end + + def self.create_validator_procedure_fast0(mod, original_method, method_sig) + mod.send(:define_method, method_sig.method_name) do |&blk| + # This method is a manually sped-up version of more general code in `validate_call` + # The following line breaks are intentional to show nice pry message + + + + + + + + + + + # PRY note: + # this code is sig validation code. + # Please issue `finish` to step out of it + + original_method.bind(self).call(&blk) + T::Private::Types::Void::VOID + end + end + + def self.create_validator_procedure_fast1(mod, original_method, method_sig, arg0_type) + mod.send(:define_method, method_sig.method_name) do |arg0, &blk| + # This method is a manually sped-up version of more general code in `validate_call` + unless arg0.is_a?(arg0_type) + CallValidation.report_error( + method_sig, + method_sig.arg_types[0][1].error_message_for_obj(arg0), + 'Parameter', + method_sig.arg_types[0][0], + arg0_type, + arg0, + caller_offset: -1 + ) + end + + # The following line breaks are intentional to show nice pry message + + + + + + + + + + + # PRY note: + # this code is sig validation code. + # Please issue `finish` to step out of it + + original_method.bind(self).call(arg0, &blk) + T::Private::Types::Void::VOID + end + end + + def self.create_validator_procedure_fast2(mod, original_method, method_sig, arg0_type, arg1_type) + mod.send(:define_method, method_sig.method_name) do |arg0, arg1, &blk| + # This method is a manually sped-up version of more general code in `validate_call` + unless arg0.is_a?(arg0_type) + CallValidation.report_error( + method_sig, + method_sig.arg_types[0][1].error_message_for_obj(arg0), + 'Parameter', + method_sig.arg_types[0][0], + arg0_type, + arg0, + caller_offset: -1 + ) + end + + unless arg1.is_a?(arg1_type) + CallValidation.report_error( + method_sig, + method_sig.arg_types[1][1].error_message_for_obj(arg1), + 'Parameter', + method_sig.arg_types[1][0], + arg1_type, + arg1, + caller_offset: -1 + ) + end + + # The following line breaks are intentional to show nice pry message + + + + + + + + + + + # PRY note: + # this code is sig validation code. + # Please issue `finish` to step out of it + + original_method.bind(self).call(arg0, arg1, &blk) + T::Private::Types::Void::VOID + end + end + + def self.create_validator_procedure_fast3(mod, original_method, method_sig, arg0_type, arg1_type, arg2_type) + mod.send(:define_method, method_sig.method_name) do |arg0, arg1, arg2, &blk| + # This method is a manually sped-up version of more general code in `validate_call` + unless arg0.is_a?(arg0_type) + CallValidation.report_error( + method_sig, + method_sig.arg_types[0][1].error_message_for_obj(arg0), + 'Parameter', + method_sig.arg_types[0][0], + arg0_type, + arg0, + caller_offset: -1 + ) + end + + unless arg1.is_a?(arg1_type) + CallValidation.report_error( + method_sig, + method_sig.arg_types[1][1].error_message_for_obj(arg1), + 'Parameter', + method_sig.arg_types[1][0], + arg1_type, + arg1, + caller_offset: -1 + ) + end + + unless arg2.is_a?(arg2_type) + CallValidation.report_error( + method_sig, + method_sig.arg_types[2][1].error_message_for_obj(arg2), + 'Parameter', + method_sig.arg_types[2][0], + arg2_type, + arg2, + caller_offset: -1 + ) + end + + # The following line breaks are intentional to show nice pry message + + + + + + + + + + + # PRY note: + # this code is sig validation code. + # Please issue `finish` to step out of it + + original_method.bind(self).call(arg0, arg1, arg2, &blk) + T::Private::Types::Void::VOID + end + end + + def self.create_validator_procedure_fast4(mod, original_method, method_sig, arg0_type, arg1_type, arg2_type, arg3_type) + mod.send(:define_method, method_sig.method_name) do |arg0, arg1, arg2, arg3, &blk| + # This method is a manually sped-up version of more general code in `validate_call` + unless arg0.is_a?(arg0_type) + CallValidation.report_error( + method_sig, + method_sig.arg_types[0][1].error_message_for_obj(arg0), + 'Parameter', + method_sig.arg_types[0][0], + arg0_type, + arg0, + caller_offset: -1 + ) + end + + unless arg1.is_a?(arg1_type) + CallValidation.report_error( + method_sig, + method_sig.arg_types[1][1].error_message_for_obj(arg1), + 'Parameter', + method_sig.arg_types[1][0], + arg1_type, + arg1, + caller_offset: -1 + ) + end + + unless arg2.is_a?(arg2_type) + CallValidation.report_error( + method_sig, + method_sig.arg_types[2][1].error_message_for_obj(arg2), + 'Parameter', + method_sig.arg_types[2][0], + arg2_type, + arg2, + caller_offset: -1 + ) + end + + unless arg3.is_a?(arg3_type) + CallValidation.report_error( + method_sig, + method_sig.arg_types[3][1].error_message_for_obj(arg3), + 'Parameter', + method_sig.arg_types[3][0], + arg3_type, + arg3, + caller_offset: -1 + ) + end + + # The following line breaks are intentional to show nice pry message + + + + + + + + + + + # PRY note: + # this code is sig validation code. + # Please issue `finish` to step out of it + + original_method.bind(self).call(arg0, arg1, arg2, arg3, &blk) + T::Private::Types::Void::VOID + end + end + + def self.create_validator_method_medium(mod, original_method, method_sig) + if method_sig.return_type.is_a?(T::Private::Types::Void) + raise 'Should have used create_validator_procedure_medium' + end + # trampoline to reduce stack frame size + if method_sig.arg_types.empty? + create_validator_method_medium0(mod, original_method, method_sig, method_sig.return_type) + elsif method_sig.arg_types.length == 1 + create_validator_method_medium1(mod, original_method, method_sig, method_sig.return_type, + method_sig.arg_types[0][1]) + elsif method_sig.arg_types.length == 2 + create_validator_method_medium2(mod, original_method, method_sig, method_sig.return_type, + method_sig.arg_types[0][1], + method_sig.arg_types[1][1]) + elsif method_sig.arg_types.length == 3 + create_validator_method_medium3(mod, original_method, method_sig, method_sig.return_type, + method_sig.arg_types[0][1], + method_sig.arg_types[1][1], + method_sig.arg_types[2][1]) + elsif method_sig.arg_types.length == 4 + create_validator_method_medium4(mod, original_method, method_sig, method_sig.return_type, + method_sig.arg_types[0][1], + method_sig.arg_types[1][1], + method_sig.arg_types[2][1], + method_sig.arg_types[3][1]) + else + raise 'should not happen' + end + end + + def self.create_validator_method_medium0(mod, original_method, method_sig, return_type) + mod.send(:define_method, method_sig.method_name) do |&blk| + # This method is a manually sped-up version of more general code in `validate_call` + # The following line breaks are intentional to show nice pry message + + + + + + + + + + + # PRY note: + # this code is sig validation code. + # Please issue `finish` to step out of it + + return_value = original_method.bind(self).call(&blk) + unless return_type.valid?(return_value) + message = method_sig.return_type.error_message_for_obj(return_value) + if message + CallValidation.report_error( + method_sig, + message, + 'Return value', + nil, + method_sig.return_type, + return_value, + caller_offset: -1 + ) + end + end + return_value + end + end + + def self.create_validator_method_medium1(mod, original_method, method_sig, return_type, arg0_type) + mod.send(:define_method, method_sig.method_name) do |arg0, &blk| + # This method is a manually sped-up version of more general code in `validate_call` + unless arg0_type.valid?(arg0) + CallValidation.report_error( + method_sig, + method_sig.arg_types[0][1].error_message_for_obj(arg0), + 'Parameter', + method_sig.arg_types[0][0], + arg0_type, + arg0, + caller_offset: -1 + ) + end + + # The following line breaks are intentional to show nice pry message + + + + + + + + + + + # PRY note: + # this code is sig validation code. + # Please issue `finish` to step out of it + + return_value = original_method.bind(self).call(arg0, &blk) + unless return_type.valid?(return_value) + message = method_sig.return_type.error_message_for_obj(return_value) + if message + CallValidation.report_error( + method_sig, + message, + 'Return value', + nil, + method_sig.return_type, + return_value, + caller_offset: -1 + ) + end + end + return_value + end + end + + def self.create_validator_method_medium2(mod, original_method, method_sig, return_type, arg0_type, arg1_type) + mod.send(:define_method, method_sig.method_name) do |arg0, arg1, &blk| + # This method is a manually sped-up version of more general code in `validate_call` + unless arg0_type.valid?(arg0) + CallValidation.report_error( + method_sig, + method_sig.arg_types[0][1].error_message_for_obj(arg0), + 'Parameter', + method_sig.arg_types[0][0], + arg0_type, + arg0, + caller_offset: -1 + ) + end + + unless arg1_type.valid?(arg1) + CallValidation.report_error( + method_sig, + method_sig.arg_types[1][1].error_message_for_obj(arg1), + 'Parameter', + method_sig.arg_types[1][0], + arg1_type, + arg1, + caller_offset: -1 + ) + end + + # The following line breaks are intentional to show nice pry message + + + + + + + + + + + # PRY note: + # this code is sig validation code. + # Please issue `finish` to step out of it + + return_value = original_method.bind(self).call(arg0, arg1, &blk) + unless return_type.valid?(return_value) + message = method_sig.return_type.error_message_for_obj(return_value) + if message + CallValidation.report_error( + method_sig, + message, + 'Return value', + nil, + method_sig.return_type, + return_value, + caller_offset: -1 + ) + end + end + return_value + end + end + + def self.create_validator_method_medium3(mod, original_method, method_sig, return_type, arg0_type, arg1_type, arg2_type) + mod.send(:define_method, method_sig.method_name) do |arg0, arg1, arg2, &blk| + # This method is a manually sped-up version of more general code in `validate_call` + unless arg0_type.valid?(arg0) + CallValidation.report_error( + method_sig, + method_sig.arg_types[0][1].error_message_for_obj(arg0), + 'Parameter', + method_sig.arg_types[0][0], + arg0_type, + arg0, + caller_offset: -1 + ) + end + + unless arg1_type.valid?(arg1) + CallValidation.report_error( + method_sig, + method_sig.arg_types[1][1].error_message_for_obj(arg1), + 'Parameter', + method_sig.arg_types[1][0], + arg1_type, + arg1, + caller_offset: -1 + ) + end + + unless arg2_type.valid?(arg2) + CallValidation.report_error( + method_sig, + method_sig.arg_types[2][1].error_message_for_obj(arg2), + 'Parameter', + method_sig.arg_types[2][0], + arg2_type, + arg2, + caller_offset: -1 + ) + end + + # The following line breaks are intentional to show nice pry message + + + + + + + + + + + # PRY note: + # this code is sig validation code. + # Please issue `finish` to step out of it + + return_value = original_method.bind(self).call(arg0, arg1, arg2, &blk) + unless return_type.valid?(return_value) + message = method_sig.return_type.error_message_for_obj(return_value) + if message + CallValidation.report_error( + method_sig, + message, + 'Return value', + nil, + method_sig.return_type, + return_value, + caller_offset: -1 + ) + end + end + return_value + end + end + + def self.create_validator_method_medium4(mod, original_method, method_sig, return_type, arg0_type, arg1_type, arg2_type, arg3_type) + mod.send(:define_method, method_sig.method_name) do |arg0, arg1, arg2, arg3, &blk| + # This method is a manually sped-up version of more general code in `validate_call` + unless arg0_type.valid?(arg0) + CallValidation.report_error( + method_sig, + method_sig.arg_types[0][1].error_message_for_obj(arg0), + 'Parameter', + method_sig.arg_types[0][0], + arg0_type, + arg0, + caller_offset: -1 + ) + end + + unless arg1_type.valid?(arg1) + CallValidation.report_error( + method_sig, + method_sig.arg_types[1][1].error_message_for_obj(arg1), + 'Parameter', + method_sig.arg_types[1][0], + arg1_type, + arg1, + caller_offset: -1 + ) + end + + unless arg2_type.valid?(arg2) + CallValidation.report_error( + method_sig, + method_sig.arg_types[2][1].error_message_for_obj(arg2), + 'Parameter', + method_sig.arg_types[2][0], + arg2_type, + arg2, + caller_offset: -1 + ) + end + + unless arg3_type.valid?(arg3) + CallValidation.report_error( + method_sig, + method_sig.arg_types[3][1].error_message_for_obj(arg3), + 'Parameter', + method_sig.arg_types[3][0], + arg3_type, + arg3, + caller_offset: -1 + ) + end + + # The following line breaks are intentional to show nice pry message + + + + + + + + + + + # PRY note: + # this code is sig validation code. + # Please issue `finish` to step out of it + + return_value = original_method.bind(self).call(arg0, arg1, arg2, arg3, &blk) + unless return_type.valid?(return_value) + message = method_sig.return_type.error_message_for_obj(return_value) + if message + CallValidation.report_error( + method_sig, + message, + 'Return value', + nil, + method_sig.return_type, + return_value, + caller_offset: -1 + ) + end + end + return_value + end + end + + def self.create_validator_procedure_medium(mod, original_method, method_sig) + # trampoline to reduce stack frame size + if method_sig.arg_types.empty? + create_validator_procedure_medium0(mod, original_method, method_sig) + elsif method_sig.arg_types.length == 1 + create_validator_procedure_medium1(mod, original_method, method_sig, + method_sig.arg_types[0][1]) + elsif method_sig.arg_types.length == 2 + create_validator_procedure_medium2(mod, original_method, method_sig, + method_sig.arg_types[0][1], + method_sig.arg_types[1][1]) + elsif method_sig.arg_types.length == 3 + create_validator_procedure_medium3(mod, original_method, method_sig, + method_sig.arg_types[0][1], + method_sig.arg_types[1][1], + method_sig.arg_types[2][1]) + elsif method_sig.arg_types.length == 4 + create_validator_procedure_medium4(mod, original_method, method_sig, + method_sig.arg_types[0][1], + method_sig.arg_types[1][1], + method_sig.arg_types[2][1], + method_sig.arg_types[3][1]) + else + raise 'should not happen' + end + end + + def self.create_validator_procedure_medium0(mod, original_method, method_sig) + mod.send(:define_method, method_sig.method_name) do |&blk| + # This method is a manually sped-up version of more general code in `validate_call` + # The following line breaks are intentional to show nice pry message + + + + + + + + + + + # PRY note: + # this code is sig validation code. + # Please issue `finish` to step out of it + + original_method.bind(self).call(&blk) + T::Private::Types::Void::VOID + end + end + + def self.create_validator_procedure_medium1(mod, original_method, method_sig, arg0_type) + mod.send(:define_method, method_sig.method_name) do |arg0, &blk| + # This method is a manually sped-up version of more general code in `validate_call` + unless arg0_type.valid?(arg0) + CallValidation.report_error( + method_sig, + method_sig.arg_types[0][1].error_message_for_obj(arg0), + 'Parameter', + method_sig.arg_types[0][0], + arg0_type, + arg0, + caller_offset: -1 + ) + end + + # The following line breaks are intentional to show nice pry message + + + + + + + + + + + # PRY note: + # this code is sig validation code. + # Please issue `finish` to step out of it + + original_method.bind(self).call(arg0, &blk) + T::Private::Types::Void::VOID + end + end + + def self.create_validator_procedure_medium2(mod, original_method, method_sig, arg0_type, arg1_type) + mod.send(:define_method, method_sig.method_name) do |arg0, arg1, &blk| + # This method is a manually sped-up version of more general code in `validate_call` + unless arg0_type.valid?(arg0) + CallValidation.report_error( + method_sig, + method_sig.arg_types[0][1].error_message_for_obj(arg0), + 'Parameter', + method_sig.arg_types[0][0], + arg0_type, + arg0, + caller_offset: -1 + ) + end + + unless arg1_type.valid?(arg1) + CallValidation.report_error( + method_sig, + method_sig.arg_types[1][1].error_message_for_obj(arg1), + 'Parameter', + method_sig.arg_types[1][0], + arg1_type, + arg1, + caller_offset: -1 + ) + end + + # The following line breaks are intentional to show nice pry message + + + + + + + + + + + # PRY note: + # this code is sig validation code. + # Please issue `finish` to step out of it + + original_method.bind(self).call(arg0, arg1, &blk) + T::Private::Types::Void::VOID + end + end + + def self.create_validator_procedure_medium3(mod, original_method, method_sig, arg0_type, arg1_type, arg2_type) + mod.send(:define_method, method_sig.method_name) do |arg0, arg1, arg2, &blk| + # This method is a manually sped-up version of more general code in `validate_call` + unless arg0_type.valid?(arg0) + CallValidation.report_error( + method_sig, + method_sig.arg_types[0][1].error_message_for_obj(arg0), + 'Parameter', + method_sig.arg_types[0][0], + arg0_type, + arg0, + caller_offset: -1 + ) + end + + unless arg1_type.valid?(arg1) + CallValidation.report_error( + method_sig, + method_sig.arg_types[1][1].error_message_for_obj(arg1), + 'Parameter', + method_sig.arg_types[1][0], + arg1_type, + arg1, + caller_offset: -1 + ) + end + + unless arg2_type.valid?(arg2) + CallValidation.report_error( + method_sig, + method_sig.arg_types[2][1].error_message_for_obj(arg2), + 'Parameter', + method_sig.arg_types[2][0], + arg2_type, + arg2, + caller_offset: -1 + ) + end + + # The following line breaks are intentional to show nice pry message + + + + + + + + + + + # PRY note: + # this code is sig validation code. + # Please issue `finish` to step out of it + + original_method.bind(self).call(arg0, arg1, arg2, &blk) + T::Private::Types::Void::VOID + end + end + + def self.create_validator_procedure_medium4(mod, original_method, method_sig, arg0_type, arg1_type, arg2_type, arg3_type) + mod.send(:define_method, method_sig.method_name) do |arg0, arg1, arg2, arg3, &blk| + # This method is a manually sped-up version of more general code in `validate_call` + unless arg0_type.valid?(arg0) + CallValidation.report_error( + method_sig, + method_sig.arg_types[0][1].error_message_for_obj(arg0), + 'Parameter', + method_sig.arg_types[0][0], + arg0_type, + arg0, + caller_offset: -1 + ) + end + + unless arg1_type.valid?(arg1) + CallValidation.report_error( + method_sig, + method_sig.arg_types[1][1].error_message_for_obj(arg1), + 'Parameter', + method_sig.arg_types[1][0], + arg1_type, + arg1, + caller_offset: -1 + ) + end + + unless arg2_type.valid?(arg2) + CallValidation.report_error( + method_sig, + method_sig.arg_types[2][1].error_message_for_obj(arg2), + 'Parameter', + method_sig.arg_types[2][0], + arg2_type, + arg2, + caller_offset: -1 + ) + end + + unless arg3_type.valid?(arg3) + CallValidation.report_error( + method_sig, + method_sig.arg_types[3][1].error_message_for_obj(arg3), + 'Parameter', + method_sig.arg_types[3][0], + arg3_type, + arg3, + caller_offset: -1 + ) + end + + # The following line breaks are intentional to show nice pry message + + + + + + + + + + + # PRY note: + # this code is sig validation code. + # Please issue `finish` to step out of it + + original_method.bind(self).call(arg0, arg1, arg2, arg3, &blk) + T::Private::Types::Void::VOID + end + end + +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/call_validation_2_7.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/call_validation_2_7.rb new file mode 100644 index 0000000000..1686db8977 --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/call_validation_2_7.rb @@ -0,0 +1,1203 @@ +# frozen_string_literal: true +# typed: false + +# DO NOT EDIT. This file is autogenerated. To regenerate, run: +# +# bazel test //gems/sorbet-runtime:update_call_validation + +module T::Private::Methods::CallValidation + def self.create_validator_method_fast(mod, original_method, method_sig) + if method_sig.return_type.is_a?(T::Private::Types::Void) + raise 'Should have used create_validator_procedure_fast' + end + # trampoline to reduce stack frame size + if method_sig.arg_types.empty? + create_validator_method_fast0(mod, original_method, method_sig, method_sig.return_type.raw_type) + elsif method_sig.arg_types.length == 1 + create_validator_method_fast1(mod, original_method, method_sig, method_sig.return_type.raw_type, + method_sig.arg_types[0][1].raw_type) + elsif method_sig.arg_types.length == 2 + create_validator_method_fast2(mod, original_method, method_sig, method_sig.return_type.raw_type, + method_sig.arg_types[0][1].raw_type, + method_sig.arg_types[1][1].raw_type) + elsif method_sig.arg_types.length == 3 + create_validator_method_fast3(mod, original_method, method_sig, method_sig.return_type.raw_type, + method_sig.arg_types[0][1].raw_type, + method_sig.arg_types[1][1].raw_type, + method_sig.arg_types[2][1].raw_type) + elsif method_sig.arg_types.length == 4 + create_validator_method_fast4(mod, original_method, method_sig, method_sig.return_type.raw_type, + method_sig.arg_types[0][1].raw_type, + method_sig.arg_types[1][1].raw_type, + method_sig.arg_types[2][1].raw_type, + method_sig.arg_types[3][1].raw_type) + else + raise 'should not happen' + end + end + + def self.create_validator_method_fast0(mod, original_method, method_sig, return_type) + mod.send(:define_method, method_sig.method_name) do |&blk| + # This method is a manually sped-up version of more general code in `validate_call` + # The following line breaks are intentional to show nice pry message + + + + + + + + + + + # PRY note: + # this code is sig validation code. + # Please issue `finish` to step out of it + + return_value = original_method.bind_call(self, &blk) + unless return_value.is_a?(return_type) + message = method_sig.return_type.error_message_for_obj(return_value) + if message + CallValidation.report_error( + method_sig, + message, + 'Return value', + nil, + method_sig.return_type, + return_value, + caller_offset: -1 + ) + end + end + return_value + end + end + + def self.create_validator_method_fast1(mod, original_method, method_sig, return_type, arg0_type) + mod.send(:define_method, method_sig.method_name) do |arg0, &blk| + # This method is a manually sped-up version of more general code in `validate_call` + unless arg0.is_a?(arg0_type) + CallValidation.report_error( + method_sig, + method_sig.arg_types[0][1].error_message_for_obj(arg0), + 'Parameter', + method_sig.arg_types[0][0], + arg0_type, + arg0, + caller_offset: -1 + ) + end + + # The following line breaks are intentional to show nice pry message + + + + + + + + + + + # PRY note: + # this code is sig validation code. + # Please issue `finish` to step out of it + + return_value = original_method.bind_call(self, arg0, &blk) + unless return_value.is_a?(return_type) + message = method_sig.return_type.error_message_for_obj(return_value) + if message + CallValidation.report_error( + method_sig, + message, + 'Return value', + nil, + method_sig.return_type, + return_value, + caller_offset: -1 + ) + end + end + return_value + end + end + + def self.create_validator_method_fast2(mod, original_method, method_sig, return_type, arg0_type, arg1_type) + mod.send(:define_method, method_sig.method_name) do |arg0, arg1, &blk| + # This method is a manually sped-up version of more general code in `validate_call` + unless arg0.is_a?(arg0_type) + CallValidation.report_error( + method_sig, + method_sig.arg_types[0][1].error_message_for_obj(arg0), + 'Parameter', + method_sig.arg_types[0][0], + arg0_type, + arg0, + caller_offset: -1 + ) + end + + unless arg1.is_a?(arg1_type) + CallValidation.report_error( + method_sig, + method_sig.arg_types[1][1].error_message_for_obj(arg1), + 'Parameter', + method_sig.arg_types[1][0], + arg1_type, + arg1, + caller_offset: -1 + ) + end + + # The following line breaks are intentional to show nice pry message + + + + + + + + + + + # PRY note: + # this code is sig validation code. + # Please issue `finish` to step out of it + + return_value = original_method.bind_call(self, arg0, arg1, &blk) + unless return_value.is_a?(return_type) + message = method_sig.return_type.error_message_for_obj(return_value) + if message + CallValidation.report_error( + method_sig, + message, + 'Return value', + nil, + method_sig.return_type, + return_value, + caller_offset: -1 + ) + end + end + return_value + end + end + + def self.create_validator_method_fast3(mod, original_method, method_sig, return_type, arg0_type, arg1_type, arg2_type) + mod.send(:define_method, method_sig.method_name) do |arg0, arg1, arg2, &blk| + # This method is a manually sped-up version of more general code in `validate_call` + unless arg0.is_a?(arg0_type) + CallValidation.report_error( + method_sig, + method_sig.arg_types[0][1].error_message_for_obj(arg0), + 'Parameter', + method_sig.arg_types[0][0], + arg0_type, + arg0, + caller_offset: -1 + ) + end + + unless arg1.is_a?(arg1_type) + CallValidation.report_error( + method_sig, + method_sig.arg_types[1][1].error_message_for_obj(arg1), + 'Parameter', + method_sig.arg_types[1][0], + arg1_type, + arg1, + caller_offset: -1 + ) + end + + unless arg2.is_a?(arg2_type) + CallValidation.report_error( + method_sig, + method_sig.arg_types[2][1].error_message_for_obj(arg2), + 'Parameter', + method_sig.arg_types[2][0], + arg2_type, + arg2, + caller_offset: -1 + ) + end + + # The following line breaks are intentional to show nice pry message + + + + + + + + + + + # PRY note: + # this code is sig validation code. + # Please issue `finish` to step out of it + + return_value = original_method.bind_call(self, arg0, arg1, arg2, &blk) + unless return_value.is_a?(return_type) + message = method_sig.return_type.error_message_for_obj(return_value) + if message + CallValidation.report_error( + method_sig, + message, + 'Return value', + nil, + method_sig.return_type, + return_value, + caller_offset: -1 + ) + end + end + return_value + end + end + + def self.create_validator_method_fast4(mod, original_method, method_sig, return_type, arg0_type, arg1_type, arg2_type, arg3_type) + mod.send(:define_method, method_sig.method_name) do |arg0, arg1, arg2, arg3, &blk| + # This method is a manually sped-up version of more general code in `validate_call` + unless arg0.is_a?(arg0_type) + CallValidation.report_error( + method_sig, + method_sig.arg_types[0][1].error_message_for_obj(arg0), + 'Parameter', + method_sig.arg_types[0][0], + arg0_type, + arg0, + caller_offset: -1 + ) + end + + unless arg1.is_a?(arg1_type) + CallValidation.report_error( + method_sig, + method_sig.arg_types[1][1].error_message_for_obj(arg1), + 'Parameter', + method_sig.arg_types[1][0], + arg1_type, + arg1, + caller_offset: -1 + ) + end + + unless arg2.is_a?(arg2_type) + CallValidation.report_error( + method_sig, + method_sig.arg_types[2][1].error_message_for_obj(arg2), + 'Parameter', + method_sig.arg_types[2][0], + arg2_type, + arg2, + caller_offset: -1 + ) + end + + unless arg3.is_a?(arg3_type) + CallValidation.report_error( + method_sig, + method_sig.arg_types[3][1].error_message_for_obj(arg3), + 'Parameter', + method_sig.arg_types[3][0], + arg3_type, + arg3, + caller_offset: -1 + ) + end + + # The following line breaks are intentional to show nice pry message + + + + + + + + + + + # PRY note: + # this code is sig validation code. + # Please issue `finish` to step out of it + + return_value = original_method.bind_call(self, arg0, arg1, arg2, arg3, &blk) + unless return_value.is_a?(return_type) + message = method_sig.return_type.error_message_for_obj(return_value) + if message + CallValidation.report_error( + method_sig, + message, + 'Return value', + nil, + method_sig.return_type, + return_value, + caller_offset: -1 + ) + end + end + return_value + end + end + + def self.create_validator_procedure_fast(mod, original_method, method_sig) + # trampoline to reduce stack frame size + if method_sig.arg_types.empty? + create_validator_procedure_fast0(mod, original_method, method_sig) + elsif method_sig.arg_types.length == 1 + create_validator_procedure_fast1(mod, original_method, method_sig, + method_sig.arg_types[0][1].raw_type) + elsif method_sig.arg_types.length == 2 + create_validator_procedure_fast2(mod, original_method, method_sig, + method_sig.arg_types[0][1].raw_type, + method_sig.arg_types[1][1].raw_type) + elsif method_sig.arg_types.length == 3 + create_validator_procedure_fast3(mod, original_method, method_sig, + method_sig.arg_types[0][1].raw_type, + method_sig.arg_types[1][1].raw_type, + method_sig.arg_types[2][1].raw_type) + elsif method_sig.arg_types.length == 4 + create_validator_procedure_fast4(mod, original_method, method_sig, + method_sig.arg_types[0][1].raw_type, + method_sig.arg_types[1][1].raw_type, + method_sig.arg_types[2][1].raw_type, + method_sig.arg_types[3][1].raw_type) + else + raise 'should not happen' + end + end + + def self.create_validator_procedure_fast0(mod, original_method, method_sig) + mod.send(:define_method, method_sig.method_name) do |&blk| + # This method is a manually sped-up version of more general code in `validate_call` + # The following line breaks are intentional to show nice pry message + + + + + + + + + + + # PRY note: + # this code is sig validation code. + # Please issue `finish` to step out of it + + original_method.bind_call(self, &blk) + T::Private::Types::Void::VOID + end + end + + def self.create_validator_procedure_fast1(mod, original_method, method_sig, arg0_type) + mod.send(:define_method, method_sig.method_name) do |arg0, &blk| + # This method is a manually sped-up version of more general code in `validate_call` + unless arg0.is_a?(arg0_type) + CallValidation.report_error( + method_sig, + method_sig.arg_types[0][1].error_message_for_obj(arg0), + 'Parameter', + method_sig.arg_types[0][0], + arg0_type, + arg0, + caller_offset: -1 + ) + end + + # The following line breaks are intentional to show nice pry message + + + + + + + + + + + # PRY note: + # this code is sig validation code. + # Please issue `finish` to step out of it + + original_method.bind_call(self, arg0, &blk) + T::Private::Types::Void::VOID + end + end + + def self.create_validator_procedure_fast2(mod, original_method, method_sig, arg0_type, arg1_type) + mod.send(:define_method, method_sig.method_name) do |arg0, arg1, &blk| + # This method is a manually sped-up version of more general code in `validate_call` + unless arg0.is_a?(arg0_type) + CallValidation.report_error( + method_sig, + method_sig.arg_types[0][1].error_message_for_obj(arg0), + 'Parameter', + method_sig.arg_types[0][0], + arg0_type, + arg0, + caller_offset: -1 + ) + end + + unless arg1.is_a?(arg1_type) + CallValidation.report_error( + method_sig, + method_sig.arg_types[1][1].error_message_for_obj(arg1), + 'Parameter', + method_sig.arg_types[1][0], + arg1_type, + arg1, + caller_offset: -1 + ) + end + + # The following line breaks are intentional to show nice pry message + + + + + + + + + + + # PRY note: + # this code is sig validation code. + # Please issue `finish` to step out of it + + original_method.bind_call(self, arg0, arg1, &blk) + T::Private::Types::Void::VOID + end + end + + def self.create_validator_procedure_fast3(mod, original_method, method_sig, arg0_type, arg1_type, arg2_type) + mod.send(:define_method, method_sig.method_name) do |arg0, arg1, arg2, &blk| + # This method is a manually sped-up version of more general code in `validate_call` + unless arg0.is_a?(arg0_type) + CallValidation.report_error( + method_sig, + method_sig.arg_types[0][1].error_message_for_obj(arg0), + 'Parameter', + method_sig.arg_types[0][0], + arg0_type, + arg0, + caller_offset: -1 + ) + end + + unless arg1.is_a?(arg1_type) + CallValidation.report_error( + method_sig, + method_sig.arg_types[1][1].error_message_for_obj(arg1), + 'Parameter', + method_sig.arg_types[1][0], + arg1_type, + arg1, + caller_offset: -1 + ) + end + + unless arg2.is_a?(arg2_type) + CallValidation.report_error( + method_sig, + method_sig.arg_types[2][1].error_message_for_obj(arg2), + 'Parameter', + method_sig.arg_types[2][0], + arg2_type, + arg2, + caller_offset: -1 + ) + end + + # The following line breaks are intentional to show nice pry message + + + + + + + + + + + # PRY note: + # this code is sig validation code. + # Please issue `finish` to step out of it + + original_method.bind_call(self, arg0, arg1, arg2, &blk) + T::Private::Types::Void::VOID + end + end + + def self.create_validator_procedure_fast4(mod, original_method, method_sig, arg0_type, arg1_type, arg2_type, arg3_type) + mod.send(:define_method, method_sig.method_name) do |arg0, arg1, arg2, arg3, &blk| + # This method is a manually sped-up version of more general code in `validate_call` + unless arg0.is_a?(arg0_type) + CallValidation.report_error( + method_sig, + method_sig.arg_types[0][1].error_message_for_obj(arg0), + 'Parameter', + method_sig.arg_types[0][0], + arg0_type, + arg0, + caller_offset: -1 + ) + end + + unless arg1.is_a?(arg1_type) + CallValidation.report_error( + method_sig, + method_sig.arg_types[1][1].error_message_for_obj(arg1), + 'Parameter', + method_sig.arg_types[1][0], + arg1_type, + arg1, + caller_offset: -1 + ) + end + + unless arg2.is_a?(arg2_type) + CallValidation.report_error( + method_sig, + method_sig.arg_types[2][1].error_message_for_obj(arg2), + 'Parameter', + method_sig.arg_types[2][0], + arg2_type, + arg2, + caller_offset: -1 + ) + end + + unless arg3.is_a?(arg3_type) + CallValidation.report_error( + method_sig, + method_sig.arg_types[3][1].error_message_for_obj(arg3), + 'Parameter', + method_sig.arg_types[3][0], + arg3_type, + arg3, + caller_offset: -1 + ) + end + + # The following line breaks are intentional to show nice pry message + + + + + + + + + + + # PRY note: + # this code is sig validation code. + # Please issue `finish` to step out of it + + original_method.bind_call(self, arg0, arg1, arg2, arg3, &blk) + T::Private::Types::Void::VOID + end + end + + def self.create_validator_method_medium(mod, original_method, method_sig) + if method_sig.return_type.is_a?(T::Private::Types::Void) + raise 'Should have used create_validator_procedure_medium' + end + # trampoline to reduce stack frame size + if method_sig.arg_types.empty? + create_validator_method_medium0(mod, original_method, method_sig, method_sig.return_type) + elsif method_sig.arg_types.length == 1 + create_validator_method_medium1(mod, original_method, method_sig, method_sig.return_type, + method_sig.arg_types[0][1]) + elsif method_sig.arg_types.length == 2 + create_validator_method_medium2(mod, original_method, method_sig, method_sig.return_type, + method_sig.arg_types[0][1], + method_sig.arg_types[1][1]) + elsif method_sig.arg_types.length == 3 + create_validator_method_medium3(mod, original_method, method_sig, method_sig.return_type, + method_sig.arg_types[0][1], + method_sig.arg_types[1][1], + method_sig.arg_types[2][1]) + elsif method_sig.arg_types.length == 4 + create_validator_method_medium4(mod, original_method, method_sig, method_sig.return_type, + method_sig.arg_types[0][1], + method_sig.arg_types[1][1], + method_sig.arg_types[2][1], + method_sig.arg_types[3][1]) + else + raise 'should not happen' + end + end + + def self.create_validator_method_medium0(mod, original_method, method_sig, return_type) + mod.send(:define_method, method_sig.method_name) do |&blk| + # This method is a manually sped-up version of more general code in `validate_call` + # The following line breaks are intentional to show nice pry message + + + + + + + + + + + # PRY note: + # this code is sig validation code. + # Please issue `finish` to step out of it + + return_value = original_method.bind_call(self, &blk) + unless return_type.valid?(return_value) + message = method_sig.return_type.error_message_for_obj(return_value) + if message + CallValidation.report_error( + method_sig, + message, + 'Return value', + nil, + method_sig.return_type, + return_value, + caller_offset: -1 + ) + end + end + return_value + end + end + + def self.create_validator_method_medium1(mod, original_method, method_sig, return_type, arg0_type) + mod.send(:define_method, method_sig.method_name) do |arg0, &blk| + # This method is a manually sped-up version of more general code in `validate_call` + unless arg0_type.valid?(arg0) + CallValidation.report_error( + method_sig, + method_sig.arg_types[0][1].error_message_for_obj(arg0), + 'Parameter', + method_sig.arg_types[0][0], + arg0_type, + arg0, + caller_offset: -1 + ) + end + + # The following line breaks are intentional to show nice pry message + + + + + + + + + + + # PRY note: + # this code is sig validation code. + # Please issue `finish` to step out of it + + return_value = original_method.bind_call(self, arg0, &blk) + unless return_type.valid?(return_value) + message = method_sig.return_type.error_message_for_obj(return_value) + if message + CallValidation.report_error( + method_sig, + message, + 'Return value', + nil, + method_sig.return_type, + return_value, + caller_offset: -1 + ) + end + end + return_value + end + end + + def self.create_validator_method_medium2(mod, original_method, method_sig, return_type, arg0_type, arg1_type) + mod.send(:define_method, method_sig.method_name) do |arg0, arg1, &blk| + # This method is a manually sped-up version of more general code in `validate_call` + unless arg0_type.valid?(arg0) + CallValidation.report_error( + method_sig, + method_sig.arg_types[0][1].error_message_for_obj(arg0), + 'Parameter', + method_sig.arg_types[0][0], + arg0_type, + arg0, + caller_offset: -1 + ) + end + + unless arg1_type.valid?(arg1) + CallValidation.report_error( + method_sig, + method_sig.arg_types[1][1].error_message_for_obj(arg1), + 'Parameter', + method_sig.arg_types[1][0], + arg1_type, + arg1, + caller_offset: -1 + ) + end + + # The following line breaks are intentional to show nice pry message + + + + + + + + + + + # PRY note: + # this code is sig validation code. + # Please issue `finish` to step out of it + + return_value = original_method.bind_call(self, arg0, arg1, &blk) + unless return_type.valid?(return_value) + message = method_sig.return_type.error_message_for_obj(return_value) + if message + CallValidation.report_error( + method_sig, + message, + 'Return value', + nil, + method_sig.return_type, + return_value, + caller_offset: -1 + ) + end + end + return_value + end + end + + def self.create_validator_method_medium3(mod, original_method, method_sig, return_type, arg0_type, arg1_type, arg2_type) + mod.send(:define_method, method_sig.method_name) do |arg0, arg1, arg2, &blk| + # This method is a manually sped-up version of more general code in `validate_call` + unless arg0_type.valid?(arg0) + CallValidation.report_error( + method_sig, + method_sig.arg_types[0][1].error_message_for_obj(arg0), + 'Parameter', + method_sig.arg_types[0][0], + arg0_type, + arg0, + caller_offset: -1 + ) + end + + unless arg1_type.valid?(arg1) + CallValidation.report_error( + method_sig, + method_sig.arg_types[1][1].error_message_for_obj(arg1), + 'Parameter', + method_sig.arg_types[1][0], + arg1_type, + arg1, + caller_offset: -1 + ) + end + + unless arg2_type.valid?(arg2) + CallValidation.report_error( + method_sig, + method_sig.arg_types[2][1].error_message_for_obj(arg2), + 'Parameter', + method_sig.arg_types[2][0], + arg2_type, + arg2, + caller_offset: -1 + ) + end + + # The following line breaks are intentional to show nice pry message + + + + + + + + + + + # PRY note: + # this code is sig validation code. + # Please issue `finish` to step out of it + + return_value = original_method.bind_call(self, arg0, arg1, arg2, &blk) + unless return_type.valid?(return_value) + message = method_sig.return_type.error_message_for_obj(return_value) + if message + CallValidation.report_error( + method_sig, + message, + 'Return value', + nil, + method_sig.return_type, + return_value, + caller_offset: -1 + ) + end + end + return_value + end + end + + def self.create_validator_method_medium4(mod, original_method, method_sig, return_type, arg0_type, arg1_type, arg2_type, arg3_type) + mod.send(:define_method, method_sig.method_name) do |arg0, arg1, arg2, arg3, &blk| + # This method is a manually sped-up version of more general code in `validate_call` + unless arg0_type.valid?(arg0) + CallValidation.report_error( + method_sig, + method_sig.arg_types[0][1].error_message_for_obj(arg0), + 'Parameter', + method_sig.arg_types[0][0], + arg0_type, + arg0, + caller_offset: -1 + ) + end + + unless arg1_type.valid?(arg1) + CallValidation.report_error( + method_sig, + method_sig.arg_types[1][1].error_message_for_obj(arg1), + 'Parameter', + method_sig.arg_types[1][0], + arg1_type, + arg1, + caller_offset: -1 + ) + end + + unless arg2_type.valid?(arg2) + CallValidation.report_error( + method_sig, + method_sig.arg_types[2][1].error_message_for_obj(arg2), + 'Parameter', + method_sig.arg_types[2][0], + arg2_type, + arg2, + caller_offset: -1 + ) + end + + unless arg3_type.valid?(arg3) + CallValidation.report_error( + method_sig, + method_sig.arg_types[3][1].error_message_for_obj(arg3), + 'Parameter', + method_sig.arg_types[3][0], + arg3_type, + arg3, + caller_offset: -1 + ) + end + + # The following line breaks are intentional to show nice pry message + + + + + + + + + + + # PRY note: + # this code is sig validation code. + # Please issue `finish` to step out of it + + return_value = original_method.bind_call(self, arg0, arg1, arg2, arg3, &blk) + unless return_type.valid?(return_value) + message = method_sig.return_type.error_message_for_obj(return_value) + if message + CallValidation.report_error( + method_sig, + message, + 'Return value', + nil, + method_sig.return_type, + return_value, + caller_offset: -1 + ) + end + end + return_value + end + end + + def self.create_validator_procedure_medium(mod, original_method, method_sig) + # trampoline to reduce stack frame size + if method_sig.arg_types.empty? + create_validator_procedure_medium0(mod, original_method, method_sig) + elsif method_sig.arg_types.length == 1 + create_validator_procedure_medium1(mod, original_method, method_sig, + method_sig.arg_types[0][1]) + elsif method_sig.arg_types.length == 2 + create_validator_procedure_medium2(mod, original_method, method_sig, + method_sig.arg_types[0][1], + method_sig.arg_types[1][1]) + elsif method_sig.arg_types.length == 3 + create_validator_procedure_medium3(mod, original_method, method_sig, + method_sig.arg_types[0][1], + method_sig.arg_types[1][1], + method_sig.arg_types[2][1]) + elsif method_sig.arg_types.length == 4 + create_validator_procedure_medium4(mod, original_method, method_sig, + method_sig.arg_types[0][1], + method_sig.arg_types[1][1], + method_sig.arg_types[2][1], + method_sig.arg_types[3][1]) + else + raise 'should not happen' + end + end + + def self.create_validator_procedure_medium0(mod, original_method, method_sig) + mod.send(:define_method, method_sig.method_name) do |&blk| + # This method is a manually sped-up version of more general code in `validate_call` + # The following line breaks are intentional to show nice pry message + + + + + + + + + + + # PRY note: + # this code is sig validation code. + # Please issue `finish` to step out of it + + original_method.bind_call(self, &blk) + T::Private::Types::Void::VOID + end + end + + def self.create_validator_procedure_medium1(mod, original_method, method_sig, arg0_type) + mod.send(:define_method, method_sig.method_name) do |arg0, &blk| + # This method is a manually sped-up version of more general code in `validate_call` + unless arg0_type.valid?(arg0) + CallValidation.report_error( + method_sig, + method_sig.arg_types[0][1].error_message_for_obj(arg0), + 'Parameter', + method_sig.arg_types[0][0], + arg0_type, + arg0, + caller_offset: -1 + ) + end + + # The following line breaks are intentional to show nice pry message + + + + + + + + + + + # PRY note: + # this code is sig validation code. + # Please issue `finish` to step out of it + + original_method.bind_call(self, arg0, &blk) + T::Private::Types::Void::VOID + end + end + + def self.create_validator_procedure_medium2(mod, original_method, method_sig, arg0_type, arg1_type) + mod.send(:define_method, method_sig.method_name) do |arg0, arg1, &blk| + # This method is a manually sped-up version of more general code in `validate_call` + unless arg0_type.valid?(arg0) + CallValidation.report_error( + method_sig, + method_sig.arg_types[0][1].error_message_for_obj(arg0), + 'Parameter', + method_sig.arg_types[0][0], + arg0_type, + arg0, + caller_offset: -1 + ) + end + + unless arg1_type.valid?(arg1) + CallValidation.report_error( + method_sig, + method_sig.arg_types[1][1].error_message_for_obj(arg1), + 'Parameter', + method_sig.arg_types[1][0], + arg1_type, + arg1, + caller_offset: -1 + ) + end + + # The following line breaks are intentional to show nice pry message + + + + + + + + + + + # PRY note: + # this code is sig validation code. + # Please issue `finish` to step out of it + + original_method.bind_call(self, arg0, arg1, &blk) + T::Private::Types::Void::VOID + end + end + + def self.create_validator_procedure_medium3(mod, original_method, method_sig, arg0_type, arg1_type, arg2_type) + mod.send(:define_method, method_sig.method_name) do |arg0, arg1, arg2, &blk| + # This method is a manually sped-up version of more general code in `validate_call` + unless arg0_type.valid?(arg0) + CallValidation.report_error( + method_sig, + method_sig.arg_types[0][1].error_message_for_obj(arg0), + 'Parameter', + method_sig.arg_types[0][0], + arg0_type, + arg0, + caller_offset: -1 + ) + end + + unless arg1_type.valid?(arg1) + CallValidation.report_error( + method_sig, + method_sig.arg_types[1][1].error_message_for_obj(arg1), + 'Parameter', + method_sig.arg_types[1][0], + arg1_type, + arg1, + caller_offset: -1 + ) + end + + unless arg2_type.valid?(arg2) + CallValidation.report_error( + method_sig, + method_sig.arg_types[2][1].error_message_for_obj(arg2), + 'Parameter', + method_sig.arg_types[2][0], + arg2_type, + arg2, + caller_offset: -1 + ) + end + + # The following line breaks are intentional to show nice pry message + + + + + + + + + + + # PRY note: + # this code is sig validation code. + # Please issue `finish` to step out of it + + original_method.bind_call(self, arg0, arg1, arg2, &blk) + T::Private::Types::Void::VOID + end + end + + def self.create_validator_procedure_medium4(mod, original_method, method_sig, arg0_type, arg1_type, arg2_type, arg3_type) + mod.send(:define_method, method_sig.method_name) do |arg0, arg1, arg2, arg3, &blk| + # This method is a manually sped-up version of more general code in `validate_call` + unless arg0_type.valid?(arg0) + CallValidation.report_error( + method_sig, + method_sig.arg_types[0][1].error_message_for_obj(arg0), + 'Parameter', + method_sig.arg_types[0][0], + arg0_type, + arg0, + caller_offset: -1 + ) + end + + unless arg1_type.valid?(arg1) + CallValidation.report_error( + method_sig, + method_sig.arg_types[1][1].error_message_for_obj(arg1), + 'Parameter', + method_sig.arg_types[1][0], + arg1_type, + arg1, + caller_offset: -1 + ) + end + + unless arg2_type.valid?(arg2) + CallValidation.report_error( + method_sig, + method_sig.arg_types[2][1].error_message_for_obj(arg2), + 'Parameter', + method_sig.arg_types[2][0], + arg2_type, + arg2, + caller_offset: -1 + ) + end + + unless arg3_type.valid?(arg3) + CallValidation.report_error( + method_sig, + method_sig.arg_types[3][1].error_message_for_obj(arg3), + 'Parameter', + method_sig.arg_types[3][0], + arg3_type, + arg3, + caller_offset: -1 + ) + end + + # The following line breaks are intentional to show nice pry message + + + + + + + + + + + # PRY note: + # this code is sig validation code. + # Please issue `finish` to step out of it + + original_method.bind_call(self, arg0, arg1, arg2, arg3, &blk) + T::Private::Types::Void::VOID + end + end + +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/decl_builder.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/decl_builder.rb new file mode 100644 index 0000000000..b48b1d5b68 --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/decl_builder.rb @@ -0,0 +1,232 @@ +# frozen_string_literal: true +# typed: true + +module T::Private::Methods + Declaration = Struct.new(:mod, :params, :returns, :bind, :mode, :checked, :finalized, :on_failure, :override_allow_incompatible, :type_parameters, :raw) + + class DeclBuilder + attr_reader :decl + + class BuilderError < StandardError; end + + private def check_live! + if decl.finalized + raise BuilderError.new("You can't modify a signature declaration after it has been used.") + end + end + + def initialize(mod, raw) + # TODO RUBYPLAT-1278 - with ruby 2.5, use kwargs here + @decl = Declaration.new( + mod, + ARG_NOT_PROVIDED, # params + ARG_NOT_PROVIDED, # returns + ARG_NOT_PROVIDED, # bind + Modes.standard, # mode + ARG_NOT_PROVIDED, # checked + false, # finalized + ARG_NOT_PROVIDED, # on_failure + nil, # override_allow_incompatible + ARG_NOT_PROVIDED, # type_parameters + raw + ) + end + + def params(**params) + check_live! + if !decl.params.equal?(ARG_NOT_PROVIDED) + raise BuilderError.new("You can't call .params twice") + end + + if params.empty? + raise BuilderError.new("params expects keyword arguments") + end + decl.params = params + + self + end + + def returns(type) + check_live! + if decl.returns.is_a?(T::Private::Types::Void) + raise BuilderError.new("You can't call .returns after calling .void.") + end + if !decl.returns.equal?(ARG_NOT_PROVIDED) + raise BuilderError.new("You can't call .returns multiple times in a signature.") + end + + decl.returns = type + + self + end + + def void + check_live! + if !decl.returns.equal?(ARG_NOT_PROVIDED) + raise BuilderError.new("You can't call .void after calling .returns.") + end + + decl.returns = T::Private::Types::Void.new + + self + end + + def bind(type) + check_live! + if !decl.bind.equal?(ARG_NOT_PROVIDED) + raise BuilderError.new("You can't call .bind multiple times in a signature.") + end + + decl.bind = type + + self + end + + def checked(level) + check_live! + + if !decl.checked.equal?(ARG_NOT_PROVIDED) + raise BuilderError.new("You can't call .checked multiple times in a signature.") + end + if (level == :never || level == :compiled) && !decl.on_failure.equal?(ARG_NOT_PROVIDED) + raise BuilderError.new("You can't use .checked(:#{level}) with .on_failure because .on_failure will have no effect.") + end + if !T::Private::RuntimeLevels::LEVELS.include?(level) + raise BuilderError.new("Invalid `checked` level '#{level}'. Use one of: #{T::Private::RuntimeLevels::LEVELS}.") + end + + decl.checked = level + + self + end + + def on_failure(*args) + check_live! + + if !decl.on_failure.equal?(ARG_NOT_PROVIDED) + raise BuilderError.new("You can't call .on_failure multiple times in a signature.") + end + if decl.checked == :never || decl.checked == :compiled + raise BuilderError.new("You can't use .on_failure with .checked(:#{decl.checked}) because .on_failure will have no effect.") + end + + decl.on_failure = args + + self + end + + def abstract + check_live! + + case decl.mode + when Modes.standard + decl.mode = Modes.abstract + when Modes.abstract + raise BuilderError.new(".abstract cannot be repeated in a single signature") + else + raise BuilderError.new("`.abstract` cannot be combined with `.override` or `.overridable`.") + end + + self + end + + def final + check_live! + raise BuilderError.new("The syntax for declaring a method final is `sig(:final) {...}`, not `sig {final. ...}`") + end + + def override(allow_incompatible: false) + check_live! + + case decl.mode + when Modes.standard + decl.mode = Modes.override + decl.override_allow_incompatible = allow_incompatible + when Modes.override, Modes.overridable_override + raise BuilderError.new(".override cannot be repeated in a single signature") + when Modes.overridable + decl.mode = Modes.overridable_override + else + raise BuilderError.new("`.override` cannot be combined with `.abstract`.") + end + + self + end + + def overridable + check_live! + + case decl.mode + when Modes.abstract + raise BuilderError.new("`.overridable` cannot be combined with `.#{decl.mode}`") + when Modes.override + decl.mode = Modes.overridable_override + when Modes.standard + decl.mode = Modes.overridable + when Modes.overridable, Modes.overridable_override + raise BuilderError.new(".overridable cannot be repeated in a single signature") + end + + self + end + + # Declares valid type paramaters which can be used with `T.type_parameter` in + # this `sig`. + # + # This is used for generic methods. Example usage: + # + # sig do + # type_parameters(:U) + # .params(blk: T.proc.params(arg0: Elem).returns(T.type_parameter(:U))) + # .returns(T::Array[T.type_parameter(:U)]) + # end + # def map(&blk); end + def type_parameters(*names) + check_live! + + names.each do |name| + raise BuilderError.new("not a symbol: #{name}") unless name.is_a?(Symbol) + end + + if !decl.type_parameters.equal?(ARG_NOT_PROVIDED) + raise BuilderError.new("You can't call .type_parameters multiple times in a signature.") + end + + decl.type_parameters = names + + self + end + + def finalize! + check_live! + + if decl.returns.equal?(ARG_NOT_PROVIDED) + raise BuilderError.new("You must provide a return type; use the `.returns` or `.void` builder methods.") + end + + if decl.bind.equal?(ARG_NOT_PROVIDED) + decl.bind = nil + end + if decl.checked.equal?(ARG_NOT_PROVIDED) + default_checked_level = T::Private::RuntimeLevels.default_checked_level + if (default_checked_level == :never || default_checked_level == :compiled) && !decl.on_failure.equal?(ARG_NOT_PROVIDED) + raise BuilderError.new("To use .on_failure you must additionally call .checked(:tests) or .checked(:always), otherwise, the .on_failure has no effect.") + end + decl.checked = default_checked_level + end + if decl.on_failure.equal?(ARG_NOT_PROVIDED) + decl.on_failure = nil + end + if decl.params.equal?(ARG_NOT_PROVIDED) + decl.params = {} + end + if decl.type_parameters.equal?(ARG_NOT_PROVIDED) + decl.type_parameters = {} + end + + decl.finalized = true + + self + end + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/modes.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/modes.rb new file mode 100644 index 0000000000..53d9a93195 --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/modes.rb @@ -0,0 +1,28 @@ +# frozen_string_literal: true +# typed: true + +module T::Private::Methods::Modes + def self.standard + 'standard' + end + def self.abstract + 'abstract' + end + def self.overridable + 'overridable' + end + def self.override + 'override' + end + def self.overridable_override + 'overridable_override' + end + def self.untyped + 'untyped' + end + MODES = [self.standard, self.abstract, self.overridable, self.override, self.overridable_override, self.untyped].freeze + + OVERRIDABLE_MODES = [self.override, self.overridable, self.overridable_override, self.untyped, self.abstract].freeze + OVERRIDE_MODES = [self.override, self.overridable_override].freeze + NON_OVERRIDE_MODES = MODES - OVERRIDE_MODES +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/signature.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/signature.rb new file mode 100644 index 0000000000..bd15977bd5 --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/signature.rb @@ -0,0 +1,225 @@ +# frozen_string_literal: true +# typed: true + +class T::Private::Methods::Signature + attr_reader :method, :method_name, :arg_types, :kwarg_types, :block_type, :block_name, + :rest_type, :rest_name, :keyrest_type, :keyrest_name, :bind, + :return_type, :mode, :req_arg_count, :req_kwarg_names, :has_rest, :has_keyrest, + :check_level, :parameters, :on_failure, :override_allow_incompatible, + :defined_raw + + def self.new_untyped(method:, mode: T::Private::Methods::Modes.untyped, parameters: method.parameters) + # Using `Untyped` ensures we'll get an error if we ever try validation on these. + not_typed = T::Private::Types::NotTyped.new + raw_return_type = not_typed + # Map missing parameter names to "argN" positionally + parameters = parameters.each_with_index.map do |(param_kind, param_name), index| + [param_kind, param_name || "arg#{index}"] + end + raw_arg_types = parameters.map do |_param_kind, param_name| + [param_name, not_typed] + end.to_h + + self.new( + method: method, + method_name: method.name, + raw_arg_types: raw_arg_types, + raw_return_type: raw_return_type, + bind: nil, + mode: mode, + check_level: :never, + parameters: parameters, + on_failure: nil, + ) + end + + def initialize(method:, method_name:, raw_arg_types:, raw_return_type:, bind:, mode:, check_level:, on_failure:, parameters: method.parameters, override_allow_incompatible: false, defined_raw: false) + @method = method + @method_name = method_name + @arg_types = [] + @kwarg_types = {} + @block_type = nil + @block_name = nil + @rest_type = nil + @rest_name = nil + @keyrest_type = nil + @keyrest_name = nil + @return_type = T::Utils.coerce(raw_return_type) + @bind = bind ? T::Utils.coerce(bind) : bind + @mode = mode + @check_level = check_level + @req_arg_count = 0 + @req_kwarg_names = [] + @has_rest = false + @has_keyrest = false + @parameters = parameters + @on_failure = on_failure + @override_allow_incompatible = override_allow_incompatible + @defined_raw = defined_raw + + declared_param_names = raw_arg_types.keys + # If sig params are declared but there is a single parameter with a missing name + # **and** the method ends with a "=", assume it is a writer method generated + # by attr_writer or attr_accessor + writer_method = declared_param_names != [nil] && parameters == [[:req]] && method_name[-1] == "=" + # For writer methods, map the single parameter to the method name without the "=" at the end + parameters = [[:req, method_name[0...-1].to_sym]] if writer_method + param_names = parameters.map {|_, name| name} + missing_names = param_names - declared_param_names + extra_names = declared_param_names - param_names + if !missing_names.empty? + raise "The declaration for `#{method.name}` is missing parameter(s): #{missing_names.join(', ')}" + end + if !extra_names.empty? + raise "The declaration for `#{method.name}` has extra parameter(s): #{extra_names.join(', ')}" + end + + if parameters.size != raw_arg_types.size + raise "The declaration for `#{method.name}` has arguments with duplicate names" + end + + parameters.zip(raw_arg_types) do |(param_kind, param_name), (type_name, raw_type)| + if type_name != param_name + hint = "" + # Ruby reorders params so that required keyword arguments + # always precede optional keyword arguments. We can't tell + # whether the culprit is the Ruby reordering or user error, so + # we error but include a note + if param_kind == :keyreq && parameters.any? {|k, _| k == :key} + hint = "\n\nNote: Any required keyword arguments must precede any optional keyword " \ + "arguments. If your method declaration matches your `def`, try reordering any " \ + "optional keyword parameters to the end of the method list." + end + + raise "Parameter `#{type_name}` is declared out of order (declared as arg number " \ + "#{declared_param_names.index(type_name) + 1}, defined in the method as arg number " \ + "#{param_names.index(type_name) + 1}).#{hint}\nMethod: #{method_desc}" + end + + type = T::Utils.coerce(raw_type) + + case param_kind + when :req + if @arg_types.length > @req_arg_count + # Note that this is actually is supported by Ruby, but it would add complexity to + # support it here, and I'm happy to discourage its use anyway. + # + # If you are seeing this error and surprised by it, it's possible that you have + # overridden the method described in the error message. For example, Rails defines + # def self.update!(id = :all, attributes) + # on AR models. If you have also defined `self.update!` on an AR model you might + # see this error. The simplest resolution is to rename your method. + raise "Required params after optional params are not supported in method declarations. Method: #{method_desc}" + end + @arg_types << [param_name, type] + @req_arg_count += 1 + when :opt + @arg_types << [param_name, type] + when :key, :keyreq + @kwarg_types[param_name] = type + if param_kind == :keyreq + @req_kwarg_names << param_name + end + when :block + @block_name = param_name + @block_type = type + when :rest + @has_rest = true + @rest_name = param_name + @rest_type = type + when :keyrest + @has_keyrest = true + @keyrest_name = param_name + @keyrest_type = type + else + raise "Unexpected param_kind: `#{param_kind}`. Method: #{method_desc}" + end + end + end + + attr_writer :method_name + protected :method_name= + + def as_alias(alias_name) + new_sig = clone + new_sig.method_name = alias_name + new_sig + end + + def arg_count + @arg_types.length + end + + def kwarg_names + @kwarg_types.keys + end + + def owner + @method.owner + end + + def dsl_method + "#{@mode}_method" + end + + # @return [Hash] a mapping like `{arg_name: [val, type], ...}`, for only those args actually present. + def each_args_value_type(args) + # Manually split out args and kwargs based on ruby's behavior. Do not try to implement this by + # getting ruby to determine the kwargs for you (e.g., by defining this method to take *args and + # **kwargs). That won't work, because ruby's behavior for determining kwargs is dependent on the + # the other parameters in the method definition, and our method definition here doesn't (and + # can't) match the definition of the method we're validating. In addition, Ruby has a bug that + # causes forwarding **kwargs to do the wrong thing: see https://bugs.ruby-lang.org/issues/10708 + # and https://bugs.ruby-lang.org/issues/11860. + args_length = args.length + if (args_length > @req_arg_count) && (!@kwarg_types.empty? || @has_keyrest) && args[-1].is_a?(Hash) + kwargs = args[-1] + args_length -= 1 + else + kwargs = EMPTY_HASH + end + + arg_types = @arg_types + + if @has_rest + rest_count = args_length - @arg_types.length + rest_count = 0 if rest_count.negative? + + arg_types += [[@rest_name, @rest_type]] * rest_count + + elsif (args_length < @req_arg_count) || (args_length > @arg_types.length) + expected_str = @req_arg_count.to_s + if @arg_types.length != @req_arg_count + expected_str += "..#{@arg_types.length}" + end + raise ArgumentError.new("wrong number of arguments (given #{args_length}, expected #{expected_str})") + end + + begin + it = 0 + while it < args_length + yield arg_types[it][0], args[it], arg_types[it][1] + it += 1 + end + end + + kwargs.each do |name, val| + type = @kwarg_types[name] + if !type && @has_keyrest + type = @keyrest_type + end + yield name, val, type if type + end + end + + def method_desc + loc = if @method.source_location + @method.source_location.join(':') + else + "" + end + "#{@method} at #{loc}" + end + + EMPTY_HASH = {}.freeze +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/signature_validation.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/signature_validation.rb new file mode 100644 index 0000000000..16188e0bf3 --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/signature_validation.rb @@ -0,0 +1,225 @@ +# frozen_string_literal: true +# typed: true + +module T::Private::Methods::SignatureValidation + Methods = T::Private::Methods + Modes = Methods::Modes + + def self.validate(signature) + if signature.method_name == :initialize && signature.method.owner.is_a?(Class) + # Constructors are special. They look like overrides in terms of a super_method existing, + # but in practice, you never call them polymorphically. Conceptually, they're standard + # methods (this is consistent with how they're treated in other languages, e.g. Java) + if signature.mode != Modes.standard + raise "`initialize` should not use `.abstract` or `.implementation` or any other inheritance modifiers." + end + return + end + + super_method = signature.method.super_method + + if super_method && super_method.owner != signature.method.owner + Methods.maybe_run_sig_block_for_method(super_method) + super_signature = Methods.signature_for_method(super_method) + + # If the super_method has any kwargs we can't build a + # Signature for it, so we'll just skip validation in that case. + if !super_signature && !super_method.parameters.select {|kind, _| kind == :rest || kind == :kwrest}.empty? + nil + else + # super_signature can be nil when we're overriding a method (perhaps a builtin) that didn't use + # one of the method signature helpers. Use an untyped signature so we can still validate + # everything but types. + # + # We treat these signatures as overridable, that way people can use `.override` with + # overrides of builtins. In the future we could try to distinguish when the method is a + # builtin and treat non-builtins as non-overridable (so you'd be forced to declare them with + # `.overridable`). + # + super_signature ||= Methods::Signature.new_untyped(method: super_method) + + validate_override_mode(signature, super_signature) + validate_override_shape(signature, super_signature) + validate_override_types(signature, super_signature) + end + else + validate_non_override_mode(signature) + end + end + + private_class_method def self.pretty_mode(signature) + if signature.mode == Modes.overridable_override + '.overridable.override' + else + ".#{signature.mode}" + end + end + + def self.validate_override_mode(signature, super_signature) + case signature.mode + when *Modes::OVERRIDE_MODES + # Peaceful + when *Modes::NON_OVERRIDE_MODES + if super_signature.mode == Modes.standard + # Peaceful + elsif super_signature.mode == Modes.abstract + raise "You must use `.override` when overriding the abstract method `#{signature.method_name}`.\n" \ + " Abstract definition: #{method_loc_str(super_signature.method)}\n" \ + " Implementation definition: #{method_loc_str(signature.method)}\n" + elsif super_signature.mode != Modes.untyped + raise "You must use `.override` when overriding the existing method `#{signature.method_name}`.\n" \ + " Parent definition: #{method_loc_str(super_signature.method)}\n" \ + " Child definition: #{method_loc_str(signature.method)}\n" + end + else + raise "Unexpected mode: #{signature.mode}. Please report this bug at https://github.com/sorbet/sorbet/issues" + end + end + + def self.validate_non_override_mode(signature) + case signature.mode + when Modes.override + if signature.method_name == :each && signature.method.owner < Enumerable + # Enumerable#each is the only method in Sorbet's RBI payload that defines an abstract method. + # Enumerable#each does not actually exist at runtime, but it is required to be implemented by + # any class which includes Enumerable. We want to declare Enumerable#each as abstract so that + # people can call it anything which implements the Enumerable interface, and so that it's a + # static error to forget to implement it. + # + # This is a one-off hack, and we should think carefully before adding more methods here. + nil + else + raise "You marked `#{signature.method_name}` as #{pretty_mode(signature)}, but that method doesn't already exist in this class/module to be overriden.\n" \ + " Either check for typos and for missing includes or super classes to make the parent method shows up\n" \ + " ... or remove #{pretty_mode(signature)} here: #{method_loc_str(signature.method)}\n" + end + when Modes.standard, *Modes::NON_OVERRIDE_MODES + # Peaceful + nil + else + raise "Unexpected mode: #{signature.mode}. Please report this bug at https://github.com/sorbet/sorbet/issues" + end + + # Given a singleton class, we can check if it belongs to a + # module by looking at its superclass; given `module M`, + # `M.singleton_class.superclass == Module`, which is not true + # for any class. + owner = signature.method.owner + if (signature.mode == Modes.abstract || Modes::OVERRIDABLE_MODES.include?(signature.mode)) && + owner.singleton_class? && owner.superclass == Module + raise "Defining an overridable class method (via #{pretty_mode(signature)}) " \ + "on a module is not allowed. Class methods on " \ + "modules do not get inherited and thus cannot be overridden." + end + end + + def self.validate_override_shape(signature, super_signature) + return if signature.override_allow_incompatible + return if super_signature.mode == Modes.untyped + + method_name = signature.method_name + mode_verb = super_signature.mode == Modes.abstract ? 'implements' : 'overrides' + + if !signature.has_rest && signature.arg_count < super_signature.arg_count + raise "Your definition of `#{method_name}` must accept at least #{super_signature.arg_count} " \ + "positional arguments to be compatible with the method it #{mode_verb}: " \ + "#{base_override_loc_str(signature, super_signature)}" + end + + if !signature.has_rest && super_signature.has_rest + raise "Your definition of `#{method_name}` must have `*#{super_signature.rest_name}` " \ + "to be compatible with the method it #{mode_verb}: " \ + "#{base_override_loc_str(signature, super_signature)}" + end + + if signature.req_arg_count > super_signature.req_arg_count + raise "Your definition of `#{method_name}` must have no more than #{super_signature.req_arg_count} " \ + "required argument(s) to be compatible with the method it #{mode_verb}: " \ + "#{base_override_loc_str(signature, super_signature)}" + end + + if !signature.has_keyrest + # O(nm), but n and m are tiny here + missing_kwargs = super_signature.kwarg_names - signature.kwarg_names + if !missing_kwargs.empty? + raise "Your definition of `#{method_name}` is missing these keyword arg(s): #{missing_kwargs} " \ + "which are defined in the method it #{mode_verb}: " \ + "#{base_override_loc_str(signature, super_signature)}" + end + end + + if !signature.has_keyrest && super_signature.has_keyrest + raise "Your definition of `#{method_name}` must have `**#{super_signature.keyrest_name}` " \ + "to be compatible with the method it #{mode_verb}: " \ + "#{base_override_loc_str(signature, super_signature)}" + end + + # O(nm), but n and m are tiny here + extra_req_kwargs = signature.req_kwarg_names - super_signature.req_kwarg_names + if !extra_req_kwargs.empty? + raise "Your definition of `#{method_name}` has extra required keyword arg(s) " \ + "#{extra_req_kwargs} relative to the method it #{mode_verb}, making it incompatible: " \ + "#{base_override_loc_str(signature, super_signature)}" + end + + if super_signature.block_name && !signature.block_name + raise "Your definition of `#{method_name}` must accept a block parameter to be compatible " \ + "with the method it #{mode_verb}: " \ + "#{base_override_loc_str(signature, super_signature)}" + end + end + + def self.validate_override_types(signature, super_signature) + return if signature.override_allow_incompatible + return if super_signature.mode == Modes.untyped + return unless [signature, super_signature].all? do |sig| + sig.check_level == :always || sig.check_level == :compiled || (sig.check_level == :tests && T::Private::RuntimeLevels.check_tests?) + end + mode_noun = super_signature.mode == Modes.abstract ? 'implementation' : 'override' + + # arg types must be contravariant + super_signature.arg_types.zip(signature.arg_types).each_with_index do |((_super_name, super_type), (name, type)), index| + if !super_type.subtype_of?(type) + raise "Incompatible type for arg ##{index + 1} (`#{name}`) in signature for #{mode_noun} of method " \ + "`#{signature.method_name}`:\n" \ + "* Base: `#{super_type}` (in #{method_loc_str(super_signature.method)})\n" \ + "* #{mode_noun.capitalize}: `#{type}` (in #{method_loc_str(signature.method)})\n" \ + "(The types must be contravariant.)" + end + end + + # kwarg types must be contravariant + super_signature.kwarg_types.each do |name, super_type| + type = signature.kwarg_types[name] + if !super_type.subtype_of?(type) + raise "Incompatible type for arg `#{name}` in signature for #{mode_noun} of method `#{signature.method_name}`:\n" \ + "* Base: `#{super_type}` (in #{method_loc_str(super_signature.method)})\n" \ + "* #{mode_noun.capitalize}: `#{type}` (in #{method_loc_str(signature.method)})\n" \ + "(The types must be contravariant.)" + end + end + + # return types must be covariant + if !signature.return_type.subtype_of?(super_signature.return_type) + raise "Incompatible return type in signature for #{mode_noun} of method `#{signature.method_name}`:\n" \ + "* Base: `#{super_signature.return_type}` (in #{method_loc_str(super_signature.method)})\n" \ + "* #{mode_noun.capitalize}: `#{signature.return_type}` (in #{method_loc_str(signature.method)})\n" \ + "(The types must be covariant.)" + end + end + + private_class_method def self.base_override_loc_str(signature, super_signature) + mode_noun = super_signature.mode == Modes.abstract ? 'Implementation' : 'Override' + "\n * Base definition: in #{method_loc_str(super_signature.method)}" \ + "\n * #{mode_noun}: in #{method_loc_str(signature.method)}" + end + + private_class_method def self.method_loc_str(method) + loc = if method.source_location + method.source_location.join(':') + else + "" + end + "#{method.owner} at #{loc}" + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/mixins/mixins.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/mixins/mixins.rb new file mode 100644 index 0000000000..01eb42bd3a --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/mixins/mixins.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true +# typed: true + +module T::Private + module MixesInClassMethods + def included(other) + mods = Abstract::Data.get(self, :class_methods_mixins) + mods.each {|mod| other.extend(mod)} + super + end + end + + module Mixins + def self.declare_mixes_in_class_methods(mixin, class_methods) + if mixin.is_a?(Class) + raise "Classes cannot be used as mixins, and so mixes_in_class_methods cannot be used on a Class." + end + + if Abstract::Data.key?(mixin, :class_methods_mixins) + class_methods = Abstract::Data.get(mixin, :class_methods_mixins) + class_methods + end + + mixin.singleton_class.include(MixesInClassMethods) + Abstract::Data.set(mixin, :class_methods_mixins, class_methods) + end + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/retry.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/retry.rb new file mode 100644 index 0000000000..7b2822d394 --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/retry.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true +# typed: true + +module T::Private::Retry + + # A special singleton used for static analysis of exceptions. + module RETRY + freeze + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/runtime_levels.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/runtime_levels.rb new file mode 100644 index 0000000000..2454b21988 --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/runtime_levels.rb @@ -0,0 +1,62 @@ +# frozen_string_literal: true +# typed: true + +# Used in `sig.checked(level)` to determine when runtime type checking +# is enabled on a method. +module T::Private::RuntimeLevels + LEVELS = [ + # Validate every call in every environment + :always, + # Validate in tests, but not in production + :tests, + # Don't even validate in tests, b/c too expensive, + # or b/c we fully trust the static typing + :never, + # Validate the sig when the file is using the Sorbet Compiler. + # Behaves like :never when interpreted. + :compiled, + ].freeze + + @check_tests = false + @wrapped_tests_with_validation = false + + @has_read_default_checked_level = false + @default_checked_level = :always + + def self.check_tests? + # Assume that this code path means that some `sig.checked(:tests)` + # has been wrapped (or not wrapped) already, which is a trapdoor + # for toggling `@check_tests`. + @wrapped_tests_with_validation = true + + @check_tests + end + + def self.enable_checking_in_tests + if !@check_tests && @wrapped_tests_with_validation + all_checked_tests_sigs = T::Private::Methods.all_checked_tests_sigs + locations = all_checked_tests_sigs.map {|sig| sig.method.source_location.join(':')}.join("\n- ") + raise "Toggle `:tests`-level runtime type checking earlier. " \ + "There are already some methods wrapped with `sig.checked(:tests)`:\n" \ + "- #{locations}" + end + + _toggle_checking_tests(true) + end + + def self.default_checked_level + @has_read_default_checked_level = true + @default_checked_level + end + + def self.default_checked_level=(default_checked_level) + if @has_read_default_checked_level + raise "Set the default checked level earlier. There are already some methods whose sig blocks have evaluated which would not be affected by the new default." + end + @default_checked_level = default_checked_level + end + + def self._toggle_checking_tests(checked) + @check_tests = checked + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/sealed.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/sealed.rb new file mode 100644 index 0000000000..62e19fb088 --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/sealed.rb @@ -0,0 +1,91 @@ +# frozen_string_literal: true +# typed: false + +module T::Private::Sealed + module NoInherit + def inherited(child) + super + this_line = Kernel.caller.find {|line| !line.match(/in `inherited'$/)} + T::Private::Sealed.validate_inheritance(this_line, self, child, 'inherited') + @sorbet_sealed_module_all_subclasses << child + end + + def sealed_subclasses + @sorbet_sealed_module_all_subclasses_set ||= # rubocop:disable Naming/MemoizedInstanceVariableName + begin + require 'set' + Set.new(@sorbet_sealed_module_all_subclasses).freeze + end + end + end + + module NoIncludeExtend + def included(child) + super + this_line = Kernel.caller.find {|line| !line.match(/in `included'$/)} + T::Private::Sealed.validate_inheritance(this_line, self, child, 'included') + @sorbet_sealed_module_all_subclasses << child + end + + def extended(child) + super + this_line = Kernel.caller.find {|line| !line.match(/in `extended'$/)} + T::Private::Sealed.validate_inheritance(this_line, self, child, 'extended') + @sorbet_sealed_module_all_subclasses << child + end + + def sealed_subclasses + # this will freeze the set so that you can never get into a + # state where you use the subclasses list and then something + # else will add to it + @sorbet_sealed_module_all_subclasses_set ||= # rubocop:disable Naming/MemoizedInstanceVariableName + begin + require 'set' + Set.new(@sorbet_sealed_module_all_subclasses).freeze + end + end + end + + def self.declare(mod, decl_file) + if !mod.is_a?(Module) + raise "#{mod} is not a class or module and cannot be declared `sealed!`" + end + if sealed_module?(mod) + raise "#{mod} was already declared `sealed!` and cannot be re-declared `sealed!`" + end + if T::Private::Final.final_module?(mod) + raise "#{mod} was already declared `final!` and cannot be declared `sealed!`" + end + mod.extend(mod.is_a?(Class) ? NoInherit : NoIncludeExtend) + if !decl_file + raise "Couldn't determine declaration file for sealed class." + end + mod.instance_variable_set(:@sorbet_sealed_module_decl_file, decl_file) + mod.instance_variable_set(:@sorbet_sealed_module_all_subclasses, []) + end + + def self.sealed_module?(mod) + mod.instance_variable_defined?(:@sorbet_sealed_module_decl_file) + end + + def self.validate_inheritance(this_line, parent, child, verb) + this_file = this_line&.split(':')&.first + decl_file = parent.instance_variable_get(:@sorbet_sealed_module_decl_file) if sealed_module?(parent) + + if !this_file + raise "Could not use backtrace to determine file for #{verb} child #{child}" + end + if !decl_file + raise "#{parent} does not seem to be a sealed module (#{verb} by #{child})" + end + + if !this_file.start_with?(decl_file) + whitelist = T::Configuration.sealed_violation_whitelist + if !whitelist.nil? && whitelist.any? {|pattern| this_file =~ pattern} + return + end + + raise "#{parent} was declared sealed and can only be #{verb} in #{decl_file}, not #{this_file}" + end + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/types/not_typed.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/types/not_typed.rb new file mode 100644 index 0000000000..57196553b6 --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/types/not_typed.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true +# typed: true + +# A placeholder for when an untyped thing must provide a type. +# Raises an exception if it is ever used for validation. +class T::Private::Types::NotTyped < T::Types::Base + ERROR_MESSAGE = "Validation is being done on a `NotTyped`. Please report this bug at https://github.com/sorbet/sorbet/issues" + + # overrides Base + def name + "" + end + + # overrides Base + def valid?(obj) + raise ERROR_MESSAGE + end + + # overrides Base + private def subtype_of_single?(other) + raise ERROR_MESSAGE + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/types/string_holder.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/types/string_holder.rb new file mode 100644 index 0000000000..b2295f7730 --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/types/string_holder.rb @@ -0,0 +1,26 @@ +# frozen_string_literal: true +# typed: true + +# Holds a string. Useful for showing type aliases in error messages +class T::Private::Types::StringHolder < T::Types::Base + attr_reader :string + + def initialize(string) + @string = string + end + + # overrides Base + def name + string + end + + # overrides Base + def valid?(obj) + false + end + + # overrides Base + private def subtype_of_single?(other) + false + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/types/type_alias.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/types/type_alias.rb new file mode 100644 index 0000000000..de805c9659 --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/types/type_alias.rb @@ -0,0 +1,31 @@ +# frozen_string_literal: true +# typed: true + +module T::Private::Types + # Wraps a proc for a type alias to defer its evaluation. + class TypeAlias < T::Types::Base + + def initialize(callable) + @callable = callable + end + + def aliased_type + @aliased_type ||= T::Utils.coerce(@callable.call) + end + + # overrides Base + def name + aliased_type.name + end + + # overrides Base + def recursively_valid?(obj) + aliased_type.recursively_valid?(obj) + end + + # overrides Base + def valid?(obj) + aliased_type.valid?(obj) + end + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/types/void.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/types/void.rb new file mode 100644 index 0000000000..310fc56abc --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/types/void.rb @@ -0,0 +1,34 @@ +# frozen_string_literal: true +# typed: true + +# A marking class for when methods return void. +# Should never appear in types directly. +class T::Private::Types::Void < T::Types::Base + ERROR_MESSAGE = "Validation is being done on an `Void`. Please report this bug at https://github.com/sorbet/sorbet/issues" + + # The actual return value of `.void` methods. + # + # Uses `module VOID` because this gives it a readable name when someone + # examines it in Pry or with `#inspect` like: + # + # T::Private::Types::Void::VOID + # + module VOID + freeze + end + + # overrides Base + def name + "" + end + + # overrides Base + def valid?(obj) + raise ERROR_MESSAGE + end + + # overrides Base + private def subtype_of_single?(other) + raise ERROR_MESSAGE + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/_props.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/_props.rb new file mode 100644 index 0000000000..fae252aa04 --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/_props.rb @@ -0,0 +1,169 @@ +# frozen_string_literal: true +# typed: true + +# A mixin for defining typed properties (attributes). +# To get serialization methods (to/from JSON-style hashes), add T::Props::Serializable. +# To get a constructor based on these properties, inherit from T::Struct. +module T::Props + extend T::Helpers + + ##### + # CAUTION: This mixin is used in hundreds of classes; we want to keep its surface area as narrow + # as possible and avoid polluting (and possibly conflicting with) the classes that use it. + # + # It currently has *zero* instance methods; let's try to keep it that way. + # For ClassMethods (below), try to add things to T::Props::Decorator instead unless you are sure + # it needs to be exposed here. + ##### + + module ClassMethods + extend T::Sig + extend T::Helpers + + def props + decorator.props + end + def plugins + @plugins ||= [] + end + + def decorator_class + Decorator + end + + def decorator + @decorator ||= decorator_class.new(self) + end + def reload_decorator! + @decorator = decorator_class.new(self) + end + + # Define a new property. See {file:README.md} for some concrete + # examples. + # + # Defining a property defines a method with the same name as the + # property, that returns the current value, and a `prop=` method + # to set its value. Properties will be inherited by subclasses of + # a document class. + # + # @param name [Symbol] The name of this property + # @param cls [Class,T::Types::Base] The type of this + # property. If the type is itself a `Document` subclass, this + # property will be recursively serialized/deserialized. + # @param rules [Hash] Options to control this property's behavior. + # @option rules [T::Boolean,Symbol] :optional If `true`, this property + # is never required to be set before an instance is serialized. + # If `:on_load` (default), when this property is missing or nil, a + # new model cannot be saved, and an existing model can only be + # saved if the property was already missing when it was loaded. + # If `false`, when the property is missing/nil after deserialization, it + # will be set to the default value (as defined by the `default` or + # `factory` option) or will raise if they are not present. + # Deprecated: For `Model`s, if `:optional` is set to the special value + # `:existing`, the property can be saved as nil even if it was + # deserialized with a non-nil value. (Deprecated because there should + # never be a need for this behavior; the new behavior of non-optional + # properties should be sufficient.) + # @option rules [Array] :enum An array of legal values; The + # property is required to take on one of those values. + # @option rules [T::Boolean] :dont_store If true, this property will + # not be saved on the hash resulting from + # {T::Props::Serializable#serialize} + # @option rules [Object] :ifunset A value to be returned if this + # property is requested but has never been set (is set to + # `nil`). It is applied at property-access time, and never saved + # back onto the object or into the database. + # + # ``:ifunset`` is considered **DEPRECATED** and should not be used + # in new code, in favor of just setting a default value. + # @option rules [Model, Symbol, Proc] :foreign A model class that this + # property is a reference to. Passing `:foreign` will define a + # `:"#{name}_"` method, that will load and return the + # corresponding foreign model. + # + # A symbol can be passed to avoid load-order dependencies; It + # will be lazily resolved relative to the enclosing module of the + # defining class. + # + # A callable (proc or method) can be passed to dynamically specify the + # foreign model. This will be passed the object instance so that other + # properties of the object can be used to determine the relevant model + # class. It should return a string/symbol class name or the foreign model + # class directly. + # + # @option rules [Object] :default A default value that will be set + # by `#initialize` if none is provided in the initialization + # hash. This will not affect objects loaded by {.from_hash}. + # @option rules [Proc] :factory A `Proc` that will be called to + # generate an initial value for this prop on `#initialize`, if + # none is provided. + # @option rules [T::Boolean] :immutable If true, this prop cannot be + # modified after an instance is created or loaded from a hash. + # @option rules [T::Boolean] :override It is an error to redeclare a + # `prop` that has already been declared (including on a + # superclass), unless `:override` is set to `true`. + # @option rules [Symbol, Array] :redaction A redaction directive that may + # be passed to Chalk::Tools::RedactionUtils.redact_with_directive to + # sanitize this parameter for display. Will define a + # `:"#{name}_redacted"` method, which will return the value in sanitized + # form. + # + # @return [void] + sig {params(name: Symbol, cls: T.untyped, rules: T.untyped).void} + def prop(name, cls, rules={}) + cls = T::Utils.coerce(cls) if !cls.is_a?(Module) + decorator.prop_defined(name, cls, rules) + end + + # Validates the value of the specified prop. This method allows the caller to + # validate a value for a prop without having to set the data on the instance. + # Throws if invalid. + # + # @param prop [Symbol] + # @param val [Object] + # @return [void] + def validate_prop_value(prop, val) + decorator.validate_prop_value(prop, val) + end + + # Needs to be documented + def plugin(mod) + decorator.plugin(mod) + end + + # Shorthand helper to define a `prop` with `immutable => true` + sig {params(name: Symbol, cls_or_args: T.untyped, args: T::Hash[Symbol, T.untyped]).void} + def const(name, cls_or_args, args={}) + if (cls_or_args.is_a?(Hash) && cls_or_args.key?(:immutable)) || args.key?(:immutable) + Kernel.raise ArgumentError.new("Cannot pass 'immutable' argument when using 'const' keyword to define a prop") + end + + if cls_or_args.is_a?(Hash) + self.prop(name, cls_or_args.merge(immutable: true)) + else + self.prop(name, cls_or_args, args.merge(immutable: true)) + end + end + + def included(child) + decorator.model_inherited(child) + super + end + + def prepended(child) + decorator.model_inherited(child) + super + end + + def extended(child) + decorator.model_inherited(child.singleton_class) + super + end + + def inherited(child) + decorator.model_inherited(child) + super + end + end + mixes_in_class_methods(ClassMethods) +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/constructor.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/constructor.rb new file mode 100644 index 0000000000..570c068ac4 --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/constructor.rb @@ -0,0 +1,40 @@ +# frozen_string_literal: true +# typed: false + +module T::Props::Constructor + include T::Props::WeakConstructor +end + +module T::Props::Constructor::DecoratorMethods + extend T::Sig + + # Set values for all props that have no defaults. Override what `WeakConstructor` + # does in order to raise errors on nils instead of ignoring them. + # + # @return [Integer] A count of props that we successfully initialized (which + # we'll use to check for any unrecognized input.) + # + # checked(:never) - O(runtime object construction) + sig {params(instance: T::Props::Constructor, hash: T::Hash[Symbol, T.untyped]).returns(Integer).checked(:never)} + def construct_props_without_defaults(instance, hash) + # Use `each_pair` rather than `count` because, as of Ruby 2.6, the latter delegates to Enumerator + # and therefore allocates for each entry. + result = 0 + props_without_defaults&.each_pair do |p, setter_proc| + begin + val = hash[p] + instance.instance_exec(val, &setter_proc) + if val || hash.key?(p) + result += 1 + end + rescue TypeError, T::Props::InvalidValueError + if !hash.key?(p) + raise ArgumentError.new("Missing required prop `#{p}` for class `#{instance.class.name}`") + else + raise + end + end + end + result + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/custom_type.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/custom_type.rb new file mode 100644 index 0000000000..0df6a0d863 --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/custom_type.rb @@ -0,0 +1,108 @@ +# frozen_string_literal: true +# typed: strict + +module T::Props + module CustomType + extend T::Sig + extend T::Helpers + + abstract! + + include Kernel # for `is_a?` + + # Alias for backwards compatibility + sig(:final) do + params( + value: BasicObject, + ) + .returns(T::Boolean) + .checked(:never) + end + def instance?(value) + self.===(value) + end + + # Alias for backwards compatibility + sig(:final) do + params( + value: BasicObject, + ) + .returns(T::Boolean) + .checked(:never) + end + def valid?(value) + instance?(value) + end + + # Given an instance of this type, serialize that into a scalar type + # supported by T::Props. + # + # @param [Object] instance + # @return An instance of one of T::Configuration.scalar_types + sig {abstract.params(instance: T.untyped).returns(T.untyped).checked(:never)} + def serialize(instance); end + + # Given the serialized form of your type, this returns an instance + # of that custom type representing that value. + # + # @param scalar One of T::Configuration.scalar_types + # @return Object + sig {abstract.params(scalar: T.untyped).returns(T.untyped).checked(:never)} + def deserialize(scalar); end + + sig {override.params(_base: Module).void} + def self.included(_base) + super + + raise 'Please use "extend", not "include" to attach this module' + end + + sig(:final) {params(val: Object).returns(T::Boolean).checked(:never)} + def self.scalar_type?(val) + # We don't need to check for val's included modules in + # T::Configuration.scalar_types, because T::Configuration.scalar_types + # are all classes. + klass = T.let(val.class, T.nilable(Class)) + until klass.nil? + return true if T::Configuration.scalar_types.include?(klass.to_s) + klass = klass.superclass + end + false + end + + # We allow custom types to serialize to Arrays, so that we can + # implement set-like fields that store a unique-array, but forbid + # hashes; Custom hash types should be implemented via an emebdded + # T::Struct (or a subclass like Chalk::ODM::Document) or via T. + sig(:final) {params(val: Object).returns(T::Boolean).checked(:never)} + def self.valid_serialization?(val) + case val + when Array + val.each do |v| + return false unless scalar_type?(v) + end + + true + else + scalar_type?(val) + end + end + + sig(:final) do + params(instance: Object) + .returns(T.untyped) + .checked(:never) + end + def self.checked_serialize(instance) + val = T.cast(instance.class, T::Props::CustomType).serialize(instance) + unless valid_serialization?(val) + msg = "#{instance.class} did not serialize to a valid scalar type. It became a: #{val.class}" + if val.is_a?(Hash) + msg += "\nIf you want to store a structured Hash, consider using a T::Struct as your type." + end + raise TypeError.new(msg) + end + val + end + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/decorator.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/decorator.rb new file mode 100644 index 0000000000..679a32584b --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/decorator.rb @@ -0,0 +1,669 @@ +# frozen_string_literal: true +# typed: strict + +# NB: This is not actually a decorator. It's just named that way for consistency +# with DocumentDecorator and ModelDecorator (which both seem to have been written +# with an incorrect understanding of the decorator pattern). These "decorators" +# should really just be static methods on private modules (we'd also want/need to +# replace decorator overrides in plugins with class methods that expose the necessary +# functionality). +class T::Props::Decorator + extend T::Sig + + Rules = T.type_alias {T::Hash[Symbol, T.untyped]} + DecoratedInstance = T.type_alias {Object} # Would be T::Props, but that produces circular reference errors in some circumstances + PropType = T.type_alias {T::Types::Base} + PropTypeOrClass = T.type_alias {T.any(PropType, Module)} + + class NoRulesError < StandardError; end + + EMPTY_PROPS = T.let({}.freeze, T::Hash[Symbol, Rules]) + private_constant :EMPTY_PROPS + + sig {params(klass: T.untyped).void.checked(:never)} + def initialize(klass) + @class = T.let(klass, T.all(Module, T::Props::ClassMethods)) + @class.plugins.each do |mod| + T::Props::Plugin::Private.apply_decorator_methods(mod, self) + end + @props = T.let(EMPTY_PROPS, T::Hash[Symbol, Rules]) + end + + # checked(:never) - O(prop accesses) + sig {returns(T::Hash[Symbol, Rules]).checked(:never)} + attr_reader :props + + sig {returns(T::Array[Symbol])} + def all_props + props.keys + end + + # checked(:never) - O(prop accesses) + sig {params(prop: T.any(Symbol, String)).returns(Rules).checked(:never)} + def prop_rules(prop) + props[prop.to_sym] || raise("No such prop: #{prop.inspect}") + end + + # checked(:never) - Rules hash is expensive to check + sig {params(prop: Symbol, rules: Rules).void.checked(:never)} + def add_prop_definition(prop, rules) + override = rules.delete(:override) + + if props.include?(prop) && !override + raise ArgumentError.new("Attempted to redefine prop #{prop.inspect} that's already defined without specifying :override => true: #{prop_rules(prop)}") + elsif !props.include?(prop) && override + raise ArgumentError.new("Attempted to override a prop #{prop.inspect} that doesn't already exist") + end + + @props = @props.merge(prop => rules.freeze).freeze + end + + # Heads up! + # + # There are already too many ad-hoc options on the prop DSL. + # + # We have already done a lot of work to remove unnecessary and confusing + # options. If you're considering adding a new rule key, please come chat with + # the Sorbet team first, as we'd really like to learn more about how to best + # solve the problem you're encountering. + VALID_RULE_KEYS = T.let(%i[ + enum + foreign + ifunset + immutable + override + redaction + sensitivity + without_accessors + clobber_existing_method! + extra + setter_validate + _tnilable + ].map {|k| [k, true]}.to_h.freeze, T::Hash[Symbol, T::Boolean]) + private_constant :VALID_RULE_KEYS + + sig {params(key: Symbol).returns(T::Boolean).checked(:never)} + def valid_rule_key?(key) + !!VALID_RULE_KEYS[key] + end + + # checked(:never) - O(prop accesses) + sig {returns(T.all(Module, T::Props::ClassMethods)).checked(:never)} + def decorated_class + @class + end + + # Accessors + + # Use this to validate that a value will validate for a given prop. Useful for knowing whether a value can be set on a model without setting it. + # + # checked(:never) - potentially O(prop accesses) depending on usage pattern + sig {params(prop: Symbol, val: T.untyped).void.checked(:never)} + def validate_prop_value(prop, val) + # We call `setter_proc` here without binding to an instance, so it'll run + # `instance_variable_set` if validation passes, but nothing will care. + # We only care about the validation. + prop_rules(prop).fetch(:setter_proc).call(val) + end + + # For performance, don't use named params here. + # Passing in rules here is purely a performance optimization. + # Unlike the other methods that take rules, this one calls prop_rules for + # the default, which raises if the prop doesn't exist (this maintains + # preexisting behavior). + # + # Note this path is NOT used by generated setters on instances, + # which are defined using `setter_proc` directly. + # + # checked(:never) - O(prop accesses) + sig do + params( + instance: DecoratedInstance, + prop: Symbol, + val: T.untyped, + rules: Rules + ) + .void + .checked(:never) + end + def prop_set(instance, prop, val, rules=prop_rules(prop)) + instance.instance_exec(val, &rules.fetch(:setter_proc)) + end + alias_method :set, :prop_set + + # Only Models have any custom get logic but we need to call this on + # non-Models since we don't know at code gen time what we have. + sig do + params( + instance: DecoratedInstance, + prop: Symbol, + value: T.untyped + ) + .returns(T.untyped) + .checked(:never) + end + def prop_get_logic(instance, prop, value) + value + end + + # For performance, don't use named params here. + # Passing in rules here is purely a performance optimization. + # + # Note this path is NOT used by generated getters on instances, + # unless `ifunset` is used on the prop, or `prop_get` is overridden. + # + # checked(:never) - O(prop accesses) + sig do + params( + instance: DecoratedInstance, + prop: T.any(String, Symbol), + rules: Rules + ) + .returns(T.untyped) + .checked(:never) + end + def prop_get(instance, prop, rules=prop_rules(prop)) + val = instance.instance_variable_get(rules[:accessor_key]) if instance.instance_variable_defined?(rules[:accessor_key]) + if !val.nil? + val + elsif (d = rules[:ifunset]) + T::Props::Utils.deep_clone_object(d) + else + nil + end + end + + sig do + params( + instance: DecoratedInstance, + prop: T.any(String, Symbol), + rules: Rules + ) + .returns(T.untyped) + .checked(:never) + end + def prop_get_if_set(instance, prop, rules=prop_rules(prop)) + instance.instance_variable_get(rules[:accessor_key]) if instance.instance_variable_defined?(rules[:accessor_key]) + end + alias_method :get, :prop_get_if_set # Alias for backwards compatibility + + # checked(:never) - O(prop accesses) + sig do + params( + instance: DecoratedInstance, + prop: Symbol, + foreign_class: Module, + rules: Rules, + opts: T::Hash[Symbol, T.untyped], + ) + .returns(T.untyped) + .checked(:never) + end + def foreign_prop_get(instance, prop, foreign_class, rules=prop_rules(prop), opts={}) + return if !(value = prop_get(instance, prop, rules)) + T.unsafe(foreign_class).load(value, {}, opts) + end + + # TODO: we should really be checking all the methods on `cls`, not just Object + BANNED_METHOD_NAMES = T.let(Object.instance_methods.each_with_object({}) {|x, acc| acc[x] = true}.freeze, T::Hash[Symbol, TrueClass]) + + # checked(:never) - Rules hash is expensive to check + sig do + params( + name: Symbol, + cls: Module, + rules: Rules, + type: PropTypeOrClass + ) + .void + .checked(:never) + end + def prop_validate_definition!(name, cls, rules, type) + validate_prop_name(name) + + if rules.key?(:pii) + raise ArgumentError.new("The 'pii:' option for props has been renamed " \ + "to 'sensitivity:' (in prop #{@class.name}.#{name})") + end + + if rules.keys.any? {|k| !valid_rule_key?(k)} + raise ArgumentError.new("At least one invalid prop arg supplied in #{self}: #{rules.keys.inspect}") + end + + if !rules[:clobber_existing_method!] && !rules[:without_accessors] && BANNED_METHOD_NAMES.include?(name.to_sym) + raise ArgumentError.new( + "#{name} can't be used as a prop in #{@class} because a method with " \ + "that name already exists (defined by #{@class.instance_method(name).owner} " \ + "at #{@class.instance_method(name).source_location || ''}). " \ + "(If using this name is unavoidable, try `without_accessors: true`.)" + ) + end + + extra = rules[:extra] + if !extra.nil? && !extra.is_a?(Hash) + raise ArgumentError.new("Extra metadata must be a Hash in prop #{@class.name}.#{name}") + end + + nil + end + + SAFE_NAME = T.let(/\A[A-Za-z_][A-Za-z0-9_-]*\z/.freeze, Regexp) + + # Used to validate both prop names and serialized forms + sig {params(name: T.any(Symbol, String)).void} + private def validate_prop_name(name) + if !name.match?(SAFE_NAME) + raise ArgumentError.new("Invalid prop name in #{@class.name}: #{name}") + end + end + + # This converts the type from a T::Type to a regular old ruby class. + sig {params(type: T::Types::Base).returns(Module)} + private def convert_type_to_class(type) + case type + when T::Types::TypedArray, T::Types::FixedArray + Array + when T::Types::TypedHash, T::Types::FixedHash + Hash + when T::Types::TypedSet + Set + when T::Types::Union + # The below unwraps our T.nilable types for T::Props if we can. + # This lets us do things like specify: const T.nilable(String), foreign: Opus::DB::Model::Merchant + non_nil_type = T::Utils.unwrap_nilable(type) + if non_nil_type + convert_type_to_class(non_nil_type) + else + Object + end + when T::Types::Simple + type.raw_type + else + # This isn't allowed unless whitelisted_for_underspecification is + # true, due to the check in prop_validate_definition + Object + end + end + + # Returns `true` when the type of the prop is nilable, or the field is typed + # as `T.untyped`, a `:default` is present in the rules hash, and its value is + # `nil`. The latter case is a workaround for explicitly not supporting the use + # of `T.nilable(T.untyped)`. + # + # checked(:never) - Rules hash is expensive to check + sig do + params( + cls: PropTypeOrClass, + rules: Rules, + ) + .void + .checked(:never) + end + private def prop_nilable?(cls, rules) + T::Utils::Nilable.is_union_with_nilclass(cls) || (cls == T.untyped && rules.key?(:default) && rules[:default].nil?) + end + + # checked(:never) - Rules hash is expensive to check + sig do + params( + name: T.any(Symbol, String), + cls: PropTypeOrClass, + rules: Rules, + ) + .void + .checked(:never) + end + def prop_defined(name, cls, rules={}) + cls = T::Utils.resolve_alias(cls) + + if prop_nilable?(cls, rules) + # :_tnilable is introduced internally for performance purpose so that clients do not need to call + # T::Utils::Nilable.is_tnilable(cls) again. + # It is strictly internal: clients should always use T::Props::Utils.required_prop?() or + # T::Props::Utils.optional_prop?() for checking whether a field is required or optional. + rules[:_tnilable] = true + end + + name = name.to_sym + type = cls + if !cls.is_a?(Module) + cls = convert_type_to_class(cls) + end + type_object = smart_coerce(type, enum: rules[:enum]) + + prop_validate_definition!(name, cls, rules, type_object) + + # Retrive the possible underlying object with T.nilable. + type = T::Utils::Nilable.get_underlying_type(type) + + sensitivity_and_pii = {sensitivity: rules[:sensitivity]} + normalize = T::Configuration.normalize_sensitivity_and_pii_handler + if normalize + sensitivity_and_pii = normalize.call(sensitivity_and_pii) + + # We check for Class so this is only applied on concrete + # documents/models; We allow mixins containing props to not + # specify their PII nature, as long as every class into which they + # are ultimately included does. + # + if sensitivity_and_pii[:pii] && @class.is_a?(Class) && !T.unsafe(@class).contains_pii? + raise ArgumentError.new( + 'Cannot include a pii prop in a class that declares `contains_no_pii`' + ) + end + end + + rules = rules.merge( + # TODO: The type of this element is confusing. We should refactor so that + # it can be always `type_object` (a PropType) or always `cls` (a Module) + type: type, + type_object: type_object, + accessor_key: "@#{name}".to_sym, + sensitivity: sensitivity_and_pii[:sensitivity], + pii: sensitivity_and_pii[:pii], + # extra arbitrary metadata attached by the code defining this property + extra: rules[:extra]&.freeze, + ) + + validate_not_missing_sensitivity(name, rules) + + # for backcompat (the `:array` key is deprecated but because the name is + # so generic it's really hard to be sure it's not being relied on anymore) + if type.is_a?(T::Types::TypedArray) + inner = T::Utils::Nilable.get_underlying_type(type.type) + if inner.is_a?(Module) + rules[:array] = inner + end + end + + rules[:setter_proc] = T::Props::Private::SetterFactory.build_setter_proc(@class, name, rules).freeze + + add_prop_definition(name, rules) + + # NB: using `without_accessors` doesn't make much sense unless you also define some other way to + # get at the property (e.g., Chalk::ODM::Document exposes `get` and `set`). + define_getter_and_setter(name, rules) unless rules[:without_accessors] + + handle_foreign_option(name, cls, rules, rules[:foreign]) if rules[:foreign] + handle_redaction_option(name, rules[:redaction]) if rules[:redaction] + end + + # checked(:never) - Rules hash is expensive to check + sig {params(name: Symbol, rules: Rules).void.checked(:never)} + private def define_getter_and_setter(name, rules) + T::Configuration.without_ruby_warnings do + if !rules[:immutable] + if method(:prop_set).owner != T::Props::Decorator + @class.send(:define_method, "#{name}=") do |val| + T.unsafe(self.class).decorator.prop_set(self, name, val, rules) + end + else + # Fast path (~4x faster as of Ruby 2.6) + @class.send(:define_method, "#{name}=", &rules.fetch(:setter_proc)) + end + end + + if method(:prop_get).owner != T::Props::Decorator || rules.key?(:ifunset) + @class.send(:define_method, name) do + T.unsafe(self.class).decorator.prop_get(self, name, rules) + end + else + # Fast path (~30x faster as of Ruby 2.6) + @class.send(:attr_reader, name) # send is used because `attr_reader` is private in 2.4 + end + end + end + + sig do + params(type: PropTypeOrClass, enum: T.untyped) + .returns(T::Types::Base) + end + private def smart_coerce(type, enum:) + # Backwards compatibility for pre-T::Types style + type = T::Utils.coerce(type) + if enum.nil? + type + else + nonnil_type = T::Utils.unwrap_nilable(type) + if nonnil_type + T.unsafe(T.nilable(T.all(nonnil_type, T.deprecated_enum(enum)))) + else + T.unsafe(T.all(T.unsafe(type), T.deprecated_enum(enum))) + end + end + end + + # checked(:never) - Rules hash is expensive to check + sig {params(prop_name: Symbol, rules: Rules).void.checked(:never)} + private def validate_not_missing_sensitivity(prop_name, rules) + if rules[:sensitivity].nil? + if rules[:redaction] + T::Configuration.hard_assert_handler( + "#{@class}##{prop_name} has a 'redaction:' annotation but no " \ + "'sensitivity:' annotation. This is probably wrong, because if a " \ + "prop needs redaction then it is probably sensitive. Add a " \ + "sensitivity annotation like 'sensitivity: Opus::Sensitivity::PII." \ + "whatever', or explicitly override this check with 'sensitivity: []'." + ) + end + # TODO(PRIVACYENG-982) Ideally we'd also check for 'password' and possibly + # other terms, but this interacts badly with ProtoDefinedDocument because + # the proto syntax currently can't declare "sensitivity: []" + if /\bsecret\b/.match?(prop_name) + T::Configuration.hard_assert_handler( + "#{@class}##{prop_name} has the word 'secret' in its name, but no " \ + "'sensitivity:' annotation. This is probably wrong, because if a " \ + "prop is named 'secret' then it is probably sensitive. Add a " \ + "sensitivity annotation like 'sensitivity: Opus::Sensitivity::NonPII." \ + "security_token', or explicitly override this check with " \ + "'sensitivity: []'." + ) + end + end + end + + # Create `#{prop_name}_redacted` method + sig do + params( + prop_name: Symbol, + redaction: T.untyped, + ) + .void + end + private def handle_redaction_option(prop_name, redaction) + redacted_method = "#{prop_name}_redacted" + + @class.send(:define_method, redacted_method) do + value = self.public_send(prop_name) + handler = T::Configuration.redaction_handler + if !handler + raise "Using `redaction:` on a prop requires specifying `T::Configuration.redaction_handler`" + end + handler.call(value, redaction) + end + end + + sig do + params( + option_sym: Symbol, + foreign: T.untyped, + valid_type_msg: String, + ) + .void + end + private def validate_foreign_option(option_sym, foreign, valid_type_msg:) + if foreign.is_a?(Symbol) || foreign.is_a?(String) + raise ArgumentError.new( + "Using a symbol/string for `#{option_sym}` is no longer supported. Instead, use a Proc " \ + "that returns the class, e.g., foreign: -> {Foo}" + ) + end + + if !foreign.is_a?(Proc) && !foreign.is_a?(Array) && !foreign.respond_to?(:load) + raise ArgumentError.new("The `#{option_sym}` option must be #{valid_type_msg}") + end + end + + # checked(:never) - Rules hash is expensive to check + sig do + params( + prop_name: T.any(String, Symbol), + rules: Rules, + foreign: T.untyped, + ) + .void + .checked(:never) + end + private def define_foreign_method(prop_name, rules, foreign) + fk_method = "#{prop_name}_" + + # n.b. there's no clear reason *not* to allow additional options + # here, but we're baking in `allow_direct_mutation` since we + # *haven't* allowed additional options in the past and want to + # default to keeping this interface narrow. + @class.send(:define_method, fk_method) do |allow_direct_mutation: nil| + foreign = T.let(foreign, T.untyped) + if foreign.is_a?(Proc) + resolved_foreign = foreign.call + if !resolved_foreign.respond_to?(:load) + raise ArgumentError.new( + "The `foreign` proc for `#{prop_name}` must return a model class. " \ + "Got `#{resolved_foreign.inspect}` instead." + ) + end + # `foreign` is part of the closure state, so this will persist to future invocations + # of the method, optimizing it so this only runs on the first invocation. + foreign = resolved_foreign + end + opts = if allow_direct_mutation.nil? + {} + else + {allow_direct_mutation: allow_direct_mutation} + end + + T.unsafe(self.class).decorator.foreign_prop_get(self, prop_name, foreign, rules, opts) + end + + force_fk_method = "#{fk_method}!" + @class.send(:define_method, force_fk_method) do |allow_direct_mutation: nil| + loaded_foreign = send(fk_method, allow_direct_mutation: allow_direct_mutation) + if !loaded_foreign + T::Configuration.hard_assert_handler( + 'Failed to load foreign model', + storytime: {method: force_fk_method, class: self.class} + ) + end + loaded_foreign + end + end + + # checked(:never) - Rules hash is expensive to check + sig do + params( + prop_name: Symbol, + prop_cls: Module, + rules: Rules, + foreign: T.untyped, + ) + .void + .checked(:never) + end + private def handle_foreign_option(prop_name, prop_cls, rules, foreign) + validate_foreign_option( + :foreign, foreign, valid_type_msg: "a model class or a Proc that returns one" + ) + + if prop_cls != String + raise ArgumentError.new("`foreign` can only be used with a prop type of String") + end + + if foreign.is_a?(Array) + # We don't support arrays with `foreign` because it's hard to both preserve ordering and + # keep them from being lurky performance hits by issuing a bunch of un-batched DB queries. + # We could potentially address that by porting over something like AmbiguousIDLoader. + raise ArgumentError.new( + "Using an array for `foreign` is no longer supported. Instead, please use a union type of " \ + "token types for the prop type, e.g., T.any(Opus::Autogen::Tokens::FooModelToken, Opus::Autogen::Tokens::BarModelToken)" + ) + end + + unless foreign.is_a?(Proc) + T::Configuration.soft_assert_handler(<<~MESSAGE, storytime: {prop: prop_name, value: foreign}, notify: 'jerry') + Please use a Proc that returns a model class instead of the model class itself as the argument to `foreign`. In other words: + + instead of `prop :foo, String, foreign: FooModel` + use `prop :foo, String, foreign: -> {FooModel}` + + MESSAGE + end + + define_foreign_method(prop_name, rules, foreign) + end + + # TODO: rename this to props_inherited + # + # This gets called when a module or class that extends T::Props gets included, extended, + # prepended, or inherited. + sig {params(child: Module).void.checked(:never)} + def model_inherited(child) + child.extend(T::Props::ClassMethods) + child = T.cast(child, T.all(Module, T::Props::ClassMethods)) + + child.plugins.concat(decorated_class.plugins) + decorated_class.plugins.each do |mod| + # NB: apply_class_methods must not be an instance method on the decorator itself, + # otherwise we'd have to call child.decorator here, which would create the decorator + # before any `decorator_class` override has a chance to take effect (see the comment below). + T::Props::Plugin::Private.apply_class_methods(mod, child) + end + + props.each do |name, rules| + copied_rules = rules.dup + # NB: Calling `child.decorator` here is a timb bomb that's going to give someone a really bad + # time. Any class that defines props and also overrides the `decorator_class` method is going + # to reach this line before its override take effect, turning it into a no-op. + child.decorator.add_prop_definition(name, copied_rules) + + # It's a bit tricky to support `prop_get` hooks added by plugins without + # sacrificing the `attr_reader` fast path or clobbering customized getters + # defined manually on a child. + # + # To make this work, we _do_ clobber getters defined on the child, but only if: + # (a) it's needed in order to support a `prop_get` hook, and + # (b) it's safe because the getter was defined by this file. + # + unless rules[:without_accessors] + if clobber_getter?(child, name) + child.send(:define_method, name) do + T.unsafe(self.class).decorator.prop_get(self, name, rules) + end + end + + if !rules[:immutable] && clobber_setter?(child, name) + child.send(:define_method, "#{name}=") do |val| + T.unsafe(self.class).decorator.prop_set(self, name, val, rules) + end + end + end + end + end + + sig {params(child: T.all(Module, T::Props::ClassMethods), prop: Symbol).returns(T::Boolean).checked(:never)} + private def clobber_getter?(child, prop) + !!(child.decorator.method(:prop_get).owner != method(:prop_get).owner && + child.instance_method(prop).source_location&.first == __FILE__) + end + + sig {params(child: T.all(Module, T::Props::ClassMethods), prop: Symbol).returns(T::Boolean).checked(:never)} + private def clobber_setter?(child, prop) + !!(child.decorator.method(:prop_set).owner != method(:prop_set).owner && + child.instance_method("#{prop}=").source_location&.first == __FILE__) + end + + sig {params(mod: Module).void.checked(:never)} + def plugin(mod) + decorated_class.plugins << mod + T::Props::Plugin::Private.apply_class_methods(mod, decorated_class) + T::Props::Plugin::Private.apply_decorator_methods(mod, self) + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/errors.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/errors.rb new file mode 100644 index 0000000000..6977f20471 --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/errors.rb @@ -0,0 +1,8 @@ +# frozen_string_literal: true +# typed: strict + +module T::Props + class Error < StandardError; end + class InvalidValueError < Error; end + class ImmutableProp < Error; end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/generated_code_validation.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/generated_code_validation.rb new file mode 100644 index 0000000000..91f256799d --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/generated_code_validation.rb @@ -0,0 +1,277 @@ +# frozen_string_literal: true +# typed: true + +module T::Props + # Helper to validate generated code, to mitigate security concerns around + # `class_eval`. Not called by default; the expectation is this will be used + # in a test iterating over all T::Props::Serializable subclasses. + # + # We validate the exact expected structure of the generated methods as far + # as we can, and then where cloning produces an arbitrarily nested structure, + # we just validate a lack of side effects. + module GeneratedCodeValidation + extend Private::Parse + + class ValidationError < RuntimeError; end + + def self.validate_deserialize(source) + parsed = parse(source) + + # def %(hash) + # ... + # end + assert_equal(:def, parsed.type) + name, args, body = parsed.children + assert_equal(:__t_props_generated_deserialize, name) + assert_equal(s(:args, s(:arg, :hash)), args) + + assert_equal(:begin, body.type) + init, *prop_clauses, ret = body.children + + # found = % + # ... + # found + assert_equal(:lvasgn, init.type) + init_name, init_val = init.children + assert_equal(:found, init_name) + assert_equal(:int, init_val.type) + assert_equal(s(:lvar, :found), ret) + + prop_clauses.each_with_index do |clause, i| + if i.even? + validate_deserialize_hash_read(clause) + else + validate_deserialize_ivar_set(clause) + end + end + end + + def self.validate_serialize(source) + parsed = parse(source) + + # def %(strict) + # ... + # end + assert_equal(:def, parsed.type) + name, args, body = parsed.children + assert_equal(:__t_props_generated_serialize, name) + assert_equal(s(:args, s(:arg, :strict)), args) + + assert_equal(:begin, body.type) + init, *prop_clauses, ret = body.children + + # h = {} + # ... + # h + assert_equal(s(:lvasgn, :h, s(:hash)), init) + assert_equal(s(:lvar, :h), ret) + + prop_clauses.each do |clause| + validate_serialize_clause(clause) + end + end + + private_class_method def self.validate_serialize_clause(clause) + assert_equal(:if, clause.type) + condition, if_body, else_body = clause.children + + # if @%.nil? + assert_equal(:send, condition.type) + receiver, method = condition.children + assert_equal(:ivar, receiver.type) + assert_equal(:nil?, method) + + unless if_body.nil? + # required_prop_missing_from_serialize(%) if strict + assert_equal(:if, if_body.type) + if_strict_condition, if_strict_body, if_strict_else = if_body.children + assert_equal(s(:lvar, :strict), if_strict_condition) + assert_equal(:send, if_strict_body.type) + on_strict_receiver, on_strict_method, on_strict_arg = if_strict_body.children + assert_equal(nil, on_strict_receiver) + assert_equal(:required_prop_missing_from_serialize, on_strict_method) + assert_equal(:sym, on_strict_arg.type) + assert_equal(nil, if_strict_else) + end + + # h[%] = ... + assert_equal(:send, else_body.type) + receiver, method, h_key, h_val = else_body.children + assert_equal(s(:lvar, :h), receiver) + assert_equal(:[]=, method) + assert_equal(:str, h_key.type) + + validate_lack_of_side_effects(h_val, whitelisted_methods_for_serialize) + end + + private_class_method def self.validate_deserialize_hash_read(clause) + # val = hash[%s] + + assert_equal(:lvasgn, clause.type) + name, val = clause.children + assert_equal(:val, name) + assert_equal(:send, val.type) + receiver, method, arg = val.children + assert_equal(s(:lvar, :hash), receiver) + assert_equal(:[], method) + assert_equal(:str, arg.type) + end + + private_class_method def self.validate_deserialize_ivar_set(clause) + # %s = if val.nil? + # found -= 1 unless hash.key?(%s) + # %s + # else + # %s + # end + + assert_equal(:ivasgn, clause.type) + ivar_name, deser_val = clause.children + unless ivar_name.is_a?(Symbol) + raise ValidationError.new("Unexpected ivar: #{ivar_name}") + end + + assert_equal(:if, deser_val.type) + condition, if_body, else_body = deser_val.children + assert_equal(s(:send, s(:lvar, :val), :nil?), condition) + + assert_equal(:begin, if_body.type) + update_found, handle_nil = if_body.children + assert_equal(:if, update_found.type) + found_condition, found_if_body, found_else_body = update_found.children + assert_equal(:send, found_condition.type) + receiver, method, arg = found_condition.children + assert_equal(s(:lvar, :hash), receiver) + assert_equal(:key?, method) + assert_equal(:str, arg.type) + assert_equal(nil, found_if_body) + assert_equal(s(:op_asgn, s(:lvasgn, :found), :-, s(:int, 1)), found_else_body) + + validate_deserialize_handle_nil(handle_nil) + + if else_body.type == :kwbegin + rescue_expression, = else_body.children + assert_equal(:rescue, rescue_expression.type) + + try, rescue_body = rescue_expression.children + validate_lack_of_side_effects(try, whitelisted_methods_for_deserialize) + + assert_equal(:resbody, rescue_body.type) + exceptions, assignment, handler = rescue_body.children + assert_equal(:array, exceptions.type) + exceptions.children.each {|c| assert_equal(:const, c.type)} + assert_equal(:lvasgn, assignment.type) + assert_equal([:e], assignment.children) + + deserialization_error, val_return = handler.children + + assert_equal(:send, deserialization_error.type) + receiver, method, *args = deserialization_error.children + assert_equal(nil, receiver) + assert_equal(:raise_deserialization_error, method) + args.each {|a| validate_lack_of_side_effects(a, whitelisted_methods_for_deserialize)} + + validate_lack_of_side_effects(val_return, whitelisted_methods_for_deserialize) + else + validate_lack_of_side_effects(else_body, whitelisted_methods_for_deserialize) + end + end + + private_class_method def self.validate_deserialize_handle_nil(node) + case node.type + when :hash, :array, :str, :sym, :int, :float, :true, :false, :nil, :const # rubocop:disable Lint/BooleanSymbol + # Primitives and constants are safe + when :send + receiver, method, arg = node.children + if receiver.nil? + # required_prop_missing_from_deserialize(%) + assert_equal(:required_prop_missing_from_deserialize, method) + assert_equal(:sym, arg.type) + elsif receiver == self_class_decorator + # self.class.decorator.raise_nil_deserialize_error(%) + assert_equal(:raise_nil_deserialize_error, method) + assert_equal(:str, arg.type) + elsif method == :default + # self.class.decorator.props_with_defaults.fetch(%).default + assert_equal(:send, receiver.type) + inner_receiver, inner_method, inner_arg = receiver.children + assert_equal( + s(:send, self_class_decorator, :props_with_defaults), + inner_receiver, + ) + assert_equal(:fetch, inner_method) + assert_equal(:sym, inner_arg.type) + else + raise ValidationError.new("Unexpected receiver in nil handler: #{node.inspect}") + end + else + raise ValidationError.new("Unexpected nil handler: #{node.inspect}") + end + end + + private_class_method def self.self_class_decorator + @self_class_decorator ||= s(:send, s(:send, s(:self), :class), :decorator).freeze + end + + private_class_method def self.validate_lack_of_side_effects(node, whitelisted_methods_by_receiver_type) + case node.type + when :const + # This is ok, because we'll have validated what method has been called + # if applicable + when :hash, :array, :str, :sym, :int, :float, :true, :false, :nil, :self # rubocop:disable Lint/BooleanSymbol + # Primitives & self are ok + when :lvar, :arg, :ivar + # Reading local & instance variables & arguments is ok + unless node.children.all? {|c| c.is_a?(Symbol)} + raise ValidationError.new("Unexpected child for #{node.type}: #{node.inspect}") + end + when :args, :mlhs, :block, :begin, :if + # Blocks etc are read-only if their contents are read-only + node.children.each {|c| validate_lack_of_side_effects(c, whitelisted_methods_by_receiver_type) if c} + when :send + # Sends are riskier so check a whitelist + receiver, method, *args = node.children + if receiver + if receiver.type == :send + key = receiver + else + key = receiver.type + validate_lack_of_side_effects(receiver, whitelisted_methods_by_receiver_type) + end + + if !whitelisted_methods_by_receiver_type[key]&.include?(method) + raise ValidationError.new("Unexpected method #{method} called on #{receiver.inspect}") + end + end + args.each do |arg| + validate_lack_of_side_effects(arg, whitelisted_methods_by_receiver_type) + end + else + raise ValidationError.new("Unexpected node type #{node.type}: #{node.inspect}") + end + end + + private_class_method def self.assert_equal(expected, actual) + if expected != actual + raise ValidationError.new("Expected #{expected}, got #{actual}") + end + end + + # Method calls generated by SerdeTransform + private_class_method def self.whitelisted_methods_for_serialize + @whitelisted_methods_for_serialize ||= { + lvar: %i{dup map transform_values transform_keys each_with_object nil? []= serialize}, + ivar: %i[dup map transform_values transform_keys each_with_object serialize], + const: %i[checked_serialize deep_clone_object], + } + end + + # Method calls generated by SerdeTransform + private_class_method def self.whitelisted_methods_for_deserialize + @whitelisted_methods_for_deserialize ||= { + lvar: %i{dup map transform_values transform_keys each_with_object nil? []= to_f}, + const: %i[deserialize from_hash deep_clone_object], + } + end + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/has_lazily_specialized_methods.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/has_lazily_specialized_methods.rb new file mode 100644 index 0000000000..5c1acecb69 --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/has_lazily_specialized_methods.rb @@ -0,0 +1,140 @@ +# frozen_string_literal: true +# typed: false + +module T::Props + + # Helper for generating methods that replace themselves with a specialized + # version on first use. The main use case is when we want to generate a + # method using the full set of props on a class; we can't do that during + # prop definition because we have no way of knowing whether we are defining + # the last prop. + # + # See go/M8yrvzX2 (Stripe-internal) for discussion of security considerations. + # In outline, while `class_eval` is a bit scary, we believe that as long as + # all inputs are defined in version control (and this is enforced by calling + # `disable_lazy_evaluation!` appropriately), risk isn't significantly higher + # than with build-time codegen. + module HasLazilySpecializedMethods + extend T::Sig + + class SourceEvaluationDisabled < RuntimeError + def initialize + super("Evaluation of lazily-defined methods is disabled") + end + end + + # Disable any future evaluation of lazily-defined methods. + # + # This is intended to be called after startup but before interacting with + # the outside world, to limit attack surface for our `class_eval` use. + # + # Note it does _not_ prevent explicit calls to `eagerly_define_lazy_methods!` + # from working. + sig {void} + def self.disable_lazy_evaluation! + @lazy_evaluation_disabled ||= true + end + + sig {returns(T::Boolean)} + def self.lazy_evaluation_enabled? + !defined?(@lazy_evaluation_disabled) || !@lazy_evaluation_disabled + end + + module DecoratorMethods + extend T::Sig + + sig {returns(T::Hash[Symbol, T.proc.returns(String)]).checked(:never)} + private def lazily_defined_methods + @lazily_defined_methods ||= {} + end + + sig {returns(T::Hash[Symbol, T.untyped]).checked(:never)} + private def lazily_defined_vm_methods + @lazily_defined_vm_methods ||= {} + end + + sig {params(name: Symbol).void} + private def eval_lazily_defined_method!(name) + if !HasLazilySpecializedMethods.lazy_evaluation_enabled? + raise SourceEvaluationDisabled.new + end + + source = lazily_defined_methods.fetch(name).call + + cls = decorated_class + cls.class_eval(source.to_s) + cls.send(:private, name) + end + + sig {params(name: Symbol).void} + private def eval_lazily_defined_vm_method!(name) + if !HasLazilySpecializedMethods.lazy_evaluation_enabled? + raise SourceEvaluationDisabled.new + end + + lazily_defined_vm_methods.fetch(name).call + + cls = decorated_class + cls.send(:private, name) + end + + sig {params(name: Symbol, blk: T.proc.returns(String)).void} + private def enqueue_lazy_method_definition!(name, &blk) + lazily_defined_methods[name] = blk + + cls = decorated_class + if cls.method_defined?(name) + # Ruby does not emit "method redefined" warnings for aliased methods + # (more robust than undef_method that would create a small window in which the method doesn't exist) + cls.send(:alias_method, name, name) + end + cls.send(:define_method, name) do |*args| + self.class.decorator.send(:eval_lazily_defined_method!, name) + send(name, *args) + end + if cls.respond_to?(:ruby2_keywords, true) + cls.send(:ruby2_keywords, name) + end + cls.send(:private, name) + end + + sig {params(name: Symbol, blk: T.untyped).void} + private def enqueue_lazy_vm_method_definition!(name, &blk) + lazily_defined_vm_methods[name] = blk + + cls = decorated_class + cls.send(:define_method, name) do |*args| + self.class.decorator.send(:eval_lazily_defined_vm_method!, name) + send(name, *args) + end + if cls.respond_to?(:ruby2_keywords, true) + cls.send(:ruby2_keywords, name) + end + cls.send(:private, name) + end + + sig {void} + def eagerly_define_lazy_methods! + return if lazily_defined_methods.empty? + + source = lazily_defined_methods.values.map(&:call).map(&:to_s).join("\n\n") + + cls = decorated_class + cls.class_eval(source) + lazily_defined_methods.each_key {|name| cls.send(:private, name)} + lazily_defined_methods.clear + end + + sig {void} + def eagerly_define_lazy_vm_methods! + return if lazily_defined_vm_methods.empty? + + lazily_defined_vm_methods.values.map(&:call) + + cls = decorated_class + lazily_defined_vm_methods.each_key {|name| cls.send(:private, name)} + lazily_defined_vm_methods.clear + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/optional.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/optional.rb new file mode 100644 index 0000000000..4f482beac3 --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/optional.rb @@ -0,0 +1,89 @@ +# frozen_string_literal: true +# typed: false + +module T::Props::Optional + include T::Props::Plugin +end + +############################################## + +# NB: This must stay in the same file where T::Props::Optional is defined due to +# T::Props::Decorator#apply_plugin; see https://git.corp.stripe.com/stripe-internal/pay-server/blob/fc7f15593b49875f2d0499ffecfd19798bac05b3/chalk/odm/lib/chalk-odm/document_decorator.rb#L716-L717 +module T::Props::Optional::DecoratorMethods + extend T::Sig + + # Heads up! + # + # There are already too many ad-hoc options on the prop DSL. + # + # We have already done a lot of work to remove unnecessary and confusing + # options. If you're considering adding a new rule key, please come chat with + # the Sorbet team first, as we'd really like to learn more about how to best + # solve the problem you're encountering. + VALID_RULE_KEYS = { + default: true, + factory: true, + }.freeze + private_constant :VALID_RULE_KEYS + + DEFAULT_SETTER_RULE_KEY = :_t_props_private_apply_default + private_constant :DEFAULT_SETTER_RULE_KEY + + def valid_rule_key?(key) + super || VALID_RULE_KEYS[key] + end + + def prop_optional?(prop) + prop_rules(prop)[:fully_optional] + end + + def compute_derived_rules(rules) + rules[:fully_optional] = !T::Props::Utils.need_nil_write_check?(rules) + rules[:need_nil_read_check] = T::Props::Utils.need_nil_read_check?(rules) + end + + # checked(:never) - O(runtime object construction) + sig {returns(T::Hash[Symbol, T::Props::Private::ApplyDefault]).checked(:never)} + attr_reader :props_with_defaults + + # checked(:never) - O(runtime object construction) + sig {returns(T::Hash[Symbol, T::Props::Private::SetterFactory::SetterProc]).checked(:never)} + attr_reader :props_without_defaults + + def add_prop_definition(prop, rules) + compute_derived_rules(rules) + + default_setter = T::Props::Private::ApplyDefault.for(decorated_class, rules) + if default_setter + @props_with_defaults ||= {} + @props_with_defaults[prop] = default_setter + props_without_defaults&.delete(prop) # Handle potential override + + rules[DEFAULT_SETTER_RULE_KEY] = default_setter + else + @props_without_defaults ||= {} + @props_without_defaults[prop] = rules.fetch(:setter_proc) + props_with_defaults&.delete(prop) # Handle potential override + end + + super + end + + def prop_validate_definition!(name, cls, rules, type) + result = super + + if rules.key?(:default) && rules.key?(:factory) + raise ArgumentError.new("Setting both :default and :factory is invalid. See: go/chalk-docs") + end + + result + end + + def has_default?(rules) + rules.include?(DEFAULT_SETTER_RULE_KEY) + end + + def get_default(rules, instance_class) + rules[DEFAULT_SETTER_RULE_KEY]&.default + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/plugin.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/plugin.rb new file mode 100644 index 0000000000..1423c172ed --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/plugin.rb @@ -0,0 +1,37 @@ +# frozen_string_literal: true +# typed: false + +module T::Props::Plugin + include T::Props + extend T::Helpers + + module ClassMethods + def included(child) + super + child.plugin(self) + end + end + mixes_in_class_methods(ClassMethods) + + module Private + # These need to be non-instance methods so we can use them without prematurely creating the + # child decorator in `model_inherited` (see comments there for details). + # + # The dynamic constant access below forces this file to be `typed: false` + def self.apply_class_methods(plugin, target) + if plugin.const_defined?('ClassMethods') + # FIXME: This will break preloading, selective test execution, etc if `mod::ClassMethods` + # is ever defined in a separate file from `mod`. + target.extend(plugin::ClassMethods) + end + end + + def self.apply_decorator_methods(plugin, target) + if plugin.const_defined?('DecoratorMethods') + # FIXME: This will break preloading, selective test execution, etc if `mod::DecoratorMethods` + # is ever defined in a separate file from `mod`. + target.extend(plugin::DecoratorMethods) + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/pretty_printable.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/pretty_printable.rb new file mode 100644 index 0000000000..e821cd3435 --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/pretty_printable.rb @@ -0,0 +1,107 @@ +# frozen_string_literal: true +# typed: true + +module T::Props::PrettyPrintable + include T::Props::Plugin + + # Return a string representation of this object and all of its props + def inspect + T.unsafe(T.cast(self, Object).class).decorator.inspect_instance(self) + end + + # Override the PP gem with something that's similar, but gives us a hook + # to do redaction + def pretty_inspect + T.unsafe(T.cast(self, Object).class).decorator.inspect_instance(self, multiline: true) + end + + module DecoratorMethods + extend T::Sig + + sig {params(key: Symbol).returns(T::Boolean).checked(:never)} + def valid_rule_key?(key) + super || key == :inspect + end + + sig do + params(instance: T::Props::PrettyPrintable, multiline: T::Boolean, indent: String) + .returns(String) + end + def inspect_instance(instance, multiline: false, indent: ' ') + components = + inspect_instance_components( + instance, + multiline: multiline, + indent: indent + ) + .reject(&:empty?) + + # Not using #<> here as that makes pry highlight these objects + # as if they were all comments, whereas this makes them look + # like the structured thing they are. + if multiline + "#{components[0]}:\n" + T.must(components[1..-1]).join("\n") + else + "<#{components.join(' ')}>" + end + end + + sig do + params(instance: T::Props::PrettyPrintable, multiline: T::Boolean, indent: String) + .returns(T::Array[String]) + end + private def inspect_instance_components(instance, multiline:, indent:) + pretty_props = T.unsafe(self).all_props.map do |prop| + [prop, inspect_prop_value(instance, prop, multiline: multiline, indent: indent)] + end + + joined_props = join_props_with_pretty_values( + pretty_props, + multiline: multiline, + indent: indent + ) + + [ + T.unsafe(self).decorated_class.to_s, + joined_props, + ] + end + + sig do + params(instance: T::Props::PrettyPrintable, prop: Symbol, multiline: T::Boolean, indent: String) + .returns(String) + .checked(:never) + end + private def inspect_prop_value(instance, prop, multiline:, indent:) + val = T.unsafe(self).get(instance, prop) + rules = T.unsafe(self).prop_rules(prop) + if (custom_inspect = rules[:inspect]) + if T::Utils.arity(custom_inspect) == 1 + custom_inspect.call(val) + else + custom_inspect.call(val, {multiline: multiline, indent: indent}) + end + elsif rules[:sensitivity] && !rules[:sensitivity].empty? && !val.nil? + "" + else + val.inspect + end + end + + sig do + params(pretty_kvs: T::Array[[Symbol, String]], multiline: T::Boolean, indent: String) + .returns(String) + end + private def join_props_with_pretty_values(pretty_kvs, multiline:, indent: ' ') + pairs = pretty_kvs + .sort_by {|k, _v| k.to_s} + .map {|k, v| "#{k}=#{v}"} + + if multiline + indent + pairs.join("\n#{indent}") + else + pairs.join(', ') + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/private/apply_default.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/private/apply_default.rb new file mode 100644 index 0000000000..b86f506f9a --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/private/apply_default.rb @@ -0,0 +1,170 @@ +# frozen_string_literal: true +# typed: strict + +module T::Props + module Private + class ApplyDefault + extend T::Sig + extend T::Helpers + abstract! + + # checked(:never) - O(object construction x prop count) + sig {returns(SetterFactory::SetterProc).checked(:never)} + attr_reader :setter_proc + + # checked(:never) - We do this with `T.let` instead + sig {params(accessor_key: Symbol, setter_proc: SetterFactory::SetterProc).void.checked(:never)} + def initialize(accessor_key, setter_proc) + @accessor_key = T.let(accessor_key, Symbol) + @setter_proc = T.let(setter_proc, SetterFactory::SetterProc) + end + + # checked(:never) - O(object construction x prop count) + sig {abstract.returns(T.untyped).checked(:never)} + def default; end + + # checked(:never) - O(object construction x prop count) + sig {abstract.params(instance: T.all(T::Props::Optional, Object)).void.checked(:never)} + def set_default(instance); end + + NO_CLONE_TYPES = T.let([TrueClass, FalseClass, NilClass, Symbol, Numeric, T::Enum].freeze, T::Array[Module]) + + # checked(:never) - Rules hash is expensive to check + sig {params(cls: Module, rules: T::Hash[Symbol, T.untyped]).returns(T.nilable(ApplyDefault)).checked(:never)} + def self.for(cls, rules) + accessor_key = rules.fetch(:accessor_key) + setter = rules.fetch(:setter_proc) + + if rules.key?(:factory) + ApplyDefaultFactory.new(cls, rules.fetch(:factory), accessor_key, setter) + elsif rules.key?(:default) + default = rules.fetch(:default) + case default + when *NO_CLONE_TYPES + return ApplyPrimitiveDefault.new(default, accessor_key, setter) + when String + if default.frozen? + return ApplyPrimitiveDefault.new(default, accessor_key, setter) + end + when Array + if default.empty? && default.class == Array + return ApplyEmptyArrayDefault.new(accessor_key, setter) + end + when Hash + if default.empty? && default.default.nil? && T.unsafe(default).default_proc.nil? && default.class == Hash + return ApplyEmptyHashDefault.new(accessor_key, setter) + end + end + + ApplyComplexDefault.new(default, accessor_key, setter) + else + nil + end + end + end + + class ApplyFixedDefault < ApplyDefault + abstract! + + # checked(:never) - We do this with `T.let` instead + sig {params(default: BasicObject, accessor_key: Symbol, setter_proc: SetterFactory::SetterProc).void.checked(:never)} + def initialize(default, accessor_key, setter_proc) + # FIXME: Ideally we'd check here that the default is actually a valid + # value for this field, but existing code relies on the fact that we don't. + # + # :( + # + # setter_proc.call(default) + @default = T.let(default, BasicObject) + super(accessor_key, setter_proc) + end + + # checked(:never) - O(object construction x prop count) + sig {override.params(instance: T.all(T::Props::Optional, Object)).void.checked(:never)} + def set_default(instance) + instance.instance_variable_set(@accessor_key, default) + end + end + + class ApplyPrimitiveDefault < ApplyFixedDefault + # checked(:never) - O(object construction x prop count) + sig {override.returns(T.untyped).checked(:never)} + attr_reader :default + end + + class ApplyComplexDefault < ApplyFixedDefault + # checked(:never) - O(object construction x prop count) + sig {override.returns(T.untyped).checked(:never)} + def default + T::Props::Utils.deep_clone_object(@default) + end + end + + # Special case since it's so common, and a literal `[]` is meaningfully + # faster than falling back to ApplyComplexDefault or even calling + # `some_empty_array.dup` + class ApplyEmptyArrayDefault < ApplyDefault + # checked(:never) - O(object construction x prop count) + sig {override.params(instance: T.all(T::Props::Optional, Object)).void.checked(:never)} + def set_default(instance) + instance.instance_variable_set(@accessor_key, []) + end + + # checked(:never) - O(object construction x prop count) + sig {override.returns(T::Array[T.untyped]).checked(:never)} + def default + [] + end + end + + # Special case since it's so common, and a literal `{}` is meaningfully + # faster than falling back to ApplyComplexDefault or even calling + # `some_empty_hash.dup` + class ApplyEmptyHashDefault < ApplyDefault + # checked(:never) - O(object construction x prop count) + sig {override.params(instance: T.all(T::Props::Optional, Object)).void.checked(:never)} + def set_default(instance) + instance.instance_variable_set(@accessor_key, {}) + end + + # checked(:never) - O(object construction x prop count) + sig {override.returns(T::Hash[T.untyped, T.untyped]).checked(:never)} + def default + {} + end + end + + class ApplyDefaultFactory < ApplyDefault + # checked(:never) - We do this with `T.let` instead + sig do + params( + cls: Module, + factory: T.any(Proc, Method), + accessor_key: Symbol, + setter_proc: SetterFactory::SetterProc, + ) + .void + .checked(:never) + end + def initialize(cls, factory, accessor_key, setter_proc) + @class = T.let(cls, Module) + @factory = T.let(factory, T.any(Proc, Method)) + super(accessor_key, setter_proc) + end + + # checked(:never) - O(object construction x prop count) + sig {override.params(instance: T.all(T::Props::Optional, Object)).void.checked(:never)} + def set_default(instance) + # Use the actual setter to validate the factory returns a legitimate + # value every time + instance.instance_exec(default, &@setter_proc) + end + + # checked(:never) - O(object construction x prop count) + sig {override.returns(T.untyped).checked(:never)} + def default + @class.class_exec(&@factory) + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/private/deserializer_generator.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/private/deserializer_generator.rb new file mode 100644 index 0000000000..2393e1a284 --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/private/deserializer_generator.rb @@ -0,0 +1,160 @@ +# frozen_string_literal: true +# typed: strict + +module T::Props + module Private + + # Generates a specialized `deserialize` implementation for a subclass of + # T::Props::Serializable. + # + # The basic idea is that we analyze the props and for each prop, generate + # the simplest possible logic as a block of Ruby source, so that we don't + # pay the cost of supporting types like T:::Hash[CustomType, SubstructType] + # when deserializing a simple Integer. Then we join those together, + # with a little shared logic to be able to detect when we get input keys + # that don't match any prop. + module DeserializerGenerator + extend T::Sig + + # Generate a method that takes a T::Hash[String, T.untyped] representing + # serialized props, sets instance variables for each prop found in the + # input, and returns the count of we props set (which we can use to check + # for unexpected input keys with minimal effect on the fast path). + sig do + params( + props: T::Hash[Symbol, T::Hash[Symbol, T.untyped]], + defaults: T::Hash[Symbol, T::Props::Private::ApplyDefault], + ) + .returns(String) + .checked(:never) + end + def self.generate(props, defaults) + stored_props = props.reject {|_, rules| rules[:dont_store]} + parts = stored_props.map do |prop, rules| + # All of these strings should already be validated (directly or + # indirectly) in `validate_prop_name`, so we don't bother with a nice + # error message, but we double check here to prevent a refactoring + # from introducing a security vulnerability. + raise unless T::Props::Decorator::SAFE_NAME.match?(prop.to_s) + + hash_key = rules.fetch(:serialized_form) + raise unless T::Props::Decorator::SAFE_NAME.match?(hash_key) + + ivar_name = rules.fetch(:accessor_key).to_s + raise unless ivar_name.start_with?('@') && T::Props::Decorator::SAFE_NAME.match?(ivar_name[1..-1]) + + transformation = SerdeTransform.generate( + T::Utils::Nilable.get_underlying_type_object(rules.fetch(:type_object)), + SerdeTransform::Mode::DESERIALIZE, + 'val' + ) + transformed_val = if transformation + # Rescuing exactly NoMethodError is intended as a temporary hack + # to preserve the semantics from before codegen. More generally + # we are inconsistent about typechecking on deser and need to decide + # our strategy here. + <<~RUBY + begin + #{transformation} + rescue NoMethodError => e + raise_deserialization_error( + #{prop.inspect}, + val, + e, + ) + val + end + RUBY + else + 'val' + end + + nil_handler = generate_nil_handler( + prop: prop, + serialized_form: hash_key, + default: defaults[prop], + nilable_type: T::Props::Utils.optional_prop?(rules), + raise_on_nil_write: !!rules[:raise_on_nil_write], + ) + + <<~RUBY + val = hash[#{hash_key.inspect}] + #{ivar_name} = if val.nil? + found -= 1 unless hash.key?(#{hash_key.inspect}) + #{nil_handler} + else + #{transformed_val} + end + RUBY + end + + <<~RUBY + def __t_props_generated_deserialize(hash) + found = #{stored_props.size} + #{parts.join("\n\n")} + found + end + RUBY + end + + # This is very similar to what we do in ApplyDefault, but has a few + # key differences that mean we don't just re-use the code: + # + # 1. Where the logic in construction is that we generate a default + # if & only if the prop key isn't present in the input, here we'll + # generate a default even to override an explicit nil, but only + # if the prop is actually required. + # 2. Since we're generating raw Ruby source, we can remove a layer + # of indirection for marginally better performance; this seems worth + # it for the common cases of literals and empty arrays/hashes. + # 3. We need to care about the distinction between `raise_on_nil_write` + # and actually non-nilable, where new-instance construction doesn't. + # + # So we fall back to ApplyDefault only when one of the cases just + # mentioned doesn't apply. + sig do + params( + prop: Symbol, + serialized_form: String, + default: T.nilable(ApplyDefault), + nilable_type: T::Boolean, + raise_on_nil_write: T::Boolean, + ) + .returns(String) + .checked(:never) + end + private_class_method def self.generate_nil_handler( + prop:, + serialized_form:, + default:, + nilable_type:, + raise_on_nil_write: + ) + if !nilable_type + case default + when NilClass + "self.class.decorator.raise_nil_deserialize_error(#{serialized_form.inspect})" + when ApplyPrimitiveDefault + literal = default.default + case literal + when String, Integer, Symbol, Float, TrueClass, FalseClass, NilClass + literal.inspect + else + "self.class.decorator.props_with_defaults.fetch(#{prop.inspect}).default" + end + when ApplyEmptyArrayDefault + '[]' + when ApplyEmptyHashDefault + '{}' + else + "self.class.decorator.props_with_defaults.fetch(#{prop.inspect}).default" + end + elsif raise_on_nil_write + "required_prop_missing_from_deserialize(#{prop.inspect})" + else + 'nil' + end + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/private/parser.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/private/parser.rb new file mode 100644 index 0000000000..2ccd574118 --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/private/parser.rb @@ -0,0 +1,32 @@ +# frozen_string_literal: true +# typed: false + +module T::Props + module Private + module Parse + def parse(source) + @current_ruby ||= require_parser(:CurrentRuby) + @current_ruby.parse(source) + end + + def s(type, *children) + @node ||= require_parser(:AST, :Node) + @node.new(type, children) + end + + private def require_parser(*constants) + # This is an optional dependency for sorbet-runtime in general, + # but is required here + require 'parser/current' + + # Hack to work around the static checker thinking the constant is + # undefined + cls = Kernel.const_get(:Parser, true) + while (const = constants.shift) + cls = cls.const_get(const, false) + end + cls + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/private/serde_transform.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/private/serde_transform.rb new file mode 100644 index 0000000000..e0b37a376d --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/private/serde_transform.rb @@ -0,0 +1,186 @@ +# frozen_string_literal: true +# typed: strict + +module T::Props + module Private + module SerdeTransform + extend T::Sig + + class Serialize; end + private_constant :Serialize + class Deserialize; end + private_constant :Deserialize + ModeType = T.type_alias {T.any(Serialize, Deserialize)} + private_constant :ModeType + + module Mode + SERIALIZE = T.let(Serialize.new.freeze, Serialize) + DESERIALIZE = T.let(Deserialize.new.freeze, Deserialize) + end + + NO_TRANSFORM_TYPES = T.let( + [TrueClass, FalseClass, NilClass, Symbol, String].freeze, + T::Array[Module], + ) + private_constant :NO_TRANSFORM_TYPES + + sig do + params( + type: T::Types::Base, + mode: ModeType, + varname: String, + ) + .returns(T.nilable(String)) + .checked(:never) + end + def self.generate(type, mode, varname) + case type + when T::Types::TypedArray + inner = generate(type.type, mode, 'v') + if inner.nil? + "#{varname}.dup" + else + "#{varname}.map {|v| #{inner}}" + end + when T::Types::TypedSet + inner = generate(type.type, mode, 'v') + if inner.nil? + "#{varname}.dup" + else + "Set.new(#{varname}) {|v| #{inner}}" + end + when T::Types::TypedHash + keys = generate(type.keys, mode, 'k') + values = generate(type.values, mode, 'v') + if keys && values + "#{varname}.each_with_object({}) {|(k,v),h| h[#{keys}] = #{values}}" + elsif keys + "#{varname}.transform_keys {|k| #{keys}}" + elsif values + "#{varname}.transform_values {|v| #{values}}" + else + "#{varname}.dup" + end + when T::Types::Simple + raw = type.raw_type + if NO_TRANSFORM_TYPES.any? {|cls| raw <= cls} + nil + elsif raw <= Float + case mode + when Deserialize then "#{varname}.to_f" + when Serialize then nil + else T.absurd(mode) + end + elsif raw <= Numeric + nil + elsif raw < T::Props::Serializable + handle_serializable_subtype(varname, raw, mode) + elsif raw.singleton_class < T::Props::CustomType + handle_custom_type(varname, T.unsafe(raw), mode) + elsif T::Configuration.scalar_types.include?(raw.name) + # It's a bit of a hack that this is separate from NO_TRANSFORM_TYPES + # and doesn't check inheritance (like `T::Props::CustomType.scalar_type?` + # does), but it covers the main use case (pay-server's custom `Boolean` + # module) without either requiring `T::Configuration.scalar_types` to + # accept modules instead of strings (which produces load-order issues + # and subtle behavior changes) or eating the performance cost of doing + # an inheritance check by manually crawling a class hierarchy and doing + # string comparisons. + nil + else + "T::Props::Utils.deep_clone_object(#{varname})" + end + when T::Types::Union + non_nil_type = T::Utils.unwrap_nilable(type) + if non_nil_type + inner = generate(non_nil_type, mode, varname) + if inner.nil? + nil + else + "#{varname}.nil? ? nil : #{inner}" + end + elsif type.types.all? {|t| generate(t, mode, varname).nil?} + # Handle, e.g., T::Boolean + nil + else + # We currently deep_clone_object if the type was T.any(Integer, Float). + # When we get better support for union types (maybe this specific + # union type, because it would be a replacement for + # Chalk::ODM::DeprecatedNumemric), we could opt to special case + # this union to have no specific serde transform (the only reason + # why Float has a special case is because round tripping through + # JSON might normalize Floats to Integers) + "T::Props::Utils.deep_clone_object(#{varname})" + end + when T::Types::Intersection + dynamic_fallback = "T::Props::Utils.deep_clone_object(#{varname})" + + # Transformations for any members of the intersection type where we + # know what we need to do and did not have to fall back to the + # dynamic deep clone method. + # + # NB: This deliberately does include `nil`, which means we know we + # don't need to do any transforming. + inner_known = type.types + .map {|t| generate(t, mode, varname)} + .reject {|t| t == dynamic_fallback} + .uniq + + if inner_known.size != 1 + # If there were no cases where we could tell what we need to do, + # e.g. if this is `T.all(SomethingWeird, WhoKnows)`, just use the + # dynamic fallback. + # + # If there were multiple cases and they weren't consistent, e.g. + # if this is `T.all(String, T::Array[Integer])`, the type is probably + # bogus/uninhabited, but use the dynamic fallback because we still + # don't have a better option, and this isn't the place to raise that + # error. + dynamic_fallback + else + # This is probably something like `T.all(String, SomeMarker)` or + # `T.all(SomeEnum, T.deprecated_enum(SomeEnum::FOO))` and we should + # treat it like String or SomeEnum even if we don't know what to do + # with the rest of the type. + inner_known.first + end + when T::Types::Enum + generate(T::Utils.lift_enum(type), mode, varname) + else + "T::Props::Utils.deep_clone_object(#{varname})" + end + end + + sig {params(varname: String, type: Module, mode: ModeType).returns(String).checked(:never)} + private_class_method def self.handle_serializable_subtype(varname, type, mode) + case mode + when Serialize + "#{varname}.serialize(strict)" + when Deserialize + type_name = T.must(module_name(type)) + "#{type_name}.from_hash(#{varname})" + else + T.absurd(mode) + end + end + + sig {params(varname: String, type: Module, mode: ModeType).returns(String).checked(:never)} + private_class_method def self.handle_custom_type(varname, type, mode) + case mode + when Serialize + "T::Props::CustomType.checked_serialize(#{varname})" + when Deserialize + type_name = T.must(module_name(type)) + "#{type_name}.deserialize(#{varname})" + else + T.absurd(mode) + end + end + + sig {params(type: Module).returns(T.nilable(String)).checked(:never)} + private_class_method def self.module_name(type) + T::Configuration.module_name_mangler.call(type) + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/private/serializer_generator.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/private/serializer_generator.rb new file mode 100644 index 0000000000..0d49a46e0f --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/private/serializer_generator.rb @@ -0,0 +1,76 @@ +# frozen_string_literal: true +# typed: strict + +module T::Props + module Private + + # Generates a specialized `serialize` implementation for a subclass of + # T::Props::Serializable. + # + # The basic idea is that we analyze the props and for each prop, generate + # the simplest possible logic as a block of Ruby source, so that we don't + # pay the cost of supporting types like T:::Hash[CustomType, SubstructType] + # when serializing a simple Integer. Then we join those together, + # with a little shared logic to be able to detect when we get input keys + # that don't match any prop. + module SerializerGenerator + extend T::Sig + + sig do + params( + props: T::Hash[Symbol, T::Hash[Symbol, T.untyped]], + ) + .returns(String) + .checked(:never) + end + def self.generate(props) + stored_props = props.reject {|_, rules| rules[:dont_store]} + parts = stored_props.map do |prop, rules| + # All of these strings should already be validated (directly or + # indirectly) in `validate_prop_name`, so we don't bother with a nice + # error message, but we double check here to prevent a refactoring + # from introducing a security vulnerability. + raise unless T::Props::Decorator::SAFE_NAME.match?(prop.to_s) + + hash_key = rules.fetch(:serialized_form) + raise unless T::Props::Decorator::SAFE_NAME.match?(hash_key) + + ivar_name = rules.fetch(:accessor_key).to_s + raise unless ivar_name.start_with?('@') && T::Props::Decorator::SAFE_NAME.match?(ivar_name[1..-1]) + + transformed_val = SerdeTransform.generate( + T::Utils::Nilable.get_underlying_type_object(rules.fetch(:type_object)), + SerdeTransform::Mode::SERIALIZE, + ivar_name + ) || ivar_name + + nil_asserter = + if rules[:fully_optional] + '' + else + "required_prop_missing_from_serialize(#{prop.inspect}) if strict" + end + + # Don't serialize values that are nil to save space (both the + # nil value itself and the field name in the serialized BSON + # document) + <<~RUBY + if #{ivar_name}.nil? + #{nil_asserter} + else + h[#{hash_key.inspect}] = #{transformed_val} + end + RUBY + end + + <<~RUBY + def __t_props_generated_serialize(strict) + h = {} + #{parts.join("\n\n")} + h + end + RUBY + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/private/setter_factory.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/private/setter_factory.rb new file mode 100644 index 0000000000..00c76ed1e7 --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/private/setter_factory.rb @@ -0,0 +1,197 @@ +# frozen_string_literal: true +# typed: strict + +module T::Props + module Private + module SetterFactory + extend T::Sig + + SetterProc = T.type_alias {T.proc.params(val: T.untyped).void} + ValidateProc = T.type_alias {T.proc.params(prop: Symbol, value: T.untyped).void} + + sig do + params( + klass: T.all(Module, T::Props::ClassMethods), + prop: Symbol, + rules: T::Hash[Symbol, T.untyped] + ) + .returns(SetterProc) + .checked(:never) + end + def self.build_setter_proc(klass, prop, rules) + # Our nil check works differently than a simple T.nilable for various + # reasons (including the `raise_on_nil_write` setting and the existence + # of defaults & factories), so unwrap any T.nilable and do a check + # manually. + non_nil_type = T::Utils::Nilable.get_underlying_type_object(rules.fetch(:type_object)) + accessor_key = rules.fetch(:accessor_key) + validate = rules[:setter_validate] + + # It seems like a bug that this affects the behavior of setters, but + # some existing code relies on this behavior + has_explicit_nil_default = rules.key?(:default) && rules.fetch(:default).nil? + + # Use separate methods in order to ensure that we only close over necessary + # variables + if !T::Props::Utils.need_nil_write_check?(rules) || has_explicit_nil_default + if validate.nil? && non_nil_type.is_a?(T::Types::Simple) + simple_nilable_proc(prop, accessor_key, non_nil_type.raw_type, klass) + else + nilable_proc(prop, accessor_key, non_nil_type, klass, validate) + end + else + if validate.nil? && non_nil_type.is_a?(T::Types::Simple) + simple_non_nil_proc(prop, accessor_key, non_nil_type.raw_type, klass) + else + non_nil_proc(prop, accessor_key, non_nil_type, klass, validate) + end + end + end + + sig do + params( + prop: Symbol, + accessor_key: Symbol, + non_nil_type: Module, + klass: T.all(Module, T::Props::ClassMethods), + ) + .returns(SetterProc) + end + private_class_method def self.simple_non_nil_proc(prop, accessor_key, non_nil_type, klass) + proc do |val| + unless val.is_a?(non_nil_type) + T::Props::Private::SetterFactory.raise_pretty_error( + klass, + prop, + T::Utils.coerce(non_nil_type), + val, + ) + end + instance_variable_set(accessor_key, val) + end + end + + sig do + params( + prop: Symbol, + accessor_key: Symbol, + non_nil_type: T::Types::Base, + klass: T.all(Module, T::Props::ClassMethods), + validate: T.nilable(ValidateProc) + ) + .returns(SetterProc) + end + private_class_method def self.non_nil_proc(prop, accessor_key, non_nil_type, klass, validate) + proc do |val| + # this use of recursively_valid? is intentional: unlike for + # methods, we want to make sure data at the 'edge' + # (e.g. models that go into databases or structs serialized + # from disk) are correct, so we use more thorough runtime + # checks there + if non_nil_type.recursively_valid?(val) + validate&.call(prop, val) + else + T::Props::Private::SetterFactory.raise_pretty_error( + klass, + prop, + non_nil_type, + val, + ) + end + instance_variable_set(accessor_key, val) + end + end + + sig do + params( + prop: Symbol, + accessor_key: Symbol, + non_nil_type: Module, + klass: T.all(Module, T::Props::ClassMethods), + ) + .returns(SetterProc) + end + private_class_method def self.simple_nilable_proc(prop, accessor_key, non_nil_type, klass) + proc do |val| + if val.nil? + instance_variable_set(accessor_key, nil) + elsif val.is_a?(non_nil_type) + instance_variable_set(accessor_key, val) + else + T::Props::Private::SetterFactory.raise_pretty_error( + klass, + prop, + T::Utils.coerce(non_nil_type), + val, + ) + instance_variable_set(accessor_key, val) + end + end + end + + sig do + params( + prop: Symbol, + accessor_key: Symbol, + non_nil_type: T::Types::Base, + klass: T.all(Module, T::Props::ClassMethods), + validate: T.nilable(ValidateProc), + ) + .returns(SetterProc) + end + private_class_method def self.nilable_proc(prop, accessor_key, non_nil_type, klass, validate) + proc do |val| + if val.nil? + instance_variable_set(accessor_key, nil) + # this use of recursively_valid? is intentional: unlike for + # methods, we want to make sure data at the 'edge' + # (e.g. models that go into databases or structs serialized + # from disk) are correct, so we use more thorough runtime + # checks there + elsif non_nil_type.recursively_valid?(val) + validate&.call(prop, val) + instance_variable_set(accessor_key, val) + else + T::Props::Private::SetterFactory.raise_pretty_error( + klass, + prop, + non_nil_type, + val, + ) + instance_variable_set(accessor_key, val) + end + end + end + + sig do + params( + klass: T.all(Module, T::Props::ClassMethods), + prop: Symbol, + type: T.any(T::Types::Base, Module), + val: T.untyped, + ) + .void + end + def self.raise_pretty_error(klass, prop, type, val) + base_message = "Can't set #{klass.name}.#{prop} to #{val.inspect} (instance of #{val.class}) - need a #{type}" + + pretty_message = "Parameter '#{prop}': #{base_message}\n" + caller_loc = caller_locations&.find {|l| !l.to_s.include?('sorbet-runtime/lib/types/props')} + if caller_loc + pretty_message += "Caller: #{caller_loc.path}:#{caller_loc.lineno}\n" + end + + T::Configuration.call_validation_error_handler( + nil, + message: base_message, + pretty_message: pretty_message, + kind: 'Parameter', + name: prop, + type: type, + value: val, + location: caller_loc, + ) + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/serializable.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/serializable.rb new file mode 100644 index 0000000000..2e2ea1b749 --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/serializable.rb @@ -0,0 +1,374 @@ +# frozen_string_literal: true +# typed: false + +module T::Props::Serializable + include T::Props::Plugin + # Required because we have special handling for `optional: false` + include T::Props::Optional + # Required because we have special handling for extra_props + include T::Props::PrettyPrintable + + # Serializes this object to a hash, suitable for conversion to + # JSON/BSON. + # + # @param strict [T::Boolean] (true) If false, do not raise an + # exception if this object has mandatory props with missing + # values. + # @return [Hash] A serialization of this object. + def serialize(strict=true) + begin + h = __t_props_generated_serialize(strict) + rescue => e + msg = self.class.decorator.message_with_generated_source_context( + e, + :__t_props_generated_serialize, + :generate_serialize_source + ) + if msg + begin + raise e.class.new(msg) + rescue ArgumentError + raise TypeError.new(msg) + end + else + raise + end + end + + h.merge!(@_extra_props) if defined?(@_extra_props) + h + end + + private def __t_props_generated_serialize(strict) + # No-op; will be overridden if there are any props. + # + # To see the definition for class `Foo`, run `Foo.decorator.send(:generate_serialize_source)` + {} + end + + # Populates the property values on this object with the values + # from a hash. In general, prefer to use {.from_hash} to construct + # a new instance, instead of loading into an existing instance. + # + # @param hash [Hash] The hash to take property + # values from. + # @param strict [T::Boolean] (false) If true, raise an exception if + # the hash contains keys that do not correspond to any known + # props on this instance. + # @return [void] + def deserialize(hash, strict=false) + begin + hash_keys_matching_props = __t_props_generated_deserialize(hash) + rescue => e + msg = self.class.decorator.message_with_generated_source_context( + e, + :__t_props_generated_deserialize, + :generate_deserialize_source + ) + if msg + begin + raise e.class.new(msg) + rescue ArgumentError + raise TypeError.new(msg) + end + else + raise + end + end + + if hash.size > hash_keys_matching_props + serialized_forms = self.class.decorator.prop_by_serialized_forms + extra = hash.reject {|k, _| serialized_forms.key?(k)} + + # `extra` could still be empty here if the input matches a `dont_store` prop; + # historically, we just ignore those + if !extra.empty? + if strict + raise "Unknown properties for #{self.class.name}: #{extra.keys.inspect}" + else + @_extra_props = extra + end + end + end + end + + private def __t_props_generated_deserialize(hash) + # No-op; will be overridden if there are any props. + # + # To see the definition for class `Foo`, run `Foo.decorator.send(:generate_deserialize_source)` + 0 + end + + # with() will clone the old object to the new object and merge the specified props to the new object. + def with(changed_props) + with_existing_hash(changed_props, existing_hash: self.serialize) + end + + private def recursive_stringify_keys(obj) + if obj.is_a?(Hash) + new_obj = obj.class.new + obj.each do |k, v| + new_obj[k.to_s] = recursive_stringify_keys(v) + end + elsif obj.is_a?(Array) + new_obj = obj.map {|v| recursive_stringify_keys(v)} + else + new_obj = obj + end + new_obj + end + + private def with_existing_hash(changed_props, existing_hash:) + serialized = existing_hash + new_val = self.class.from_hash(serialized.merge(recursive_stringify_keys(changed_props))) + old_extra = self.instance_variable_get(:@_extra_props) if self.instance_variable_defined?(:@_extra_props) + new_extra = new_val.instance_variable_get(:@_extra_props) if new_val.instance_variable_defined?(:@_extra_props) + if old_extra != new_extra + difference = + if old_extra + new_extra.reject {|k, v| old_extra[k] == v} + else + new_extra + end + raise ArgumentError.new("Unexpected arguments: input(#{changed_props}), unexpected(#{difference})") + end + new_val + end + + # Asserts if this property is missing during strict serialize + private def required_prop_missing_from_serialize(prop) + if defined?(@_required_props_missing_from_deserialize) && + @_required_props_missing_from_deserialize&.include?(prop) + # If the prop was already missing during deserialization, that means the application + # code already had to deal with a nil value, which means we wouldn't be accomplishing + # much by raising here (other than causing an unnecessary breakage). + T::Configuration.log_info_handler( + "chalk-odm: missing required property in serialize", + prop: prop, class: self.class.name, id: self.class.decorator.get_id(self) + ) + else + raise TypeError.new("#{self.class.name}.#{prop} not set for non-optional prop") + end + end + + # Marks this property as missing during deserialize + private def required_prop_missing_from_deserialize(prop) + @_required_props_missing_from_deserialize ||= Set[] + @_required_props_missing_from_deserialize << prop + nil + end + + private def raise_deserialization_error(prop_name, value, orig_error) + T::Configuration.soft_assert_handler( + 'Deserialization error (probably unexpected stored type)', + storytime: { + klass: self.class, + prop: prop_name, + value: value, + error: orig_error.message, + notify: 'djudd' + } + ) + end +end + +############################################## + +# NB: This must stay in the same file where T::Props::Serializable is defined due to +# T::Props::Decorator#apply_plugin; see https://git.corp.stripe.com/stripe-internal/pay-server/blob/fc7f15593b49875f2d0499ffecfd19798bac05b3/chalk/odm/lib/chalk-odm/document_decorator.rb#L716-L717 +module T::Props::Serializable::DecoratorMethods + include T::Props::HasLazilySpecializedMethods::DecoratorMethods + + # Heads up! + # + # There are already too many ad-hoc options on the prop DSL. + # + # We have already done a lot of work to remove unnecessary and confusing + # options. If you're considering adding a new rule key, please come chat with + # the Sorbet team first, as we'd really like to learn more about how to best + # solve the problem you're encountering. + VALID_RULE_KEYS = {dont_store: true, name: true, raise_on_nil_write: true}.freeze + private_constant :VALID_RULE_KEYS + + def valid_rule_key?(key) + super || VALID_RULE_KEYS[key] + end + + def required_props + @class.props.select {|_, v| T::Props::Utils.required_prop?(v)}.keys + end + + def prop_dont_store?(prop) + prop_rules(prop)[:dont_store] + end + def prop_by_serialized_forms + @class.prop_by_serialized_forms + end + + def from_hash(hash, strict=false) + raise ArgumentError.new("#{hash.inspect} provided to from_hash") if !(hash && hash.is_a?(Hash)) + + i = @class.allocate + i.deserialize(hash, strict) + + i + end + + def prop_serialized_form(prop) + prop_rules(prop)[:serialized_form] + end + + def serialized_form_prop(serialized_form) + prop_by_serialized_forms[serialized_form.to_s] || raise("No such serialized form: #{serialized_form.inspect}") + end + + def add_prop_definition(prop, rules) + rules[:serialized_form] = rules.fetch(:name, prop.to_s) + res = super + prop_by_serialized_forms[rules[:serialized_form]] = prop + if T::Configuration.use_vm_prop_serde? + enqueue_lazy_vm_method_definition!(:__t_props_generated_serialize) {generate_serialize2} + enqueue_lazy_vm_method_definition!(:__t_props_generated_deserialize) {generate_deserialize2} + else + enqueue_lazy_method_definition!(:__t_props_generated_serialize) {generate_serialize_source} + enqueue_lazy_method_definition!(:__t_props_generated_deserialize) {generate_deserialize_source} + end + res + end + + private def generate_serialize_source + T::Props::Private::SerializerGenerator.generate(props) + end + + private def generate_deserialize_source + T::Props::Private::DeserializerGenerator.generate( + props, + props_with_defaults || {}, + ) + end + + private def generate_serialize2 + T::Props::Private::SerializerGenerator.generate2(decorated_class, props) + end + + private def generate_deserialize2 + T::Props::Private::DeserializerGenerator.generate2( + decorated_class, + props, + props_with_defaults || {}, + ) + end + + def message_with_generated_source_context(error, generated_method, generate_source_method) + line_label = error.backtrace.find {|l| l.end_with?("in `#{generated_method}'")} + return unless line_label + + line_num = line_label.split(':')[1]&.to_i + return unless line_num + + source_lines = self.send(generate_source_method).split("\n") + previous_blank = source_lines[0...line_num].rindex(&:empty?) || 0 + next_blank = line_num + (source_lines[line_num..-1]&.find_index(&:empty?) || 0) + context = " #{source_lines[(previous_blank + 1)...next_blank].join("\n ")}" + <<~MSG + Error in #{decorated_class.name}##{generated_method}: #{error.message} + at line #{line_num - previous_blank - 1} in: + #{context} + MSG + end + + def raise_nil_deserialize_error(hkey) + msg = "Tried to deserialize a required prop from a nil value. It's "\ + "possible that a nil value exists in the database, so you should "\ + "provide a `default: or factory:` for this prop (see go/optional "\ + "for more details). If this is already the case, you probably "\ + "omitted a required prop from the `fields:` option when doing a "\ + "partial load." + storytime = {prop: hkey, klass: decorated_class.name} + + # Notify the model owner if it exists, and always notify the API owner. + begin + if T::Configuration.class_owner_finder && (owner = T::Configuration.class_owner_finder.call(decorated_class)) + T::Configuration.hard_assert_handler( + msg, + storytime: storytime, + project: owner + ) + end + ensure + T::Configuration.hard_assert_handler(msg, storytime: storytime) + end + end + + def prop_validate_definition!(name, cls, rules, type) + result = super + + if (rules_name = rules[:name]) + unless rules_name.is_a?(String) + raise ArgumentError.new("Invalid name in prop #{@class.name}.#{name}: #{rules_name.inspect}") + end + + validate_prop_name(rules_name) + end + + if !rules[:raise_on_nil_write].nil? && rules[:raise_on_nil_write] != true + raise ArgumentError.new("The value of `raise_on_nil_write` if specified must be `true` (given: #{rules[:raise_on_nil_write]}).") + end + + result + end + + def get_id(instance) + prop = prop_by_serialized_forms['_id'] + if prop + get(instance, prop) + else + nil + end + end + + EMPTY_EXTRA_PROPS = {}.freeze + private_constant :EMPTY_EXTRA_PROPS + + def extra_props(instance) + if instance.instance_variable_defined?(:@_extra_props) + instance.instance_variable_get(:@_extra_props) || EMPTY_EXTRA_PROPS + else + EMPTY_EXTRA_PROPS + end + end + + # overrides T::Props::PrettyPrintable + private def inspect_instance_components(instance, multiline:, indent:) + if (extra_props = extra_props(instance)) && !extra_props.empty? + pretty_kvs = extra_props.map {|k, v| [k.to_sym, v.inspect]} + extra = join_props_with_pretty_values(pretty_kvs, multiline: false) + super + ["@_extra_props=<#{extra}>"] + else + super + end + end +end + +############################################## + +# NB: This must stay in the same file where T::Props::Serializable is defined due to +# T::Props::Decorator#apply_plugin; see https://git.corp.stripe.com/stripe-internal/pay-server/blob/fc7f15593b49875f2d0499ffecfd19798bac05b3/chalk/odm/lib/chalk-odm/document_decorator.rb#L716-L717 +module T::Props::Serializable::ClassMethods + def prop_by_serialized_forms + @prop_by_serialized_forms ||= {} + end + + # Allocate a new instance and call {#deserialize} to load a new + # object from a hash. + # @return [Serializable] + def from_hash(hash, strict=false) + self.decorator.from_hash(hash, strict) + end + + # Equivalent to {.from_hash} with `strict` set to true. + # @return [Serializable] + def from_hash!(hash) + self.decorator.from_hash(hash, true) + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/type_validation.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/type_validation.rb new file mode 100644 index 0000000000..ae3557783d --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/type_validation.rb @@ -0,0 +1,111 @@ +# frozen_string_literal: true +# typed: false + +module T::Props::TypeValidation + include T::Props::Plugin + + BANNED_TYPES = [Object, BasicObject, Kernel].freeze + + class UnderspecifiedType < ArgumentError; end + + module DecoratorMethods + extend T::Sig + + sig {params(key: Symbol).returns(T::Boolean).checked(:never)} + def valid_rule_key?(key) + super || key == :DEPRECATED_underspecified_type + end + + sig do + params( + name: T.any(Symbol, String), + _cls: Module, + rules: T::Hash[Symbol, T.untyped], + type: T.any(T::Types::Base, Module) + ) + .void + end + def prop_validate_definition!(name, _cls, rules, type) + super + + if !rules[:DEPRECATED_underspecified_type] + validate_type(type, field_name: name) + elsif rules[:DEPRECATED_underspecified_type] && find_invalid_subtype(type).nil? + raise ArgumentError.new("DEPRECATED_underspecified_type set unnecessarily for #{@class.name}.#{name} - #{type} is a valid type") + end + end + + sig do + params( + type: T::Types::Base, + field_name: T.any(Symbol, String), + ) + .void + end + private def validate_type(type, field_name:) + if (invalid_subtype = find_invalid_subtype(type)) + raise UnderspecifiedType.new(type_error_message(invalid_subtype, field_name, type)) + end + end + + # Returns an invalid type, if any, found in the given top-level type. + # This might be the type itself, if it is e.g. "Object", or might be + # a subtype like the type of the values of a typed hash. + # + # If the type is fully valid, returns nil. + # + # checked(:never) - called potentially many times recursively + sig {params(type: T::Types::Base).returns(T.nilable(T::Types::Base)).checked(:never)} + private def find_invalid_subtype(type) + case type + when T::Types::TypedEnumerable + find_invalid_subtype(type.type) + when T::Types::FixedHash + type.types.values.map {|subtype| find_invalid_subtype(subtype)}.compact.first + when T::Types::Union, T::Types::FixedArray + # `T.any` is valid if all of the members are valid + type.types.map {|subtype| find_invalid_subtype(subtype)}.compact.first + when T::Types::Intersection + # `T.all` is valid if at least one of the members is valid + invalid = type.types.map {|subtype| find_invalid_subtype(subtype)}.compact + if invalid.length == type.types.length + invalid.first + else + nil + end + when T::Types::Enum, T::Types::ClassOf + nil + when T::Private::Types::TypeAlias + find_invalid_subtype(type.aliased_type) + when T::Types::Simple + # TODO Could we manage to define a whitelist, consisting of something + # like primitives, subdocs, DataInterfaces, and collections/enums/unions + # thereof? + if BANNED_TYPES.include?(type.raw_type) + type + else + nil + end + else + type + end + end + + sig do + params( + type: T::Types::Base, + field_name: T.any(Symbol, String), + orig_type: T::Types::Base, + ) + .returns(String) + end + private def type_error_message(type, field_name, orig_type) + msg_prefix = "#{@class.name}.#{field_name}: #{orig_type} is invalid in prop definition" + if type == orig_type + "#{msg_prefix}. Please choose a more specific type (T.untyped and ~equivalents like Object are banned)." + else + "#{msg_prefix}. Please choose a subtype more specific than #{type} (T.untyped and ~equivalents like Object are banned)." + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/utils.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/utils.rb new file mode 100644 index 0000000000..33d1abadce --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/utils.rb @@ -0,0 +1,59 @@ +# frozen_string_literal: true +# typed: true + +module T::Props::Utils + # Deep copy an object. The object must consist of Ruby primitive + # types and Hashes and Arrays. + def self.deep_clone_object(what, freeze: false) + result = case what + when true + true + when false + false + when Symbol, NilClass, Numeric + what + when Array + what.map {|v| deep_clone_object(v, freeze: freeze)} + when Hash + h = what.class.new + what.each do |k, v| + k.freeze if freeze + h[k] = deep_clone_object(v, freeze: freeze) + end + h + when Regexp + what.dup + when T::Enum + what + else + what.clone + end + freeze ? result.freeze : result + end + + # The prop_rules indicate whether we should check for reading a nil value for the prop/field. + # This is mostly for the compatibility check that we allow existing documents carry some nil prop/field. + def self.need_nil_read_check?(prop_rules) + # . :on_load allows nil read, but we need to check for the read for future writes + prop_rules[:optional] == :on_load || prop_rules[:raise_on_nil_write] + end + + # The prop_rules indicate whether we should check for writing a nil value for the prop/field. + def self.need_nil_write_check?(prop_rules) + need_nil_read_check?(prop_rules) || T::Props::Utils.required_prop?(prop_rules) + end + + def self.required_prop?(prop_rules) + # Clients should never reference :_tnilable as the implementation can change. + !prop_rules[:_tnilable] + end + + def self.optional_prop?(prop_rules) + # Clients should never reference :_tnilable as the implementation can change. + !!prop_rules[:_tnilable] + end + + def self.merge_serialized_optional_rule(prop_rules) + {'_tnilable' => true}.merge(prop_rules.merge('_tnilable' => true)) + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/weak_constructor.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/weak_constructor.rb new file mode 100644 index 0000000000..3ffe1be695 --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/weak_constructor.rb @@ -0,0 +1,67 @@ +# frozen_string_literal: true +# typed: false + +module T::Props::WeakConstructor + include T::Props::Optional + extend T::Sig + + # checked(:never) - O(runtime object construction) + sig {params(hash: T::Hash[Symbol, T.untyped]).void.checked(:never)} + def initialize(hash={}) + decorator = self.class.decorator + + hash_keys_matching_props = decorator.construct_props_with_defaults(self, hash) + + decorator.construct_props_without_defaults(self, hash) + + if hash_keys_matching_props < hash.size + raise ArgumentError.new("#{self.class}: Unrecognized properties: #{(hash.keys - decorator.props.keys).join(', ')}") + end + end +end + +module T::Props::WeakConstructor::DecoratorMethods + extend T::Sig + + # Set values for all props that have no defaults. Ignore any not present. + # + # @return [Integer] A count of props that we successfully initialized (which + # we'll use to check for any unrecognized input.) + # + # checked(:never) - O(runtime object construction) + sig {params(instance: T::Props::WeakConstructor, hash: T::Hash[Symbol, T.untyped]).returns(Integer).checked(:never)} + def construct_props_without_defaults(instance, hash) + # Use `each_pair` rather than `count` because, as of Ruby 2.6, the latter delegates to Enumerator + # and therefore allocates for each entry. + result = 0 + props_without_defaults&.each_pair do |p, setter_proc| + if hash.key?(p) + instance.instance_exec(hash[p], &setter_proc) + result += 1 + end + end + result + end + + # Set values for all props that have defaults. Use the default if and only if + # the prop key isn't in the input. + # + # @return [Integer] A count of props that we successfully initialized (which + # we'll use to check for any unrecognized input.) + # + # checked(:never) - O(runtime object construction) + sig {params(instance: T::Props::WeakConstructor, hash: T::Hash[Symbol, T.untyped]).returns(Integer).checked(:never)} + def construct_props_with_defaults(instance, hash) + # Use `each_pair` rather than `count` because, as of Ruby 2.6, the latter delegates to Enumerator + # and therefore allocates for each entry. + result = 0 + props_with_defaults&.each_pair do |p, default_struct| + if hash.key?(p) + instance.instance_exec(hash[p], &default_struct.setter_proc) + result += 1 + else + default_struct.set_default(instance) + end + end + result + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/sig.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/sig.rb new file mode 100644 index 0000000000..3112adf861 --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/sig.rb @@ -0,0 +1,30 @@ +# frozen_string_literal: true +# typed: strict + +# Used as a mixin to any class so that you can call `sig`. +# Docs at https://sorbet.org/docs/sigs +module T::Sig + module WithoutRuntime + # At runtime, does nothing, but statically it is treated exactly the same + # as T::Sig#sig. Only use it in cases where you can't use T::Sig#sig. + def self.sig(arg0=nil, &blk); end + + original_verbose = $VERBOSE + $VERBOSE = false + + # At runtime, does nothing, but statically it is treated exactly the same + # as T::Sig#sig. Only use it in cases where you can't use T::Sig#sig. + T::Sig::WithoutRuntime.sig {params(arg0: T.nilable(Symbol), blk: T.proc.bind(T::Private::Methods::DeclBuilder).void).void} + def self.sig(arg0=nil, &blk); end # rubocop:disable Lint/DuplicateMethods + + $VERBOSE = original_verbose + end + + # Declares a method with type signatures and/or + # abstract/override/... helpers. See the documentation URL on + # {T::Helpers} + T::Sig::WithoutRuntime.sig {params(arg0: T.nilable(Symbol), blk: T.proc.bind(T::Private::Methods::DeclBuilder).void).void} + def sig(arg0=nil, &blk) + T::Private::Methods.declare_sig(self, Kernel.caller_locations(1, 1)&.first, arg0, &blk) + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/struct.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/struct.rb new file mode 100644 index 0000000000..5f35d1f81f --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/struct.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true +# typed: true + +class T::InexactStruct + include T::Props + include T::Props::Serializable + include T::Props::Constructor +end + +class T::Struct < T::InexactStruct + def self.inherited(subclass) + super(subclass) + T::Private::ClassUtils.replace_method(subclass.singleton_class, :inherited) do |s| + super(s) + raise "#{self.name} is a subclass of T::Struct and cannot be subclassed" + end + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/attached_class.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/attached_class.rb new file mode 100644 index 0000000000..059956a68d --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/attached_class.rb @@ -0,0 +1,37 @@ +# frozen_string_literal: true +# typed: true + +module T::Types + # Modeling AttachedClass properly at runtime would require additional + # tracking, so at runtime we permit all values and rely on the static checker. + # As AttachedClass is modeled statically as a type member on every singleton + # class, this is consistent with the runtime behavior for all type members. + class AttachedClassType < Base + + def initialize(); end + + # overrides Base + def name + "T.attached_class" + end + + # overrides Base + def valid?(obj) + true + end + + # overrides Base + private def subtype_of_single?(other) + case other + when AttachedClassType + true + else + false + end + end + + module Private + INSTANCE = AttachedClassType.new.freeze + end + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/base.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/base.rb new file mode 100644 index 0000000000..cce89b178a --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/base.rb @@ -0,0 +1,172 @@ +# frozen_string_literal: true +# typed: true + +module T::Types + class Base + def self.method_added(method_name) + super(method_name) + # What is now `subtype_of_single?` used to be named `subtype_of?`. Make sure people don't + # override the wrong thing. + # + # NB: Outside of T::Types, we would enforce this by using `sig` and not declaring the method + # as overridable, but doing so here would result in a dependency cycle. + if method_name == :subtype_of? && self != T::Types::Base + raise "`subtype_of?` should not be overridden. You probably want to override " \ + "`subtype_of_single?` instead." + end + end + + # this will be redefined in certain subclasses + def recursively_valid?(obj) + valid?(obj) + end + + def valid?(obj) + raise NotImplementedError + end + + # @return [T::Boolean] This method must be implemented to return whether the subclass is a subtype + # of `type`. This should only be called by `subtype_of?`, which guarantees that `type` will be + # a "single" type, by which we mean it won't be a Union or an Intersection (c.f. + # `isSubTypeSingle` in sorbet). + private def subtype_of_single?(type) + raise NotImplementedError + end + + # Equality is based on name, so be sure the name reflects all relevant state when implementing. + def name + raise NotImplementedError + end + + # Mirrors ruby_typer::core::Types::isSubType + # See https://git.corp.stripe.com/stripe-internal/ruby-typer/blob/9fc8ed998c04ac0b96592ae6bb3493b8a925c5c1/core/types/subtyping.cc#L912-L950 + # + # This method cannot be overridden (see `method_added` above). + # Subclasses only need to implement `subtype_of_single?`). + def subtype_of?(t2) + t1 = self + + if t2.is_a?(T::Private::Types::TypeAlias) + t2 = t2.aliased_type + end + + if t1.is_a?(T::Private::Types::TypeAlias) + return t1.aliased_type.subtype_of?(t2) + end + + # pairs to cover: 1 (_, _) + # 2 (_, And) + # 3 (_, Or) + # 4 (And, _) + # 5 (And, And) + # 6 (And, Or) + # 7 (Or, _) + # 8 (Or, And) + # 9 (Or, Or) + + # Note: order of cases here matters! + if t1.is_a?(T::Types::Union) # 7, 8, 9 + # this will be incorrect if/when we have Type members + return t1.types.all? {|t1_member| t1_member.subtype_of?(t2)} + end + + if t2.is_a?(T::Types::Intersection) # 2, 5 + # this will be incorrect if/when we have Type members + return t2.types.all? {|t2_member| t1.subtype_of?(t2_member)} + end + + if t2.is_a?(T::Types::Union) + if t1.is_a?(T::Types::Intersection) # 6 + # dropping either of parts eagerly make subtype test be too strict. + # we have to try both cases, when we normally try only one + return t2.types.any? {|t2_member| t1.subtype_of?(t2_member)} || + t1.types.any? {|t1_member| t1_member.subtype_of?(t2)} + end + return t2.types.any? {|t2_member| t1.subtype_of?(t2_member)} # 3 + end + + if t1.is_a?(T::Types::Intersection) # 4 + # this will be incorrect if/when we have Type members + return t1.types.any? {|t1_member| t1_member.subtype_of?(t2)} + end + + # 1; Start with some special cases + if t1.is_a?(T::Private::Types::Void) + return t2.is_a?(T::Private::Types::Void) + end + + if t1.is_a?(T::Types::Untyped) || t2.is_a?(T::Types::Untyped) + return true + end + + # Rest of (1) + subtype_of_single?(t2) + end + + def to_s + name + end + + def describe_obj(obj) + # Would be redundant to print class and value in these common cases. + case obj + when nil, true, false + return "type #{obj.class}" + end + + # In rare cases, obj.inspect may fail, or be undefined, so rescue. + begin + # Default inspect behavior of, eg; `#` is ugly; just print the hash instead, which is more concise/readable. + if obj.method(:inspect).owner == Kernel + "type #{obj.class} with hash #{obj.hash}" + elsif T::Configuration.include_value_in_type_errors? + "type #{obj.class} with value #{T::Utils.string_truncate_middle(obj.inspect, 30, 30)}" + else + "type #{obj.class}" + end + rescue StandardError, SystemStackError + "type #{obj.class} with unprintable value" + end + end + + def error_message_for_obj(obj) + if valid?(obj) + nil + else + error_message(obj) + end + end + + def error_message_for_obj_recursive(obj) + if recursively_valid?(obj) + nil + else + error_message(obj) + end + end + + private def error_message(obj) + "Expected type #{self.name}, got #{describe_obj(obj)}" + end + + def validate!(obj) + err = error_message_for_obj(obj) + raise TypeError.new(err) if err + end + + ### Equality methods (necessary for deduping types with `uniq`) + + def hash + name.hash + end + + # Type equivalence, defined by serializing the type to a string (with + # `#name`) and comparing the resulting strings for equality. + def ==(other) + (T::Utils.resolve_alias(other).class == T::Utils.resolve_alias(self).class) && + other.name == self.name + end + + alias_method :eql?, :== + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/class_of.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/class_of.rb new file mode 100644 index 0000000000..d56f21d4c7 --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/class_of.rb @@ -0,0 +1,40 @@ +# frozen_string_literal: true +# typed: true + +module T::Types + # Validates that an object belongs to the specified class. + class ClassOf < Base + attr_reader :type + + def initialize(type) + @type = type + end + + # overrides Base + def name + "T.class_of(#{@type})" + end + + # overrides Base + def valid?(obj) + obj.is_a?(Module) && obj <= @type + end + + # overrides Base + def subtype_of_single?(other) + case other + when ClassOf + @type <= other.type + when Simple + @type.is_a?(other.raw_type) + else + false + end + end + + # overrides Base + def describe_obj(obj) + obj.inspect + end + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/enum.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/enum.rb new file mode 100644 index 0000000000..97ecfe0c0c --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/enum.rb @@ -0,0 +1,40 @@ +# frozen_string_literal: true +# typed: true + +module T::Types + # validates that the provided value is within a given set/enum + class Enum < Base + extend T::Sig + + attr_reader :values + + def initialize(values) + @values = values + end + + # overrides Base + def valid?(obj) + @values.member?(obj) + end + + # overrides Base + private def subtype_of_single?(other) + case other + when Enum + (other.values - @values).empty? + else + false + end + end + + # overrides Base + def name + "T.deprecated_enum([#{@values.map(&:inspect).join(', ')}])" + end + + # overrides Base + def describe_obj(obj) + obj.inspect + end + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/fixed_array.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/fixed_array.rb new file mode 100644 index 0000000000..3bed082bcc --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/fixed_array.rb @@ -0,0 +1,86 @@ +# frozen_string_literal: true +# https://jira.corp.stripe.com/browse/RUBYPLAT-1107 +# typed: false + +module T::Types + # Takes a list of types. Validates each item in an array using the type in the same position + # in the list. + class FixedArray < Base + attr_reader :types + + def initialize(types) + @types = types.map {|type| T::Utils.coerce(type)} + end + + # overrides Base + def name + "[#{@types.join(', ')}]" + end + + # overrides Base + def recursively_valid?(obj) + if obj.is_a?(Array) && obj.length == @types.length + i = 0 + while i < @types.length + if !@types[i].recursively_valid?(obj[i]) + return false + end + i += 1 + end + true + else + false + end + end + + # overrides Base + def valid?(obj) + if obj.is_a?(Array) && obj.length == @types.length + i = 0 + while i < @types.length + if !@types[i].valid?(obj[i]) + return false + end + i += 1 + end + true + else + false + end + end + + # overrides Base + private def subtype_of_single?(other) + case other + when FixedArray + # Properly speaking, covariance here is unsound since arrays + # can be mutated, but sorbet implements covariant tuples for + # ease of adoption. + @types.size == other.types.size && @types.zip(other.types).all? do |t1, t2| + t1.subtype_of?(t2) + end + else + false + end + end + + # This gives us better errors, e.g.: + # "Expected [String, Symbol], got [String, String]" + # instead of + # "Expected [String, Symbol], got Array". + # + # overrides Base + def describe_obj(obj) + if obj.is_a?(Array) + if obj.length == @types.length + item_classes = obj.map(&:class).join(', ') + "type [#{item_classes}]" + else + "array of size #{obj.length}" + end + else + super + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/fixed_hash.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/fixed_hash.rb new file mode 100644 index 0000000000..d8fddb3703 --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/fixed_hash.rb @@ -0,0 +1,74 @@ +# frozen_string_literal: true +# typed: true + +module T::Types + # Takes a hash of types. Validates each item in a hash using the type in the same position + # in the list. + class FixedHash < Base + attr_reader :types + + def initialize(types) + @types = types.transform_values {|v| T::Utils.coerce(v)} + end + + # overrides Base + def name + serialize_hash(@types) + end + + # overrides Base + def recursively_valid?(obj) + return false unless obj.is_a?(Hash) + return false if @types.any? {|key, type| !type.recursively_valid?(obj[key])} + return false if obj.any? {|key, _| !@types[key]} + true + end + + # overrides Base + def valid?(obj) + return false unless obj.is_a?(Hash) + return false if @types.any? {|key, type| !type.valid?(obj[key])} + return false if obj.any? {|key, _| !@types[key]} + true + end + + # overrides Base + private def subtype_of_single?(other) + case other + when FixedHash + # Using `subtype_of?` here instead of == would be unsound + @types == other.types + else + false + end + end + + # This gives us better errors, e.g.: + # `Expected {a: String}, got {a: TrueClass}` + # instead of + # `Expected {a: String}, got Hash`. + # + # overrides Base + def describe_obj(obj) + if obj.is_a?(Hash) + "type #{serialize_hash(obj.transform_values(&:class))}" + else + super + end + end + + private + + def serialize_hash(hash) + entries = hash.map do |(k, v)| + if Symbol === k && ":#{k}" == k.inspect + "#{k}: #{v}" + else + "#{k.inspect} => #{v}" + end + end + + "{#{entries.join(', ')}}" + end + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/intersection.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/intersection.rb new file mode 100644 index 0000000000..8e4b42f187 --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/intersection.rb @@ -0,0 +1,42 @@ +# frozen_string_literal: true +# typed: true + +module T::Types + # Takes a list of types. Validates that an object matches all of the types. + class Intersection < Base + attr_reader :types + + def initialize(types) + @types = types.flat_map do |type| + type = T::Utils.resolve_alias(type) + if type.is_a?(Intersection) + # Simplify nested intersections (mostly so `name` returns a nicer value) + type.types + else + T::Utils.coerce(type) + end + end.uniq + end + + # overrides Base + def name + "T.all(#{@types.map(&:name).sort.join(', ')})" + end + + # overrides Base + def recursively_valid?(obj) + @types.all? {|type| type.recursively_valid?(obj)} + end + + # overrides Base + def valid?(obj) + @types.all? {|type| type.valid?(obj)} + end + + # overrides Base + private def subtype_of_single?(other) + raise "This should never be reached if you're going through `subtype_of?` (and you should be)" + end + + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/noreturn.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/noreturn.rb new file mode 100644 index 0000000000..c285797480 --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/noreturn.rb @@ -0,0 +1,29 @@ +# frozen_string_literal: true +# typed: true + +module T::Types + # The bottom type + class NoReturn < Base + + def initialize; end + + # overrides Base + def name + "T.noreturn" + end + + # overrides Base + def valid?(obj) + false + end + + # overrides Base + private def subtype_of_single?(other) + true + end + + module Private + INSTANCE = NoReturn.new.freeze + end + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/proc.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/proc.rb new file mode 100644 index 0000000000..aece6a3a2f --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/proc.rb @@ -0,0 +1,51 @@ +# frozen_string_literal: true +# typed: true + +module T::Types + # Defines the type of a proc (a ruby callable). At runtime, only + # validates that the value is a `::Proc`. + # + # At present, we only support fixed-arity procs with no optional or + # keyword arguments. + class Proc < Base + attr_reader :arg_types + attr_reader :returns + + def initialize(arg_types, returns) + @arg_types = {} + arg_types.each do |key, raw_type| + @arg_types[key] = T::Utils.coerce(raw_type) + end + @returns = T::Utils.coerce(returns) + end + + # overrides Base + def name + args = [] + @arg_types.each do |k, v| + args << "#{k}: #{v.name}" + end + "T.proc.params(#{args.join(', ')}).returns(#{returns})" + end + + # overrides Base + def valid?(obj) + obj.is_a?(::Proc) + end + + # overrides Base + private def subtype_of_single?(other) + case other + when self.class + if arg_types.size != other.arg_types.size + return false + end + arg_types.values.zip(other.arg_types.values).all? do |a, b| + b.subtype_of?(a) + end && returns.subtype_of?(other.returns) + else + false + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/self_type.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/self_type.rb new file mode 100644 index 0000000000..e431a3e0f9 --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/self_type.rb @@ -0,0 +1,35 @@ +# frozen_string_literal: true +# typed: true + +module T::Types + # Modeling self-types properly at runtime would require additional tracking, + # so at runtime we permit all values and rely on the static checker. + class SelfType < Base + + def initialize(); end + + # overrides Base + def name + "T.self_type" + end + + # overrides Base + def valid?(obj) + true + end + + # overrides Base + private def subtype_of_single?(other) + case other + when SelfType + true + else + false + end + end + + module Private + INSTANCE = SelfType.new.freeze + end + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/simple.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/simple.rb new file mode 100644 index 0000000000..2789adbb67 --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/simple.rb @@ -0,0 +1,94 @@ +# frozen_string_literal: true +# typed: true + +module T::Types + # Validates that an object belongs to the specified class. + class Simple < Base + attr_reader :raw_type + + def initialize(raw_type) + @raw_type = raw_type + end + + # overrides Base + def name + # Memoize to mitigate pathological performance with anonymous modules (https://bugs.ruby-lang.org/issues/11119) + # + # `name` isn't normally a hot path for types, but it is used in initializing a T::Types::Union, + # and so in `T.nilable`, and so in runtime constructions like `x = T.let(nil, T.nilable(Integer))`. + @name ||= @raw_type.name.freeze + end + + # overrides Base + def valid?(obj) + obj.is_a?(@raw_type) + end + + # overrides Base + private def subtype_of_single?(other) + case other + when Simple + @raw_type <= other.raw_type + else + false + end + end + + # overrides Base + private def error_message(obj) + error_message = super(obj) + actual_name = obj.class.name + + return error_message unless name == actual_name + + <<~MSG.strip + #{error_message} + + The expected type and received object type have the same name but refer to different constants. + Expected type is #{name} with object id #{@raw_type.__id__}, but received type is #{actual_name} with object id #{obj.class.__id__}. + + There might be a constant reloading problem in your application. + MSG + end + + def to_nilable + @nilable ||= T::Types::Union.new([self, T::Utils::Nilable::NIL_TYPE]) + end + + module Private + module Pool + @cache = ObjectSpace::WeakMap.new + + def self.type_for_module(mod) + cached = @cache[mod] + return cached if cached + + type = if mod == ::Array + T::Array[T.untyped] + elsif mod == ::Hash + T::Hash[T.untyped, T.untyped] + elsif mod == ::Enumerable + T::Enumerable[T.untyped] + elsif mod == ::Enumerator + T::Enumerator[T.untyped] + elsif mod == ::Range + T::Range[T.untyped] + elsif !Object.autoload?(:Set) && Object.const_defined?(:Set) && mod == ::Set + T::Set[T.untyped] + else + Simple.new(mod) + end + + # Unfortunately, we still need to check if the module is frozen, + # since WeakMap adds a finalizer to the key that is added + # to the map, so that it can clear the map entry when the key is + # garbage collected. + # For a frozen object, though, adding a finalizer is not a valid + # operation, so this still raises if `mod` is frozen. + @cache[mod] = type unless mod.frozen? + type + end + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/t_enum.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/t_enum.rb new file mode 100644 index 0000000000..121368c7b6 --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/t_enum.rb @@ -0,0 +1,38 @@ +# frozen_string_literal: true +# typed: true + +module T::Types + # Validates that an object is equal to another T::Enum singleton value. + class TEnum < Base + attr_reader :val + + def initialize(val) + @val = val + end + + # overrides Base + def name + # Strips the #<...> off, just leaving the ... + # Reasoning: the user will have written something like + # T.any(MyEnum::A, MyEnum::B) + # in the type, so we should print what they wrote in errors, not: + # T.any(#, #) + @val.inspect[2..-2] + end + + # overrides Base + def valid?(obj) + @val == obj + end + + # overrides Base + private def subtype_of_single?(other) + case other + when TEnum + @val == other.val + else + false + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/type_member.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/type_member.rb new file mode 100644 index 0000000000..fadd2a7eea --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/type_member.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true +# typed: strict + +module T::Types + class TypeMember < TypeVariable + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/type_parameter.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/type_parameter.rb new file mode 100644 index 0000000000..ea82a07cc3 --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/type_parameter.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true +# typed: true + +module T::Types + class TypeParameter < Base + def initialize(name) + raise ArgumentError.new("not a symbol: #{name}") unless name.is_a?(Symbol) + @name = name + end + + def valid?(obj) + true + end + + def subtype_of_single?(type) + true + end + + def name + "T.type_parameter(:#{@name})" + end + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/type_template.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/type_template.rb new file mode 100644 index 0000000000..8c83de8949 --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/type_template.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true +# typed: strict + +module T::Types + class TypeTemplate < TypeVariable + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/type_variable.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/type_variable.rb new file mode 100644 index 0000000000..187119167d --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/type_variable.rb @@ -0,0 +1,34 @@ +# frozen_string_literal: true +# typed: true + +module T::Types + # Since we do type erasure at runtime, this just validates the variance and + # provides some syntax for the static type checker + class TypeVariable < Base + attr_reader :variance + + VALID_VARIANCES = %i[in out invariant].freeze + + def initialize(variance) + case variance + when Hash then raise ArgumentError.new("Pass bounds using a block. Got: #{variance}") + when *VALID_VARIANCES then nil + else + raise TypeError.new("invalid variance #{variance}") + end + @variance = variance + end + + def valid?(obj) + true + end + + def subtype_of_single?(type) + true + end + + def name + Untyped.new.name + end + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/typed_array.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/typed_array.rb new file mode 100644 index 0000000000..0b5f3541a9 --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/typed_array.rb @@ -0,0 +1,39 @@ +# frozen_string_literal: true +# typed: true + +module T::Types + class TypedArray < TypedEnumerable + # overrides Base + def name + "T::Array[#{@type.name}]" + end + + def underlying_class + Array + end + + # overrides Base + def recursively_valid?(obj) + obj.is_a?(Array) && super + end + + # overrides Base + def valid?(obj) + obj.is_a?(Array) + end + + def new(*args) + Array.new(*T.unsafe(args)) + end + + class Untyped < TypedArray + def initialize + super(T.untyped) + end + + def valid?(obj) + obj.is_a?(Array) + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/typed_enumerable.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/typed_enumerable.rb new file mode 100644 index 0000000000..65c2631f0a --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/typed_enumerable.rb @@ -0,0 +1,176 @@ +# frozen_string_literal: true +# typed: true + +module T::Types + # Note: All subclasses of Enumerable should add themselves to the + # `case` statement below in `describe_obj` in order to get better + # error messages. + class TypedEnumerable < Base + attr_reader :type + + def initialize(type) + @type = T::Utils.coerce(type) + end + + def underlying_class + Enumerable + end + + # overrides Base + def name + "T::Enumerable[#{@type.name}]" + end + + # overrides Base + def valid?(obj) + obj.is_a?(Enumerable) + end + + # overrides Base + def recursively_valid?(obj) + return false unless obj.is_a?(Enumerable) + case obj + when Array + begin + it = 0 + while it < obj.count + return false unless @type.recursively_valid?(obj[it]) + it += 1 + end + true + end + when Hash + return false unless @type.is_a?(FixedArray) + types = @type.types + return false if types.count != 2 + key_type = types[0] + value_type = types[1] + obj.each_pair do |key, val| + # Some objects (I'm looking at you Rack::Utils::HeaderHash) don't + # iterate over a [key, value] array, so we can't juse use the @type.recursively_valid?(v) + return false if !key_type.recursively_valid?(key) || !value_type.recursively_valid?(val) + end + true + when Enumerator::Lazy + # Enumerators can be unbounded: see `[:foo, :bar].cycle` + true + when Enumerator + # Enumerators can be unbounded: see `[:foo, :bar].cycle` + true + when Range + # A nil beginning or a nil end does not provide any type information. That is, nil in a range represents + # boundlessness, it does not express a type. For example `(nil...nil)` is not a T::Range[NilClass], its a range + # of unknown types (T::Range[T.untyped]). + # Similarly, `(nil...1)` is not a `T::Range[T.nilable(Integer)]`, it's a boundless range of Integer. + (obj.begin.nil? || @type.recursively_valid?(obj.begin)) && (obj.end.nil? || @type.recursively_valid?(obj.end)) + when Set + obj.each do |item| + return false unless @type.recursively_valid?(item) + end + + true + else + # We don't check the enumerable since it isn't guaranteed to be + # rewindable (e.g. STDIN) and it may be expensive to enumerate + # (e.g. an enumerator that makes an HTTP request)" + true + end + end + + # overrides Base + private def subtype_of_single?(other) + if other.class <= TypedEnumerable && + underlying_class <= other.underlying_class + # Enumerables are covariant because they are read only + # + # Properly speaking, many Enumerable subtypes (e.g. Set) + # should be invariant because they are mutable and support + # both reading and writing. However, Sorbet treats *all* + # Enumerable subclasses as covariant for ease of adoption. + @type.subtype_of?(other.type) + else + false + end + end + + # overrides Base + def describe_obj(obj) + return super unless obj.is_a?(Enumerable) + type_from_instance(obj).name + end + + private def type_from_instances(objs) + return objs.class unless objs.is_a?(Enumerable) + obtained_types = [] + begin + objs.each do |x| + obtained_types << type_from_instance(x) + end + rescue + return T.untyped # all we can do is go with the types we have so far + end + if obtained_types.count > 1 + # Multiple kinds of bad types showed up, we'll suggest a union + # type you might want. + Union.new(obtained_types) + elsif obtained_types.empty? + T.noreturn + else + # Everything was the same bad type, lets just show that + obtained_types.first + end + end + + private def type_from_instance(obj) + if [true, false].include?(obj) + return T::Boolean + elsif !obj.is_a?(Enumerable) + return obj.class + end + + case obj + when Array + T::Array[type_from_instances(obj)] + when Hash + inferred_key = type_from_instances(obj.keys) + inferred_val = type_from_instances(obj.values) + T::Hash[inferred_key, inferred_val] + when Range + # We can't get any information from `NilClass` in ranges (since nil is used to represent boundlessness). + typeable_objects = [obj.begin, obj.end].compact + if typeable_objects.empty? + T::Range[T.untyped] + else + T::Range[type_from_instances(typeable_objects)] + end + when Enumerator::Lazy + T::Enumerator::Lazy[type_from_instances(obj)] + when Enumerator + T::Enumerator[type_from_instances(obj)] + when Set + T::Set[type_from_instances(obj)] + when IO + # Short circuit for anything IO-like (File, etc.). In these cases, + # enumerating the object is a destructive operation and might hang. + obj.class + else + # This is a specialized enumerable type, just return the class. + if T::Configuration::AT_LEAST_RUBY_2_7 + Object.instance_method(:class).bind_call(obj) + else + Object.instance_method(:class).bind(obj).call + end + end + end + + class Untyped < TypedEnumerable + def initialize + super(T.untyped) + end + + def valid?(obj) + obj.is_a?(Enumerable) + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/typed_enumerator.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/typed_enumerator.rb new file mode 100644 index 0000000000..e79341eb94 --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/typed_enumerator.rb @@ -0,0 +1,41 @@ +# frozen_string_literal: true +# typed: true + +module T::Types + class TypedEnumerator < TypedEnumerable + attr_reader :type + + def underlying_class + Enumerator + end + + # overrides Base + def name + "T::Enumerator[#{@type.name}]" + end + + # overrides Base + def recursively_valid?(obj) + obj.is_a?(Enumerator) && super + end + + # overrides Base + def valid?(obj) + obj.is_a?(Enumerator) + end + + def new(*args, &blk) + T.unsafe(Enumerator).new(*args, &blk) + end + + class Untyped < TypedEnumerator + def initialize + super(T.untyped) + end + + def valid?(obj) + obj.is_a?(Enumerator) + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/typed_enumerator_lazy.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/typed_enumerator_lazy.rb new file mode 100644 index 0000000000..3569be398a --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/typed_enumerator_lazy.rb @@ -0,0 +1,41 @@ +# frozen_string_literal: true +# typed: true + +module T::Types + class TypedEnumeratorLazy < TypedEnumerable + attr_reader :type + + def underlying_class + Enumerator::Lazy + end + + # overrides Base + def name + "T::Enumerator::Lazy[#{@type.name}]" + end + + # overrides Base + def recursively_valid?(obj) + obj.is_a?(Enumerator::Lazy) && super + end + + # overrides Base + def valid?(obj) + obj.is_a?(Enumerator::Lazy) + end + + def new(*args, &blk) + T.unsafe(Enumerator::Lazy).new(*args, &blk) + end + + class Untyped < TypedEnumeratorLazy + def initialize + super(T.untyped) + end + + def valid?(obj) + obj.is_a?(Enumerator::Lazy) + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/typed_hash.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/typed_hash.rb new file mode 100644 index 0000000000..f48e0c1595 --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/typed_hash.rb @@ -0,0 +1,48 @@ +# frozen_string_literal: true +# typed: true + +module T::Types + class TypedHash < TypedEnumerable + # Technically we don't need these, but they are a nice api + attr_reader :keys, :values + + def underlying_class + Hash + end + + def initialize(keys:, values:) + @keys = T::Utils.coerce(keys) + @values = T::Utils.coerce(values) + @type = T::Utils.coerce([keys, values]) + end + + # overrides Base + def name + "T::Hash[#{@keys.name}, #{@values.name}]" + end + + # overrides Base + def recursively_valid?(obj) + obj.is_a?(Hash) && super + end + + # overrides Base + def valid?(obj) + obj.is_a?(Hash) + end + + def new(*args, &blk) + Hash.new(*T.unsafe(args), &blk) + end + + class Untyped < TypedHash + def initialize + super(keys: T.untyped, values: T.untyped) + end + + def valid?(obj) + obj.is_a?(Hash) + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/typed_range.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/typed_range.rb new file mode 100644 index 0000000000..50e2ef9d53 --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/typed_range.rb @@ -0,0 +1,31 @@ +# frozen_string_literal: true +# typed: true + +module T::Types + class TypedRange < TypedEnumerable + attr_reader :type + + def underlying_class + Hash + end + + # overrides Base + def name + "T::Range[#{@type.name}]" + end + + # overrides Base + def recursively_valid?(obj) + obj.is_a?(Range) && super + end + + # overrides Base + def valid?(obj) + obj.is_a?(Range) + end + + def new(*args) + T.unsafe(Range).new(*args) + end + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/typed_set.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/typed_set.rb new file mode 100644 index 0000000000..8c1b2caee3 --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/typed_set.rb @@ -0,0 +1,53 @@ +# frozen_string_literal: true +# typed: true + +module T::Types + class TypedSet < TypedEnumerable + attr_reader :type + + def underlying_class + Hash + end + + # overrides Base + def name + "T::Set[#{@type.name}]" + end + + # overrides Base + def recursively_valid?(obj) + # Re-implements non_forcing_is_a? + return false if Object.autoload?(:Set) # Set is meant to be autoloaded but not yet loaded, this value can't be a Set + return false unless Object.const_defined?(:Set) # Set is not loaded yet + obj.is_a?(Set) && super + end + + # overrides Base + def valid?(obj) + # Re-implements non_forcing_is_a? + return false if Object.autoload?(:Set) # Set is meant to be autoloaded but not yet loaded, this value can't be a Set + return false unless Object.const_defined?(:Set) # Set is not loaded yet + obj.is_a?(Set) + end + + def new(*args) + # Fine for this to blow up, because hopefully if they're trying to make a + # Set, they don't mind putting (or already have put) a `require 'set'` in + # their program directly. + Set.new(*T.unsafe(args)) + end + + class Untyped < TypedSet + def initialize + super(T.untyped) + end + + def valid?(obj) + # Re-implements non_forcing_is_a? + return false if Object.autoload?(:Set) # Set is meant to be autoloaded but not yet loaded, this value can't be a Set + return false unless Object.const_defined?(:Set) # Set is not loaded yet + obj.is_a?(Set) + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/union.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/union.rb new file mode 100644 index 0000000000..3729dc48de --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/union.rb @@ -0,0 +1,91 @@ +# frozen_string_literal: true +# typed: true + +module T::Types + # Takes a list of types. Validates that an object matches at least one of the types. + class Union < Base + attr_reader :types + + def initialize(types) + @types = types.flat_map do |type| + type = T::Utils.coerce(type) + if type.is_a?(Union) + # Simplify nested unions (mostly so `name` returns a nicer value) + type.types + else + type + end + end.uniq + end + + # overrides Base + def name + type_shortcuts(@types) + end + + private def type_shortcuts(types) + if types.size == 1 + return types[0].name + end + nilable = T::Utils.coerce(NilClass) + trueclass = T::Utils.coerce(TrueClass) + falseclass = T::Utils.coerce(FalseClass) + if types.any? {|t| t == nilable} + remaining_types = types.reject {|t| t == nilable} + "T.nilable(#{type_shortcuts(remaining_types)})" + elsif types.any? {|t| t == trueclass} && types.any? {|t| t == falseclass} + remaining_types = types.reject {|t| t == trueclass || t == falseclass} + type_shortcuts([T::Private::Types::StringHolder.new("T::Boolean")] + remaining_types) + else + names = types.map(&:name).compact.sort + "T.any(#{names.join(', ')})" + end + end + + # overrides Base + def recursively_valid?(obj) + @types.any? {|type| type.recursively_valid?(obj)} + end + + # overrides Base + def valid?(obj) + @types.any? {|type| type.valid?(obj)} + end + + # overrides Base + private def subtype_of_single?(other) + raise "This should never be reached if you're going through `subtype_of?` (and you should be)" + end + + module Private + module Pool + EMPTY_ARRAY = [].freeze + private_constant :EMPTY_ARRAY + + # @param type_a [T::Types::Base] + # @param type_b [T::Types::Base] + # @param types [Array] optional array of additional T::Types::Base instances + def self.union_of_types(type_a, type_b, types=EMPTY_ARRAY) + if types.empty? + # We aren't guaranteed to detect a simple `T.nilable()` type here + # in cases where there are duplicate types, nested unions, etc. + # + # That's ok, because this is an optimization which isn't necessary for + # correctness. + if type_b == T::Utils::Nilable::NIL_TYPE && type_a.is_a?(T::Types::Simple) + type_a.to_nilable + elsif type_a == T::Utils::Nilable::NIL_TYPE && type_b.is_a?(T::Types::Simple) + type_b.to_nilable + else + Union.new([type_a, type_b]) + end + else + # This can't be a `T.nilable()` case unless there are duplicates, + # which is possible but unexpected. + Union.new([type_a, type_b] + types) + end + end + end + end + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/untyped.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/untyped.rb new file mode 100644 index 0000000000..a06a633d42 --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/untyped.rb @@ -0,0 +1,29 @@ +# frozen_string_literal: true +# typed: true + +module T::Types + # A dynamic type, which permits whatever + class Untyped < Base + + def initialize; end + + # overrides Base + def name + "T.untyped" + end + + # overrides Base + def valid?(obj) + true + end + + # overrides Base + private def subtype_of_single?(other) + true + end + + module Private + INSTANCE = Untyped.new.freeze + end + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/utils.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/utils.rb new file mode 100644 index 0000000000..7897eaa38f --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/utils.rb @@ -0,0 +1,209 @@ +# frozen_string_literal: true +# typed: true + +module T::Utils + # Used to convert from a type specification to a `T::Types::Base`. + def self.coerce(val) + if val.is_a?(T::Private::Types::TypeAlias) + val.aliased_type + elsif val.is_a?(T::Types::Base) + val + elsif val.is_a?(Module) + T::Types::Simple::Private::Pool.type_for_module(val) + elsif val.is_a?(::Array) + T::Types::FixedArray.new(val) + elsif val.is_a?(::Hash) + T::Types::FixedHash.new(val) + elsif val.is_a?(T::Private::Methods::DeclBuilder) + T::Private::Methods.finalize_proc(val.decl) + elsif val.is_a?(::T::Enum) + T::Types::TEnum.new(val) + elsif val.is_a?(::String) + raise "Invalid String literal for type constraint. Must be an #{T::Types::Base}, a " \ + "class/module, or an array. Got a String with value `#{val}`." + else + raise "Invalid value for type constraint. Must be an #{T::Types::Base}, a " \ + "class/module, or an array. Got a `#{val.class}`." + end + end + + # Dynamically confirm that `value` is recursively a valid value of + # type `type`, including recursively through collections. Note that + # in some cases this runtime check can be very expensive, especially + # with large collections of objects. + def self.check_type_recursive!(value, type) + T::Private::Casts.cast_recursive(value, type, cast_method: "T.check_type_recursive!") + end + + # Returns the set of all methods (public, protected, private) defined on a module or its + # ancestors, excluding Object and its ancestors. Overrides of methods from Object (and its + # ancestors) are included. + def self.methods_excluding_object(mod) + # We can't just do mod.instance_methods - Object.instance_methods, because that would leave out + # any methods from Object that are overridden in mod. + mod.ancestors.flat_map do |ancestor| + # equivalent to checking Object.ancestors.include?(ancestor) + next [] if Object <= ancestor + ancestor.instance_methods(false) + ancestor.private_instance_methods(false) + end.uniq + end + + # Returns the signature for the `UnboundMethod`, or nil if it's not sig'd + # + # @example T::Utils.signature_for_method(x.method(:foo)) + def self.signature_for_method(method) + T::Private::Methods.signature_for_method(method) + end + + # Returns the signature for the instance method on the supplied module, or nil if it's not found or not typed. + # + # @example T::Utils.signature_for_instance_method(MyClass, :my_method) + def self.signature_for_instance_method(mod, method_name) + T::Private::Methods.signature_for_method(mod.instance_method(method_name)) + end + + def self.wrap_method_with_call_validation_if_needed(mod, method_sig, original_method) + T::Private::Methods::CallValidation.wrap_method_if_needed(mod, method_sig, original_method) + end + + # Unwraps all the sigs. + def self.run_all_sig_blocks + T::Private::Methods.run_all_sig_blocks + end + + # Return the underlying type for a type alias. Otherwise returns type. + def self.resolve_alias(type) + case type + when T::Private::Types::TypeAlias + type.aliased_type + else + type + end + end + + # Give a type which is a subclass of T::Types::Base, determines if the type is a simple nilable type (union of NilClass and something else). + # If so, returns the T::Types::Base of the something else. Otherwise, returns nil. + def self.unwrap_nilable(type) + case type + when T::Types::Union + non_nil_types = type.types.reject {|t| t == Nilable::NIL_TYPE} + return nil if type.types.length == non_nil_types.length + case non_nil_types.length + when 0 then nil + when 1 then non_nil_types.first + else + T::Types::Union::Private::Pool.union_of_types(non_nil_types[0], non_nil_types[1], non_nil_types[2..-1]) + end + else + nil + end + end + + # Returns the arity of a method, unwrapping the sig if needed + def self.arity(method) + arity = method.arity + return arity if arity != -1 || method.is_a?(Proc) + sig = T::Private::Methods.signature_for_method(method) + sig ? sig.method.arity : arity + end + + # Elide the middle of a string as needed and replace it with an ellipsis. + # Keep the given number of characters at the start and end of the string. + # + # This method operates on string length, not byte length. + # + # If the string is shorter than the requested truncation length, return it + # without adding an ellipsis. This method may return a longer string than + # the original if the characters removed are shorter than the ellipsis. + # + # @param [String] str + # + # @param [Fixnum] start_len The length of string before the ellipsis + # @param [Fixnum] end_len The length of string after the ellipsis + # + # @param [String] ellipsis The string to add in place of the elided text + # + # @return [String] + # + def self.string_truncate_middle(str, start_len, end_len, ellipsis='...') + return unless str + + raise ArgumentError.new('must provide start_len') unless start_len + raise ArgumentError.new('must provide end_len') unless end_len + + raise ArgumentError.new('start_len must be >= 0') if start_len < 0 + raise ArgumentError.new('end_len must be >= 0') if end_len < 0 + + str = str.to_s + return str if str.length <= start_len + end_len + + start_part = str[0...start_len - ellipsis.length] + end_part = end_len == 0 ? '' : str[-end_len..-1] + + "#{start_part}#{ellipsis}#{end_part}" + end + + def self.lift_enum(enum) + unless enum.is_a?(T::Types::Enum) + raise ArgumentError.new("#{enum.inspect} is not a T.deprecated_enum") + end + + classes = enum.values.map(&:class).uniq + if classes.empty? + T.untyped + elsif classes.length > 1 + T::Types::Union.new(classes) + else + T::Types::Simple::Private::Pool.type_for_module(classes.first) + end + end + + module Nilable + # :is_union_type, T::Boolean: whether the type is an T::Types::Union type + # :non_nilable_type, Class: if it is an T.nilable type, the corresponding underlying type; otherwise, nil. + TypeInfo = Struct.new(:is_union_type, :non_nilable_type) + + NIL_TYPE = T::Utils.coerce(NilClass) + + def self.get_type_info(prop_type) + if prop_type.is_a?(T::Types::Union) + non_nilable_type = T::Utils.unwrap_nilable(prop_type) + if non_nilable_type&.is_a?(T::Types::Simple) + non_nilable_type = non_nilable_type.raw_type + end + TypeInfo.new(true, non_nilable_type) + else + TypeInfo.new(false, nil) + end + end + + # Get the underlying type inside prop_type: + # - if the type is A, the function returns A + # - if the type is T.nilable(A), the function returns A + def self.get_underlying_type(prop_type) + type_info = get_type_info(prop_type) + if type_info.is_union_type + type_info.non_nilable_type || prop_type + elsif prop_type.is_a?(T::Types::Simple) + prop_type.raw_type + else + prop_type + end + end + + # The difference between this function and the above function is that the Sorbet type, like T::Types::Simple + # is preserved. + def self.get_underlying_type_object(prop_type) + T::Utils.unwrap_nilable(prop_type) || prop_type + end + + def self.is_union_with_nilclass(prop_type) + case prop_type + when T::Types::Union + prop_type.types.include?(NIL_TYPE) + else + false + end + end + end +end From bc687c63587684b2cd2db1dd470c646e9f265931 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Sun, 24 Jul 2022 15:47:15 +0200 Subject: [PATCH 017/138] Added check `resources_only` --- Library/Homebrew/dev-cmd/livecheck.rb | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Library/Homebrew/dev-cmd/livecheck.rb b/Library/Homebrew/dev-cmd/livecheck.rb index 6c55f7e8d3..de7a343b9d 100644 --- a/Library/Homebrew/dev-cmd/livecheck.rb +++ b/Library/Homebrew/dev-cmd/livecheck.rb @@ -70,7 +70,8 @@ module Homebrew casks = args.formula? ? [] : Cask::Caskroom.casks formulae + casks elsif args.resources? - formula_with_resources = Formula.all.select { |formula| formula.resources.any? } + # formula_with_resources = Formula.all.select { |formula| formula.resources.any? } + formula_with_resources = Formula.all.select { |formula| formula.resources.any? { |resource| resource.livecheckable? } } formula_with_resources elsif args.all? formulae = args.cask? ? [] : Formula.all @@ -114,12 +115,13 @@ module Homebrew json: args.json?, full_name: args.full_name?, handle_name_conflict: !args.formula? && !args.cask?, + resources_only: args.resources?, newer_only: args.newer_only?, quiet: args.quiet?, debug: args.debug?, verbose: args.verbose?, }.compact - Livecheck.run_checks(package_and_resource_to_check[1..3], **options) + Livecheck.run_checks(package_and_resource_to_check, **options) end end From f4a42d7d6668878cedf124124bd4d098bd874c13 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Sun, 24 Jul 2022 15:47:40 +0200 Subject: [PATCH 018/138] Added method `resource_version` to check for resources --- Library/Homebrew/livecheck/livecheck.rb | 313 +++++++++++++++++++++--- 1 file changed, 279 insertions(+), 34 deletions(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index 50f4229385..854666816d 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -159,19 +159,20 @@ module Homebrew # `formulae_and_casks_to_check` array and prints the results. sig { params( - formulae_and_casks_to_check: T::Array[T.any(Formula, Cask::Cask, Resource)], - full_name: T::Boolean, - handle_name_conflict: T::Boolean, - json: T::Boolean, - newer_only: T::Boolean, - debug: T::Boolean, - quiet: T::Boolean, - verbose: T::Boolean, + formulae_and_casks_to_check: T::Array[T.any(Formula, Cask::Cask)], + full_name: T::Boolean, + handle_name_conflict: T::Boolean, + resources_only: T::Boolean, + json: T::Boolean, + newer_only: T::Boolean, + debug: T::Boolean, + quiet: T::Boolean, + verbose: T::Boolean, ).void } def run_checks( formulae_and_casks_to_check, - full_name: false, handle_name_conflict: false, json: false, newer_only: false, + full_name: false, handle_name_conflict: false, resources_only: false, json: false, newer_only: false, debug: false, quiet: false, verbose: false ) load_other_tap_strategies(formulae_and_casks_to_check) @@ -253,6 +254,9 @@ module Homebrew formula&.head&.downloader&.shutup! + # Check resources if "--resources" flag was given + + # Use the `stable` version for comparison except for installed # head-only formulae. A formula with `stable` and `head` that's # installed using `--head` will still use the `stable` version for @@ -267,18 +271,33 @@ module Homebrew Version.new(formula_or_cask.version) end + p "Formula: #{formula_or_cask_name(formula_or_cask, full_name: use_full_name)}" + p "Current: #{current.to_s}" + current_str = current.to_s current = LivecheckVersion.create(formula_or_cask, current) latest = if formula&.head_only? formula.head.downloader.fetch_last_commit 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 - ) + if resources_only + version_info = resource_version( + formula_or_cask, + referenced_formula: referenced_formula_or_cask, + livecheck_references: livecheck_references, + json: json, + full_name: use_full_name, + verbose: verbose, + debug: debug + ) + 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 + ) + end version_info[:latest] if version_info.present? end @@ -368,13 +387,15 @@ module Homebrew puts JSON.pretty_generate(formulae_checked.compact) end - sig { params(formula_or_cask: T.any(Formula, Cask::Cask), full_name: T::Boolean).returns(String) } + sig { params(formula_or_cask: T.any(Formula, Cask::Cask, Resource), full_name: T::Boolean).returns(String) } def formula_or_cask_name(formula_or_cask, full_name: false) case formula_or_cask when Formula formula_name(formula_or_cask, full_name: full_name) when Cask::Cask cask_name(formula_or_cask, full_name: full_name) + when Resource + resource_name(formula_or_cask, full_name: full_name) else T.absurd(formula_or_cask) end @@ -394,6 +415,13 @@ module Homebrew full_name ? formula.full_name : formula.name end + # Returns the fully-qualified name of a resource if the `full_name` argument is + # provided; returns the name otherwise. + sig { params(resource: Resource, full_name: T::Boolean).returns(String) } + def resource_name(resource, full_name: false) + full_name ? resource.full_name : resource.name + end + sig { params( formula_or_cask: T.any(Formula, Cask::Cask), @@ -449,41 +477,48 @@ module Homebrew sig { params( livecheck_url: T.any(String, Symbol), - formula_or_cask: T.any(Formula, Cask::Cask), + package_or_resource: T.any(Formula, Cask::Cask, Resource), ).returns(T.nilable(String)) } - def livecheck_url_to_string(livecheck_url, formula_or_cask) + def livecheck_url_to_string(livecheck_url, package_or_resource) case livecheck_url when String livecheck_url when :url - formula_or_cask.url&.to_s if formula_or_cask.is_a?(Cask::Cask) + package_or_resource.url&.to_s if package_or_resource.is_a?(Cask::Cask) when :head, :stable - formula_or_cask.send(livecheck_url)&.url if formula_or_cask.is_a?(Formula) + package_or_resource.send(livecheck_url)&.url if package_or_resource.is_a?(Formula) || package_or_resource.is_a?(Resource) when :homepage - formula_or_cask.homepage + package_or_resource.homepage end end # Returns an Array containing the formula/cask URLs that can be used by livecheck. - sig { params(formula_or_cask: T.any(Formula, Cask::Cask)).returns(T::Array[String]) } - def checkable_urls(formula_or_cask) + sig { params(package_or_resource: T.any(Formula, Cask::Cask, Resource)).returns(T::Array[String]) } + def checkable_urls(package_or_resource) urls = [] - case formula_or_cask - when Formula - if formula_or_cask.stable - urls << formula_or_cask.stable.url - urls.concat(formula_or_cask.stable.mirrors) + case package_or_resource + when Resource + if package_or_resource.stable + urls << package_or_resource.stable.url + urls.concat(package_or_resource.stable.mirrors) end - urls << formula_or_cask.head.url if formula_or_cask.head - urls << formula_or_cask.homepage if formula_or_cask.homepage + urls << package_or_resource.head.url if package_or_resource.head + urls << package_or_resource.homepage if package_or_resource.homepage + when Formula + if package_or_resource.stable + urls << package_or_resource.stable.url + urls.concat(package_or_resource.stable.mirrors) + end + urls << package_or_resource.head.url if package_or_resource.head + urls << package_or_resource.homepage if package_or_resource.homepage when Cask::Cask - urls << formula_or_cask.appcast.to_s if formula_or_cask.appcast - urls << formula_or_cask.url.to_s if formula_or_cask.url - urls << formula_or_cask.homepage if formula_or_cask.homepage + urls << package_or_resource.appcast.to_s if package_or_resource.appcast + urls << package_or_resource.url.to_s if package_or_resource.url + urls << package_or_resource.homepage if package_or_resource.homepage else - T.absurd(formula_or_cask) + T.absurd(package_or_resource) end urls.compact.uniq @@ -561,6 +596,216 @@ module Homebrew homebrew_curl_root_domains.include?(url_root_domain) end + #================================================================================== + + # Identifies the latest version of the resources and returns a Hash containing + # the version information. Returns nil if a latest version couldn't be found. + sig { + params( + formula_with_resources: T.any(Formula), + referenced_formula: T.nilable(T.any(Formula)), + livecheck_references: T::Array[T.any(Formula, Cask::Cask)], + json: T::Boolean, + full_name: T::Boolean, + verbose: T::Boolean, + debug: T::Boolean, + ).returns(T.nilable(Hash)) + } + def resource_version( + formula_with_resources, + referenced_formula: nil, + livecheck_references: [], + json: false, + full_name: false, + verbose: false, + debug: false + ) + formula_with_resources.resources.each_with_index do |resource, i| + has_livecheckable = resource.livecheckable? + + #@todo: for now, only check resources with livecheck block + if has_livecheckable + livecheck = resource.livecheck + # referenced_livecheck = referenced_formula_or_cask&.livecheck + livecheck_url = livecheck.url + livecheck_regex = livecheck.regex + livecheck_strategy = livecheck.strategy + livecheck_strategy_block = livecheck.strategy_block + + livecheck_url_string = livecheck_url_to_string( + livecheck_url, + resource, + ) + + urls = [livecheck_url_string] if livecheck_url_string + urls ||= checkable_urls(resource) + + end + + if debug + puts "Resource: #{resource_name(resource, full_name: full_name)}" + puts "Livecheckable?: #{has_livecheckable ? "Yes" : "No"}" + end + + end + + + + + + + # checked_urls = [] + # # rubocop:disable Metrics/BlockLength + # urls.each_with_index do |original_url, i| + # # Only preprocess the URL when it's appropriate + # url = if STRATEGY_SYMBOLS_TO_SKIP_PREPROCESS_URL.include?(livecheck_strategy) + # original_url + # else + # preprocess_url(original_url) + # end + # next if checked_urls.include?(url) + + # strategies = Strategy.from_url( + # url, + # livecheck_strategy: livecheck_strategy, + # url_provided: livecheck_url.present?, + # regex_provided: livecheck_regex.present?, + # block_provided: livecheck_strategy_block.present?, + # ) + # strategy = Strategy.from_symbol(livecheck_strategy) || strategies.first + # strategy_name = livecheck_strategy_names[strategy] + + # if debug + # puts + # if livecheck_url.is_a?(Symbol) + # # This assumes the URL symbol will fit within the available space + # puts "URL (#{livecheck_url}):".ljust(18, " ") + original_url + # else + # puts "URL: #{original_url}" + # end + # puts "URL (processed): #{url}" if url != original_url + # if strategies.present? && verbose + # puts "Strategies: #{strategies.map { |s| livecheck_strategy_names[s] }.join(", ")}" + # end + # puts "Strategy: #{strategy.blank? ? "None" : strategy_name}" + # puts "Regex: #{livecheck_regex.inspect}" if livecheck_regex.present? + # end + + # if livecheck_strategy.present? + # if livecheck_url.blank? && strategy.method(:find_versions).parameters.include?([:keyreq, :url]) + # odebug "#{strategy_name} strategy requires a URL" + # next + # elsif livecheck_strategy != :page_match && strategies.exclude?(strategy) + # odebug "#{strategy_name} strategy does not apply to this URL" + # next + # end + # end + + # next if strategy.blank? + + # homebrew_curl = case strategy_name + # when "PageMatch", "HeaderMatch" + # use_homebrew_curl?((referenced_formula_or_cask || formula_or_cask), url) + # end + # puts "Homebrew curl?: Yes" if debug && homebrew_curl.present? + + # strategy_data = strategy.find_versions( + # url: url, + # regex: livecheck_regex, + # homebrew_curl: homebrew_curl, + # cask: cask, + # &livecheck_strategy_block + # ) + # match_version_map = strategy_data[:matches] + # regex = strategy_data[:regex] + # messages = strategy_data[:messages] + # checked_urls << url + + # if messages.is_a?(Array) && match_version_map.blank? + # puts messages unless json + # next if i + 1 < urls.length + + # return status_hash(formula_or_cask, "error", messages, full_name: full_name, verbose: verbose) + # end + + # if debug + # if strategy_data[:url].present? && strategy_data[:url] != url + # puts "URL (strategy): #{strategy_data[:url]}" + # end + # puts "URL (final): #{strategy_data[:final_url]}" if strategy_data[:final_url].present? + # if strategy_data[:regex].present? && strategy_data[:regex] != livecheck_regex + # puts "Regex (strategy): #{strategy_data[:regex].inspect}" + # end + # puts "Cached?: Yes" if strategy_data[:cached] == true + # end + + # match_version_map.delete_if do |_match, version| + # next true if version.blank? + # next false if has_livecheckable + + # UNSTABLE_VERSION_KEYWORDS.any? do |rejection| + # version.to_s.include?(rejection) + # end + # end + + # next if match_version_map.blank? + + # if debug + # puts + # puts "Matched Versions:" + + # if verbose + # match_version_map.each do |match, version| + # puts "#{match} => #{version.inspect}" + # end + # else + # puts match_version_map.values.join(", ") + # end + # end + + # version_info = { + # latest: Version.new(match_version_map.values.max_by { |v| LivecheckVersion.create(formula_or_cask, v) }), + # } + + # if json && verbose + # version_info[:meta] = {} + + # if livecheck_references.present? + # 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) } + # when Cask::Cask + # { cask: cask_name(ref_formula_or_cask, full_name: full_name) } + # end + # end + # end + + # version_info[:meta][:url] = {} + # version_info[:meta][:url][:symbol] = livecheck_url if livecheck_url.is_a?(Symbol) && livecheck_url_string + # version_info[:meta][:url][:original] = original_url + # version_info[:meta][:url][:processed] = url if url != original_url + # if strategy_data[:url].present? && strategy_data[:url] != url + # version_info[:meta][:url][:strategy] = strategy_data[:url] + # end + # version_info[:meta][:url][:final] = strategy_data[:final_url] if strategy_data[:final_url] + # version_info[:meta][:url][:homebrew_curl] = homebrew_curl if homebrew_curl.present? + + # version_info[:meta][:strategy] = strategy.present? ? strategy_name : nil + # version_info[:meta][:strategies] = strategies.map { |s| livecheck_strategy_names[s] } if strategies.present? + # version_info[:meta][:regex] = regex.inspect if regex.present? + # version_info[:meta][:cached] = true if strategy_data[:cached] == true + # end + + # return version_info + # end + # rubocop:enable Metrics/BlockLength + + nil + end + + #================================================================================== + # Identifies the latest version of the formula and returns a Hash containing # the version information. Returns nil if a latest version couldn't be found. # rubocop:disable Metrics/CyclomaticComplexity From 1ee4f1a696e82d3f1c89313a4978ebce1a1d09b9 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Sun, 24 Jul 2022 17:39:07 +0200 Subject: [PATCH 019/138] Work in progress for extending livecheck command for resources --- Library/Homebrew/livecheck/livecheck.rb | 330 +++++++++++++----------- 1 file changed, 173 insertions(+), 157 deletions(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index 854666816d..13f3a435b8 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -485,9 +485,11 @@ module Homebrew when String livecheck_url when :url - package_or_resource.url&.to_s if package_or_resource.is_a?(Cask::Cask) + package_or_resource.url&.to_s if package_or_resource.is_a?(Cask::Cask) || package_or_resource.is_a?(Resource) when :head, :stable - package_or_resource.send(livecheck_url)&.url if package_or_resource.is_a?(Formula) || package_or_resource.is_a?(Resource) + # Not sure how to handle this ? + # Do I have to add :stable / :head in Resources' as well (like it's being implemented in Formula ?) + package_or_resource.send(livecheck_url)&.url if package_or_resource.is_a?(Formula) when :homepage package_or_resource.homepage end @@ -500,12 +502,7 @@ module Homebrew case package_or_resource when Resource - if package_or_resource.stable - urls << package_or_resource.stable.url - urls.concat(package_or_resource.stable.mirrors) - end - urls << package_or_resource.head.url if package_or_resource.head - urls << package_or_resource.homepage if package_or_resource.homepage + urls << package_or_resource.url when Formula if package_or_resource.stable urls << package_or_resource.stable.url @@ -623,6 +620,11 @@ module Homebrew formula_with_resources.resources.each_with_index do |resource, i| has_livecheckable = resource.livecheckable? + if debug + puts "Resource: #{resource_name(resource, full_name: full_name)}" + puts "Livecheckable?: #{has_livecheckable ? "Yes" : "No"}" + end + #@todo: for now, only check resources with livecheck block if has_livecheckable livecheck = resource.livecheck @@ -640,12 +642,165 @@ module Homebrew urls = [livecheck_url_string] if livecheck_url_string urls ||= checkable_urls(resource) + puts "URLs: #{urls}" + + checked_urls = [] + + urls.each_with_index do |original_url, i| + # Only preprocess the URL when it's appropriate + url = if STRATEGY_SYMBOLS_TO_SKIP_PREPROCESS_URL.include?(livecheck_strategy) + original_url + else + preprocess_url(original_url) + end + next if checked_urls.include?(url) + + + strategies = Strategy.from_url( + url, + livecheck_strategy: livecheck_strategy, + url_provided: livecheck_url.present?, + regex_provided: livecheck_regex.present?, + block_provided: livecheck_strategy_block.present?, + ) + + strategy = Strategy.from_symbol(livecheck_strategy) || strategies.first + strategy_name = livecheck_strategy_names[strategy] + + if debug + puts + if livecheck_url.is_a?(Symbol) + # This assumes the URL symbol will fit within the available space + puts "URL (#{livecheck_url}):".ljust(18, " ") + original_url + else + puts "URL: #{original_url}" + end + puts "URL (processed): #{url}" if url != original_url + if strategies.present? && verbose + puts "Strategies: #{strategies.map { |s| livecheck_strategy_names[s] }.join(", ")}" + end + puts "Strategy: #{strategy.blank? ? "None" : strategy_name}" + puts "Regex: #{livecheck_regex.inspect}" if livecheck_regex.present? + end + + if livecheck_strategy.present? + if livecheck_url.blank? && strategy.method(:find_versions).parameters.include?([:keyreq, :url]) + odebug "#{strategy_name} strategy requires a URL" + next + elsif livecheck_strategy != :page_match && strategies.exclude?(strategy) + odebug "#{strategy_name} strategy does not apply to this URL" + next + end + end + + next if strategy.blank? + homebrew_curl = case strategy_name + when "PageMatch", "HeaderMatch" + use_homebrew_curl?((referenced_formula_or_cask || formula_or_cask), url) + end + puts "Homebrew curl?: Yes" if debug && homebrew_curl.present? + + # p "strategy.method(:find_versions).parameters: #{strategy.method(:find_versions).parameters}" + + strategy_data = strategy.find_versions( + url: url, + regex: livecheck_regex, + homebrew_curl: homebrew_curl, + &livecheck_strategy_block + ) + + # p strategy_data + + match_version_map = strategy_data[:matches] + p "match_version_map: #{match_version_map}" + regex = strategy_data[:regex] + messages = strategy_data[:messages] + checked_urls << url + + if messages.is_a?(Array) && match_version_map.blank? + puts messages unless json + next if i + 1 < urls.length + + return status_hash(formula_or_cask, "error", messages, full_name: full_name, verbose: verbose) + end + + if debug + if strategy_data[:url].present? && strategy_data[:url] != url + puts "URL (strategy): #{strategy_data[:url]}" + end + puts "URL (final): #{strategy_data[:final_url]}" if strategy_data[:final_url].present? + if strategy_data[:regex].present? && strategy_data[:regex] != livecheck_regex + puts "Regex (strategy): #{strategy_data[:regex].inspect}" + end + puts "Cached?: Yes" if strategy_data[:cached] == true + end + + match_version_map.delete_if do |_match, version| + next true if version.blank? + next false if has_livecheckable + + UNSTABLE_VERSION_KEYWORDS.any? do |rejection| + version.to_s.include?(rejection) + end + end + + next if match_version_map.blank? + + if debug + puts + puts "Matched Versions:" + + if verbose + match_version_map.each do |match, version| + puts "#{match} => #{version.inspect}" + end + else + puts match_version_map.values.join(", ") + end + end + + version_info = { + latest: Version.new(match_version_map.values.max_by { |v| LivecheckVersion.create(formula_or_cask, v) }), + } + + if json && verbose + version_info[:meta] = {} + + if livecheck_references.present? + 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) } + when Cask::Cask + { cask: cask_name(ref_formula_or_cask, full_name: full_name) } + end + end + end + + version_info[:meta][:url] = {} + version_info[:meta][:url][:symbol] = livecheck_url if livecheck_url.is_a?(Symbol) && livecheck_url_string + version_info[:meta][:url][:original] = original_url + version_info[:meta][:url][:processed] = url if url != original_url + if strategy_data[:url].present? && strategy_data[:url] != url + version_info[:meta][:url][:strategy] = strategy_data[:url] + end + version_info[:meta][:url][:final] = strategy_data[:final_url] if strategy_data[:final_url] + version_info[:meta][:url][:homebrew_curl] = homebrew_curl if homebrew_curl.present? + + version_info[:meta][:strategy] = strategy.present? ? strategy_name : nil + version_info[:meta][:strategies] = strategies.map { |s| livecheck_strategy_names[s] } if strategies.present? + version_info[:meta][:regex] = regex.inspect if regex.present? + version_info[:meta][:cached] = true if strategy_data[:cached] == true + end + + puts "Version Info: #{}" + + return version_info + end + + end - if debug - puts "Resource: #{resource_name(resource, full_name: full_name)}" - puts "Livecheckable?: #{has_livecheckable ? "Yes" : "No"}" - end end @@ -654,152 +809,9 @@ module Homebrew - # checked_urls = [] - # # rubocop:disable Metrics/BlockLength - # urls.each_with_index do |original_url, i| - # # Only preprocess the URL when it's appropriate - # url = if STRATEGY_SYMBOLS_TO_SKIP_PREPROCESS_URL.include?(livecheck_strategy) - # original_url - # else - # preprocess_url(original_url) - # end - # next if checked_urls.include?(url) + # rubocop:disable Metrics/BlockLength - # strategies = Strategy.from_url( - # url, - # livecheck_strategy: livecheck_strategy, - # url_provided: livecheck_url.present?, - # regex_provided: livecheck_regex.present?, - # block_provided: livecheck_strategy_block.present?, - # ) - # strategy = Strategy.from_symbol(livecheck_strategy) || strategies.first - # strategy_name = livecheck_strategy_names[strategy] - - # if debug - # puts - # if livecheck_url.is_a?(Symbol) - # # This assumes the URL symbol will fit within the available space - # puts "URL (#{livecheck_url}):".ljust(18, " ") + original_url - # else - # puts "URL: #{original_url}" - # end - # puts "URL (processed): #{url}" if url != original_url - # if strategies.present? && verbose - # puts "Strategies: #{strategies.map { |s| livecheck_strategy_names[s] }.join(", ")}" - # end - # puts "Strategy: #{strategy.blank? ? "None" : strategy_name}" - # puts "Regex: #{livecheck_regex.inspect}" if livecheck_regex.present? - # end - - # if livecheck_strategy.present? - # if livecheck_url.blank? && strategy.method(:find_versions).parameters.include?([:keyreq, :url]) - # odebug "#{strategy_name} strategy requires a URL" - # next - # elsif livecheck_strategy != :page_match && strategies.exclude?(strategy) - # odebug "#{strategy_name} strategy does not apply to this URL" - # next - # end - # end - - # next if strategy.blank? - - # homebrew_curl = case strategy_name - # when "PageMatch", "HeaderMatch" - # use_homebrew_curl?((referenced_formula_or_cask || formula_or_cask), url) - # end - # puts "Homebrew curl?: Yes" if debug && homebrew_curl.present? - - # strategy_data = strategy.find_versions( - # url: url, - # regex: livecheck_regex, - # homebrew_curl: homebrew_curl, - # cask: cask, - # &livecheck_strategy_block - # ) - # match_version_map = strategy_data[:matches] - # regex = strategy_data[:regex] - # messages = strategy_data[:messages] - # checked_urls << url - - # if messages.is_a?(Array) && match_version_map.blank? - # puts messages unless json - # next if i + 1 < urls.length - - # return status_hash(formula_or_cask, "error", messages, full_name: full_name, verbose: verbose) - # end - - # if debug - # if strategy_data[:url].present? && strategy_data[:url] != url - # puts "URL (strategy): #{strategy_data[:url]}" - # end - # puts "URL (final): #{strategy_data[:final_url]}" if strategy_data[:final_url].present? - # if strategy_data[:regex].present? && strategy_data[:regex] != livecheck_regex - # puts "Regex (strategy): #{strategy_data[:regex].inspect}" - # end - # puts "Cached?: Yes" if strategy_data[:cached] == true - # end - - # match_version_map.delete_if do |_match, version| - # next true if version.blank? - # next false if has_livecheckable - - # UNSTABLE_VERSION_KEYWORDS.any? do |rejection| - # version.to_s.include?(rejection) - # end - # end - - # next if match_version_map.blank? - - # if debug - # puts - # puts "Matched Versions:" - - # if verbose - # match_version_map.each do |match, version| - # puts "#{match} => #{version.inspect}" - # end - # else - # puts match_version_map.values.join(", ") - # end - # end - - # version_info = { - # latest: Version.new(match_version_map.values.max_by { |v| LivecheckVersion.create(formula_or_cask, v) }), - # } - - # if json && verbose - # version_info[:meta] = {} - - # if livecheck_references.present? - # 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) } - # when Cask::Cask - # { cask: cask_name(ref_formula_or_cask, full_name: full_name) } - # end - # end - # end - - # version_info[:meta][:url] = {} - # version_info[:meta][:url][:symbol] = livecheck_url if livecheck_url.is_a?(Symbol) && livecheck_url_string - # version_info[:meta][:url][:original] = original_url - # version_info[:meta][:url][:processed] = url if url != original_url - # if strategy_data[:url].present? && strategy_data[:url] != url - # version_info[:meta][:url][:strategy] = strategy_data[:url] - # end - # version_info[:meta][:url][:final] = strategy_data[:final_url] if strategy_data[:final_url] - # version_info[:meta][:url][:homebrew_curl] = homebrew_curl if homebrew_curl.present? - - # version_info[:meta][:strategy] = strategy.present? ? strategy_name : nil - # version_info[:meta][:strategies] = strategies.map { |s| livecheck_strategy_names[s] } if strategies.present? - # version_info[:meta][:regex] = regex.inspect if regex.present? - # version_info[:meta][:cached] = true if strategy_data[:cached] == true - # end - - # return version_info - # end - # rubocop:enable Metrics/BlockLength + #rubocop:enable Metrics/BlockLength nil end @@ -927,7 +939,11 @@ module Homebrew cask: cask, &livecheck_strategy_block ) + + # p strategy_data + match_version_map = strategy_data[:matches] + p "match_version_map: #{match_version_map}" regex = strategy_data[:regex] messages = strategy_data[:messages] checked_urls << url From a60cd0097334717a287142d77db9353bcaf6dd3b Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Sun, 24 Jul 2022 19:54:00 +0200 Subject: [PATCH 020/138] Minor: added version_info for resources --- Library/Homebrew/livecheck/livecheck.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index 13f3a435b8..88ce4a2979 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -760,7 +760,7 @@ module Homebrew end version_info = { - latest: Version.new(match_version_map.values.max_by { |v| LivecheckVersion.create(formula_or_cask, v) }), + latest: Version.new(match_version_map.values.max_by { |v| LivecheckVersion.create(resource, v) }), } if json && verbose @@ -793,7 +793,7 @@ module Homebrew version_info[:meta][:cached] = true if strategy_data[:cached] == true end - puts "Version Info: #{}" + puts "Version Info: #{version_info}" return version_info end From 7ce15eaa60dd5552c15f851252507cbce6a8d528 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Mon, 25 Jul 2022 00:56:36 +0200 Subject: [PATCH 021/138] Basic debug info --- Library/Homebrew/livecheck/livecheck.rb | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index 88ce4a2979..5ac3258ef0 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -353,7 +353,13 @@ module Homebrew next info end - print_latest_version(info, verbose: verbose, ambiguous_cask: ambiguous_casks.include?(formula_or_cask)) + if resources_only + #@todo: modify print_latest_version for resources + onoe "#{Tty.blue}Debug info for resources is in progress!#{Tty.reset}" + else + print_latest_version(info, verbose: verbose, ambiguous_cask: ambiguous_casks.include?(formula_or_cask)) + end + nil rescue => e Homebrew.failed = true @@ -489,7 +495,7 @@ module Homebrew when :head, :stable # Not sure how to handle this ? # Do I have to add :stable / :head in Resources' as well (like it's being implemented in Formula ?) - package_or_resource.send(livecheck_url)&.url if package_or_resource.is_a?(Formula) + package_or_resource.send(livecheck_url)&.url if package_or_resource.is_a?(Formula) || package_or_resource.is_a?(Resource) when :homepage package_or_resource.homepage end From 43fcb5e563553d7450601950ed9fc97ab4e7b9ef Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Wed, 27 Jul 2022 13:26:48 +0200 Subject: [PATCH 022/138] Added support for resources in LivecheckVersion --- Library/Homebrew/livecheck/livecheck_version.rb | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/Library/Homebrew/livecheck/livecheck_version.rb b/Library/Homebrew/livecheck/livecheck_version.rb index 80336076e7..f1b722ed49 100644 --- a/Library/Homebrew/livecheck/livecheck_version.rb +++ b/Library/Homebrew/livecheck/livecheck_version.rb @@ -11,15 +11,17 @@ module Homebrew include Comparable - sig { params(formula_or_cask: T.any(Formula, Cask::Cask), version: Version).returns(LivecheckVersion) } - def self.create(formula_or_cask, version) - versions = case formula_or_cask + sig { params(package_or_resource: T.any(Formula, Cask::Cask, Resource), version: Version).returns(LivecheckVersion) } + def self.create(package_or_resource, version) + versions = case package_or_resource + when Resource + [version] when Formula [version] when Cask::Cask version.to_s.split(/[,:]/).map { |s| Version.new(s) } else - T.absurd(formula_or_cask) + T.absurd(package_or_resource) end new(versions) end From e84cc8d116e6e921ce9a93fbf66cdd54cca12829 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Wed, 27 Jul 2022 13:27:21 +0200 Subject: [PATCH 023/138] Work in progress for livecheckable resources --- Library/Homebrew/livecheck/livecheck.rb | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index 5ac3258ef0..052bfa839a 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -493,9 +493,11 @@ module Homebrew when :url package_or_resource.url&.to_s if package_or_resource.is_a?(Cask::Cask) || package_or_resource.is_a?(Resource) when :head, :stable + # Resource's "url" is considered "stable" by default. And some resources may contain in "head" block as well + package_or_resource.send(:url)&.to_s if package_or_resource.is_a?(Resource) # Not sure how to handle this ? # Do I have to add :stable / :head in Resources' as well (like it's being implemented in Formula ?) - package_or_resource.send(livecheck_url)&.url if package_or_resource.is_a?(Formula) || package_or_resource.is_a?(Resource) + package_or_resource.send(livecheck_url)&.url if package_or_resource.is_a?(Formula) when :homepage package_or_resource.homepage end @@ -702,7 +704,7 @@ module Homebrew next if strategy.blank? homebrew_curl = case strategy_name when "PageMatch", "HeaderMatch" - use_homebrew_curl?((referenced_formula_or_cask || formula_or_cask), url) + use_homebrew_curl?(resource, url) end puts "Homebrew curl?: Yes" if debug && homebrew_curl.present? From 32659afdbe0f4486ea1f6494882af0ffc86e9eaa Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Wed, 27 Jul 2022 13:53:54 +0200 Subject: [PATCH 024/138] Updated livecheck command for resources --- Library/Homebrew/dev-cmd/livecheck.rb | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Library/Homebrew/dev-cmd/livecheck.rb b/Library/Homebrew/dev-cmd/livecheck.rb index de7a343b9d..94cd1b3527 100644 --- a/Library/Homebrew/dev-cmd/livecheck.rb +++ b/Library/Homebrew/dev-cmd/livecheck.rb @@ -69,10 +69,10 @@ module Homebrew formulae = args.cask? ? [] : Formula.installed casks = args.formula? ? [] : Cask::Caskroom.casks formulae + casks - elsif args.resources? - # formula_with_resources = Formula.all.select { |formula| formula.resources.any? } - formula_with_resources = Formula.all.select { |formula| formula.resources.any? { |resource| resource.livecheckable? } } - formula_with_resources + # elsif args.resources? + # # formula_with_resources = Formula.all.select { |formula| formula.resources.any? } + # formula_with_resources = Formula.all.select { |formula| formula.resources.any? { |resource| resource.livecheckable? } } + # formula_with_resources elsif args.all? formulae = args.cask? ? [] : Formula.all casks = args.formula? ? [] : Cask::Cask.all @@ -83,7 +83,7 @@ module Homebrew elsif args.cask? args.named.to_casks else - args.named.to_package_and_resource + args.named.to_formulae_and_casks end elsif File.exist?(WATCHLIST_PATH) begin @@ -92,7 +92,7 @@ module Homebrew .map(&:strip) named_args = T.unsafe(CLI::NamedArgs).new(*names, parent: args) - named_args.to_package_and_resource(ignore_unavailable: true) + named_args.to_formulae_and_casks(ignore_unavailable: true) rescue Errno::ENOENT => e onoe e end @@ -115,7 +115,7 @@ module Homebrew json: args.json?, full_name: args.full_name?, handle_name_conflict: !args.formula? && !args.cask?, - resources_only: args.resources?, + check_resources: args.resources?, newer_only: args.newer_only?, quiet: args.quiet?, debug: args.debug?, From 277761009540b7fc3f6d2fdbbe922903631b2890 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Wed, 27 Jul 2022 13:54:20 +0200 Subject: [PATCH 025/138] Work in progress for `resource_version` --- Library/Homebrew/livecheck/livecheck.rb | 51 +++++++++++-------------- 1 file changed, 23 insertions(+), 28 deletions(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index 052bfa839a..02b66e2207 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -162,7 +162,7 @@ module Homebrew formulae_and_casks_to_check: T::Array[T.any(Formula, Cask::Cask)], full_name: T::Boolean, handle_name_conflict: T::Boolean, - resources_only: T::Boolean, + check_resources: T::Boolean, json: T::Boolean, newer_only: T::Boolean, debug: T::Boolean, @@ -172,7 +172,7 @@ module Homebrew } def run_checks( formulae_and_casks_to_check, - full_name: false, handle_name_conflict: false, resources_only: false, json: false, newer_only: false, + full_name: false, handle_name_conflict: false, check_resources: false, json: false, newer_only: false, debug: false, quiet: false, verbose: false ) load_other_tap_strategies(formulae_and_casks_to_check) @@ -280,25 +280,24 @@ module Homebrew latest = if formula&.head_only? formula.head.downloader.fetch_last_commit else - if resources_only - version_info = resource_version( + 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 + ) + version_info[:latest] if version_info.present? + + # In case "--resources" flag is passed as well + if check_resources + resource_version_info = resource_version( formula_or_cask, - referenced_formula: referenced_formula_or_cask, - livecheck_references: livecheck_references, json: json, full_name: use_full_name, verbose: verbose, debug: debug ) - 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 - ) end - version_info[:latest] if version_info.present? end if latest.blank? @@ -353,7 +352,7 @@ module Homebrew next info end - if resources_only + if check_resources #@todo: modify print_latest_version for resources onoe "#{Tty.blue}Debug info for resources is in progress!#{Tty.reset}" else @@ -607,9 +606,7 @@ module Homebrew # the version information. Returns nil if a latest version couldn't be found. sig { params( - formula_with_resources: T.any(Formula), - referenced_formula: T.nilable(T.any(Formula)), - livecheck_references: T::Array[T.any(Formula, Cask::Cask)], + formula_or_cask: T.any(Formula, Cask::Cask), json: T::Boolean, full_name: T::Boolean, verbose: T::Boolean, @@ -617,26 +614,23 @@ module Homebrew ).returns(T.nilable(Hash)) } def resource_version( - formula_with_resources, - referenced_formula: nil, - livecheck_references: [], + formula_or_cask, json: false, full_name: false, verbose: false, debug: false ) - formula_with_resources.resources.each_with_index do |resource, i| + formula_or_cask.resources.each_with_index do |resource, i| has_livecheckable = resource.livecheckable? if debug - puts "Resource: #{resource_name(resource, full_name: full_name)}" - puts "Livecheckable?: #{has_livecheckable ? "Yes" : "No"}" + odebug "Resource: #{resource_name(resource, full_name: full_name)}" + odebug "Livecheckable?: #{has_livecheckable ? "Yes" : "No"}" end - #@todo: for now, only check resources with livecheck block + # For now, only check resources with livecheck block if has_livecheckable livecheck = resource.livecheck - # referenced_livecheck = referenced_formula_or_cask&.livecheck livecheck_url = livecheck.url livecheck_regex = livecheck.regex livecheck_strategy = livecheck.strategy @@ -650,7 +644,9 @@ module Homebrew urls = [livecheck_url_string] if livecheck_url_string urls ||= checkable_urls(resource) - puts "URLs: #{urls}" + if debug + odebug "URLs: #{urls}" + end checked_urls = [] @@ -663,7 +659,6 @@ module Homebrew end next if checked_urls.include?(url) - strategies = Strategy.from_url( url, livecheck_strategy: livecheck_strategy, From e72487c8b07e59cba0d3dd1b1ed45bedc73a2592 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Wed, 27 Jul 2022 15:13:55 +0200 Subject: [PATCH 026/138] Updated for current and latest versions for resources --- Library/Homebrew/livecheck/livecheck.rb | 105 ++++++++++++------------ 1 file changed, 53 insertions(+), 52 deletions(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index 02b66e2207..0ce88ec1b3 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -287,9 +287,23 @@ module Homebrew json: json, full_name: use_full_name, verbose: verbose, debug: debug ) version_info[:latest] if version_info.present? + end + + # Check current and latest resources (if "--resources" flag is given) + if check_resources + + has_resources = formula_or_cask.resources.any? + + # In case we don't have any resources for that Formula/Cask + if !has_resources && (debug || verbose) + onoe "No resources to check for '#{formula_or_cask_name(formula_or_cask, full_name: full_name)}'" + end + + # Only check current and latest versions of resources if we have resources to check against + if has_resources + + current_resources = formula_or_cask.resources.map { |resource| { name: resource.name, version: resource.version } } - # In case "--resources" flag is passed as well - if check_resources resource_version_info = resource_version( formula_or_cask, json: json, @@ -297,6 +311,19 @@ module Homebrew verbose: verbose, debug: debug ) + + latest_resources = resource_version_info.map { |resource| { name: resource.name, version: resource.latest } } + + + + end + + + + + if debug && has_resources + odebug "Current Resources: #{current_resources}" + odebug "Latest Resources: #{latest_resources}" end end @@ -703,8 +730,6 @@ module Homebrew end puts "Homebrew curl?: Yes" if debug && homebrew_curl.present? - # p "strategy.method(:find_versions).parameters: #{strategy.method(:find_versions).parameters}" - strategy_data = strategy.find_versions( url: url, regex: livecheck_regex, @@ -712,10 +737,10 @@ module Homebrew &livecheck_strategy_block ) - # p strategy_data - match_version_map = strategy_data[:matches] - p "match_version_map: #{match_version_map}" + if debug + odebug "match_version_map: #{match_version_map}" + end regex = strategy_data[:regex] messages = strategy_data[:messages] checked_urls << url @@ -762,60 +787,36 @@ module Homebrew end end - version_info = { + resource_version_info = { + name: resource_name(resource, full_name: full_name), latest: Version.new(match_version_map.values.max_by { |v| LivecheckVersion.create(resource, v) }), } if json && verbose - version_info[:meta] = {} - - if livecheck_references.present? - 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) } - when Cask::Cask - { cask: cask_name(ref_formula_or_cask, full_name: full_name) } - end - end - end - - version_info[:meta][:url] = {} - version_info[:meta][:url][:symbol] = livecheck_url if livecheck_url.is_a?(Symbol) && livecheck_url_string - version_info[:meta][:url][:original] = original_url - version_info[:meta][:url][:processed] = url if url != original_url + resource_version_info[:meta] = {} + resource_version_info[:meta][:name] = resource_name(resource, full_name: full_name) if resource + resource_version_info[:meta][:livecheckable] = has_livecheckable ? "Yes" : "No" + resource_version_info[:meta][:url] = {} + resource_version_info[:meta][:url][:symbol] = livecheck_url if livecheck_url.is_a?(Symbol) && livecheck_url_string + resource_version_info[:meta][:url][:original] = original_url + resource_version_info[:meta][:url][:processed] = url if url != original_url if strategy_data[:url].present? && strategy_data[:url] != url - version_info[:meta][:url][:strategy] = strategy_data[:url] + resource_version_info[:meta][:url][:strategy] = strategy_data[:url] end - version_info[:meta][:url][:final] = strategy_data[:final_url] if strategy_data[:final_url] - version_info[:meta][:url][:homebrew_curl] = homebrew_curl if homebrew_curl.present? - - version_info[:meta][:strategy] = strategy.present? ? strategy_name : nil - version_info[:meta][:strategies] = strategies.map { |s| livecheck_strategy_names[s] } if strategies.present? - version_info[:meta][:regex] = regex.inspect if regex.present? - version_info[:meta][:cached] = true if strategy_data[:cached] == true + resource_version_info[:meta][:url][:final] = strategy_data[:final_url] if strategy_data[:final_url] + resource_version_info[:meta][:url][:homebrew_curl] = homebrew_curl if homebrew_curl.present? + resource_version_info[:meta][:strategy] = strategy.present? ? strategy_name : nil + resource_version_info[:meta][:strategies] = strategies.map { |s| livecheck_strategy_names[s] } if strategies.present? + resource_version_info[:meta][:regex] = regex.inspect if regex.present? + resource_version_info[:meta][:cached] = true if strategy_data[:cached] == true end - - puts "Version Info: #{version_info}" - - return version_info + if debug + odebug "Resource Version Info: #{resource_version_info}" + end + return resource_version_info end - - end - - end - - - - - - - # rubocop:disable Metrics/BlockLength - - #rubocop:enable Metrics/BlockLength - nil end @@ -946,7 +947,7 @@ module Homebrew # p strategy_data match_version_map = strategy_data[:matches] - p "match_version_map: #{match_version_map}" + # p "match_version_map: #{match_version_map}" regex = strategy_data[:regex] messages = strategy_data[:messages] checked_urls << url From 73cf8fd2059464ee8de29097e1506a14e99d939a Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Wed, 27 Jul 2022 15:24:33 +0200 Subject: [PATCH 027/138] Updated latest version for resources --- Library/Homebrew/livecheck/livecheck.rb | 32 ++++++++++++------------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index 0ce88ec1b3..e6a466280f 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -294,11 +294,6 @@ module Homebrew has_resources = formula_or_cask.resources.any? - # In case we don't have any resources for that Formula/Cask - if !has_resources && (debug || verbose) - onoe "No resources to check for '#{formula_or_cask_name(formula_or_cask, full_name: full_name)}'" - end - # Only check current and latest versions of resources if we have resources to check against if has_resources @@ -312,18 +307,20 @@ module Homebrew debug: debug ) - latest_resources = resource_version_info.map { |resource| { name: resource.name, version: resource.latest } } + odebug "resource_version_info: #{resource_version_info}" + # latest_resources = resource_version_info.map { |resource| { name: resource.name, version: resource.latest } } + if debug || verbose + odebug "Current Resources: #{current_resources}" + odebug "Latest Resources: #{latest_resources}" + end - end - - - - - if debug && has_resources - odebug "Current Resources: #{current_resources}" - odebug "Latest Resources: #{latest_resources}" + else + # In case we don't have any resources for that Formula/Cask + if debug || verbose + onoe "No resources to check for '#{formula_or_cask_name(formula_or_cask, full_name: full_name)}'" + end end end @@ -638,7 +635,7 @@ module Homebrew full_name: T::Boolean, verbose: T::Boolean, debug: T::Boolean, - ).returns(T.nilable(Hash)) + ).returns(Array(T.nilable(Hash))) } def resource_version( formula_or_cask, @@ -647,6 +644,7 @@ module Homebrew verbose: false, debug: false ) + resources_version = [] formula_or_cask.resources.each_with_index do |resource, i| has_livecheckable = resource.livecheckable? @@ -813,11 +811,11 @@ module Homebrew if debug odebug "Resource Version Info: #{resource_version_info}" end - return resource_version_info + resources_version << resource_version_info end end end - nil + resources_version end #================================================================================== From 8e3e9743ac4deb57117de84c625192638d7ee272 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Wed, 27 Jul 2022 16:37:31 +0200 Subject: [PATCH 028/138] Basic structure completed for livecheckable resources --- Library/Homebrew/livecheck/livecheck.rb | 81 +++++++++++++++++++++++-- Library/Taps/homebrew/homebrew-core | 2 +- 2 files changed, 76 insertions(+), 7 deletions(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index e6a466280f..84fbe9fdf1 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -297,7 +297,7 @@ module Homebrew # Only check current and latest versions of resources if we have resources to check against if has_resources - current_resources = formula_or_cask.resources.map { |resource| { name: resource.name, version: resource.version } } + current_resources = formula_or_cask.resources.map { |resource| { name: resource.name, version: resource.version, livecheckable: resource.livecheckable? } } resource_version_info = resource_version( formula_or_cask, @@ -307,11 +307,16 @@ module Homebrew debug: debug ) - odebug "resource_version_info: #{resource_version_info}" + # odebug "resource_version_info: #{resource_version_info}" - # latest_resources = resource_version_info.map { |resource| { name: resource.name, version: resource.latest } } + latest_resources = resource_version_info.map { |resource| { name: resource[:name], version: resource[:latest] } } if debug || verbose + puts <<~EOS + + ---------- + + EOS odebug "Current Resources: #{current_resources}" odebug "Latest Resources: #{latest_resources}" end @@ -377,8 +382,43 @@ module Homebrew end if check_resources + + resources_info = [] + + if has_resources + latest_resources_names = latest_resources.map { |r| r[:name] } + current_resources.each_with_index do |resource, i| + + current = resource[:version] + current_str = current.to_s + latest = if latest_resources_names.include?(resource[:name].to_s) + res = latest_resources.detect { |r| r[:name].to_s == resource[:name].to_s } + res[:version] + else + current + end + latest_str = latest.to_s + + is_newer_than_upstream = current > latest + is_outdated = (current != latest) && !is_newer_than_upstream + + info = {} + info[:resource] = resource[:name] + info[:livecheckable] = resource[:livecheckable] + info[:version] = { + current: current_str, + latest: latest_str, + newer_than_upstream: is_newer_than_upstream, + outdated: is_outdated, + } + resources_info << info + end + end + + #@todo: modify print_latest_version for resources onoe "#{Tty.blue}Debug info for resources is in progress!#{Tty.reset}" + print_latest_resource_version(resources_info, verbose: verbose, ambiguous_cask: ambiguous_casks.include?(formula_or_cask)) else print_latest_version(info, verbose: verbose, ambiguous_cask: ambiguous_casks.include?(formula_or_cask)) end @@ -481,6 +521,30 @@ module Homebrew status_hash end + # Formats and prints the livecheck result for a resource (for a given Formula or Cask). + sig { params(resources_info: Array(Hash), verbose: T::Boolean, ambiguous_cask: T::Boolean).void } + def print_latest_resource_version(resources_info, verbose:, ambiguous_cask: false) + odebug "resources_info: #{resources_info}" + resources_info.each_with_index do |info, i| + resource_s = "#{Tty.blue}#{info[:resource]}#{Tty.reset}" + resource_s += " (livecheckable)" if info[:livecheckable] && verbose + + current_s = if info[:version][:newer_than_upstream] + "#{Tty.red}#{info[:version][:current]}#{Tty.reset}" + else + info[:version][:current] + end + + latest_s = if info[:version][:outdated] + "#{Tty.green}#{info[:version][:latest]}#{Tty.reset}" + else + info[:version][:latest] + end + + puts "#{resource_s}: #{current_s} ==> #{latest_s}" + end + end + # Formats and prints the livecheck result for a formula. sig { params(info: Hash, verbose: T::Boolean, ambiguous_cask: T::Boolean).void } def print_latest_version(info, verbose:, ambiguous_cask: false) @@ -649,6 +713,11 @@ module Homebrew has_livecheckable = resource.livecheckable? if debug + puts <<~EOS + + ---------- + + EOS odebug "Resource: #{resource_name(resource, full_name: full_name)}" odebug "Livecheckable?: #{has_livecheckable ? "Yes" : "No"}" end @@ -736,9 +805,9 @@ module Homebrew ) match_version_map = strategy_data[:matches] - if debug - odebug "match_version_map: #{match_version_map}" - end + # if debug + # odebug "match_version_map: #{match_version_map}" + # end regex = strategy_data[:regex] messages = strategy_data[:messages] checked_urls << url diff --git a/Library/Taps/homebrew/homebrew-core b/Library/Taps/homebrew/homebrew-core index 88b2623dd6..65b3469d30 160000 --- a/Library/Taps/homebrew/homebrew-core +++ b/Library/Taps/homebrew/homebrew-core @@ -1 +1 @@ -Subproject commit 88b2623dd6ff0dec391029b1f43107438935f4b7 +Subproject commit 65b3469d300943210a42d69f75eae33faafd204c From 1f55f15d664b3ed5ee8639de985847382a70f614 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Wed, 27 Jul 2022 16:51:26 +0200 Subject: [PATCH 029/138] Removed extra bits --- Library/Homebrew/livecheck/livecheck.rb | 85 +++++++++---------------- 1 file changed, 29 insertions(+), 56 deletions(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index 84fbe9fdf1..dd78146e0e 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -271,9 +271,6 @@ module Homebrew Version.new(formula_or_cask.version) end - p "Formula: #{formula_or_cask_name(formula_or_cask, full_name: use_full_name)}" - p "Current: #{current.to_s}" - current_str = current.to_s current = LivecheckVersion.create(formula_or_cask, current) @@ -307,20 +304,8 @@ module Homebrew debug: debug ) - # odebug "resource_version_info: #{resource_version_info}" - latest_resources = resource_version_info.map { |resource| { name: resource[:name], version: resource[:latest] } } - if debug || verbose - puts <<~EOS - - ---------- - - EOS - odebug "Current Resources: #{current_resources}" - odebug "Latest Resources: #{latest_resources}" - end - else # In case we don't have any resources for that Formula/Cask if debug || verbose @@ -381,46 +366,42 @@ module Homebrew next info end - if check_resources + print_latest_version(info, verbose: verbose, ambiguous_cask: ambiguous_casks.include?(formula_or_cask)) + if check_resources && has_resources resources_info = [] - - if has_resources - latest_resources_names = latest_resources.map { |r| r[:name] } - current_resources.each_with_index do |resource, i| - - current = resource[:version] - current_str = current.to_s - latest = if latest_resources_names.include?(resource[:name].to_s) - res = latest_resources.detect { |r| r[:name].to_s == resource[:name].to_s } - res[:version] - else - current - end - latest_str = latest.to_s - - is_newer_than_upstream = current > latest - is_outdated = (current != latest) && !is_newer_than_upstream - - info = {} - info[:resource] = resource[:name] - info[:livecheckable] = resource[:livecheckable] - info[:version] = { - current: current_str, - latest: latest_str, - newer_than_upstream: is_newer_than_upstream, - outdated: is_outdated, - } - resources_info << info + latest_resources_names = latest_resources.map { |r| r[:name] } + current_resources.each_with_index do |resource, i| + current = resource[:version] + current_str = current.to_s + latest = if latest_resources_names.include?(resource[:name].to_s) + res = latest_resources.detect { |r| r[:name].to_s == resource[:name].to_s } + res[:version] + else + current end + latest_str = latest.to_s + + is_newer_than_upstream = current > latest + is_outdated = (current != latest) && !is_newer_than_upstream + + info = {} + info[:resource] = resource[:name] + info[:livecheckable] = resource[:livecheckable] + info[:version] = { + current: current_str, + latest: latest_str, + newer_than_upstream: is_newer_than_upstream, + outdated: is_outdated, + } + resources_info << info end + puts <<~EOS + ---------- - #@todo: modify print_latest_version for resources - onoe "#{Tty.blue}Debug info for resources is in progress!#{Tty.reset}" + EOS print_latest_resource_version(resources_info, verbose: verbose, ambiguous_cask: ambiguous_casks.include?(formula_or_cask)) - else - print_latest_version(info, verbose: verbose, ambiguous_cask: ambiguous_casks.include?(formula_or_cask)) end nil @@ -524,7 +505,6 @@ module Homebrew # Formats and prints the livecheck result for a resource (for a given Formula or Cask). sig { params(resources_info: Array(Hash), verbose: T::Boolean, ambiguous_cask: T::Boolean).void } def print_latest_resource_version(resources_info, verbose:, ambiguous_cask: false) - odebug "resources_info: #{resources_info}" resources_info.each_with_index do |info, i| resource_s = "#{Tty.blue}#{info[:resource]}#{Tty.reset}" resource_s += " (livecheckable)" if info[:livecheckable] && verbose @@ -738,10 +718,6 @@ module Homebrew urls = [livecheck_url_string] if livecheck_url_string urls ||= checkable_urls(resource) - if debug - odebug "URLs: #{urls}" - end - checked_urls = [] urls.each_with_index do |original_url, i| @@ -877,9 +853,6 @@ module Homebrew resource_version_info[:meta][:regex] = regex.inspect if regex.present? resource_version_info[:meta][:cached] = true if strategy_data[:cached] == true end - if debug - odebug "Resource Version Info: #{resource_version_info}" - end resources_version << resource_version_info end end From a8c1c0c8412d8a1e6b64c15afeec198b8f21bcc9 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Wed, 27 Jul 2022 18:19:14 +0200 Subject: [PATCH 030/138] Updated description for resource's option in livecheck command --- Library/Homebrew/dev-cmd/livecheck.rb | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/Library/Homebrew/dev-cmd/livecheck.rb b/Library/Homebrew/dev-cmd/livecheck.rb index 94cd1b3527..966cd75a4f 100644 --- a/Library/Homebrew/dev-cmd/livecheck.rb +++ b/Library/Homebrew/dev-cmd/livecheck.rb @@ -36,7 +36,7 @@ module Homebrew switch "--json", description: "Output information in JSON format." switch "-r", "--resources", - description: "Check resources with livecheck blocks." + description: "Check resources with livecheck blocks for a given formulae/casks." switch "-q", "--quiet", description: "Suppress warnings, don't print a progress bar for JSON output." switch "--formula", "--formulae", @@ -69,10 +69,6 @@ module Homebrew formulae = args.cask? ? [] : Formula.installed casks = args.formula? ? [] : Cask::Caskroom.casks formulae + casks - # elsif args.resources? - # # formula_with_resources = Formula.all.select { |formula| formula.resources.any? } - # formula_with_resources = Formula.all.select { |formula| formula.resources.any? { |resource| resource.livecheckable? } } - # formula_with_resources elsif args.all? formulae = args.cask? ? [] : Formula.all casks = args.formula? ? [] : Cask::Cask.all @@ -100,11 +96,6 @@ module Homebrew raise UsageError, "A watchlist file is required when no arguments are given." end - # p package_and_resource_to_check.class - # p package_and_resource_to_check.length - # p package_and_resource_to_check[0].class - # p package_and_resource_to_check.map { |d| d.name } - package_and_resource_to_check = package_and_resource_to_check.sort_by do |package_or_resource| package_or_resource.respond_to?(:token) ? package_or_resource.token : package_or_resource.name end From 3dc1b9c231d9fb3b42ce7b4e2f2416863e7073ca Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Wed, 27 Jul 2022 18:25:12 +0200 Subject: [PATCH 031/138] Refactored `run_checks` and `resource_version` methods for livecheck command --- Library/Homebrew/livecheck/livecheck.rb | 104 +++++++++++++----------- 1 file changed, 57 insertions(+), 47 deletions(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index dd78146e0e..131c03d332 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -254,9 +254,6 @@ module Homebrew formula&.head&.downloader&.shutup! - # Check resources if "--resources" flag was given - - # Use the `stable` version for comparison except for installed # head-only formulae. A formula with `stable` and `head` that's # installed using `--head` will still use the `stable` version for @@ -291,7 +288,7 @@ module Homebrew has_resources = formula_or_cask.resources.any? - # Only check current and latest versions of resources if we have resources to check against + # Only check current and latest versions if we have resources to check against if has_resources current_resources = formula_or_cask.resources.map { |resource| { name: resource.name, version: resource.version, livecheckable: resource.livecheckable? } } @@ -304,7 +301,7 @@ module Homebrew debug: debug ) - latest_resources = resource_version_info.map { |resource| { name: resource[:name], version: resource[:latest] } } + latest_resources = resource_version_info.map { |resource| { name: resource[:resource], version: resource[:version][:latest] } } else # In case we don't have any resources for that Formula/Cask @@ -356,6 +353,8 @@ module Homebrew info[:meta][:head_only] = true if formula&.head_only? info[:meta].merge!(version_info[:meta]) if version_info.present? && version_info.key?(:meta) + info[:resources] = resource_version_info if check_resources + next if newer_only && !info[:version][:outdated] has_a_newer_upstream_version ||= true @@ -366,6 +365,13 @@ module Homebrew next info end + if check_resources && has_resources && debug + puts <<~EOS + + ---------- + + EOS + end print_latest_version(info, verbose: verbose, ambiguous_cask: ambiguous_casks.include?(formula_or_cask)) if check_resources && has_resources @@ -396,11 +402,6 @@ module Homebrew } resources_info << info end - puts <<~EOS - - ---------- - - EOS print_latest_resource_version(resources_info, verbose: verbose, ambiguous_cask: ambiguous_casks.include?(formula_or_cask)) end @@ -474,28 +475,31 @@ module Homebrew sig { params( - formula_or_cask: T.any(Formula, Cask::Cask), + package_or_resource: T.any(Formula, Cask::Cask, Resource), status_str: String, messages: T.nilable(T::Array[String]), full_name: T::Boolean, verbose: T::Boolean, ).returns(Hash) } - def status_hash(formula_or_cask, status_str, messages = nil, full_name: false, verbose: false) - formula = formula_or_cask if formula_or_cask.is_a?(Formula) - cask = formula_or_cask if formula_or_cask.is_a?(Cask::Cask) + def status_hash(package_or_resource, status_str, messages = nil, full_name: false, verbose: false) + formula = package_or_resource if package_or_resource.is_a?(Formula) + cask = package_or_resource if package_or_resource.is_a?(Cask::Cask) + resource = package_or_resource if package_or_resource.is_a?(Resource) status_hash = {} if formula status_hash[:formula] = formula_name(formula, full_name: full_name) elsif cask - status_hash[:cask] = cask_name(formula_or_cask, full_name: full_name) + status_hash[:cask] = cask_name(package_or_resource, full_name: full_name) + elsif resource + status_hash[:resource] = resource_name(package_or_resource, full_name: full_name) end status_hash[:status] = status_str status_hash[:messages] = messages if messages.is_a?(Array) status_hash[:meta] = { - livecheckable: formula_or_cask.livecheckable?, + livecheckable: package_or_resource.livecheckable?, } status_hash[:meta][:head_only] = true if formula&.head_only? @@ -521,7 +525,7 @@ module Homebrew info[:version][:latest] end - puts "#{resource_s}: #{current_s} ==> #{latest_s}" + puts "-- #{resource_s}: #{current_s} ==> #{latest_s}" end end @@ -668,10 +672,8 @@ module Homebrew homebrew_curl_root_domains.include?(url_root_domain) end - #================================================================================== - - # Identifies the latest version of the resources and returns a Hash containing - # the version information. Returns nil if a latest version couldn't be found. + # Identifies the latest version of the resources in a given Formulae/Casks and returns an Array of Hash containing + # the version information for all the resources. Returns an Array with nil value if a latest version couldn't be found for a given resource. sig { params( formula_or_cask: T.any(Formula, Cask::Cask), @@ -702,7 +704,14 @@ module Homebrew odebug "Livecheckable?: #{has_livecheckable ? "Yes" : "No"}" end - # For now, only check resources with livecheck block + resource_version_info = { + resource: resource_name(resource, full_name: full_name), + version: { + current: resource.version, + }, + } + + # Check resources with livecheck block (will be updated in the future) if has_livecheckable livecheck = resource.livecheck livecheck_url = livecheck.url @@ -781,9 +790,6 @@ module Homebrew ) match_version_map = strategy_data[:matches] - # if debug - # odebug "match_version_map: #{match_version_map}" - # end regex = strategy_data[:regex] messages = strategy_data[:messages] checked_urls << url @@ -792,7 +798,7 @@ module Homebrew 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(resource, "error", messages, full_name: full_name, verbose: verbose) end if debug @@ -830,38 +836,45 @@ module Homebrew end end - resource_version_info = { - name: resource_name(resource, full_name: full_name), - latest: Version.new(match_version_map.values.max_by { |v| LivecheckVersion.create(resource, v) }), - } + resource_version_info[:version][:latest] = Version.new(match_version_map.values.max_by { |v| LivecheckVersion.create(resource, v) }) if json && verbose resource_version_info[:meta] = {} - resource_version_info[:meta][:name] = resource_name(resource, full_name: full_name) if resource resource_version_info[:meta][:livecheckable] = has_livecheckable ? "Yes" : "No" + if has_livecheckable + resource_version_info[:meta][:livecheck] = {} + resource_version_info[:meta][:livecheck][:url] = {} + resource_version_info[:meta][:livecheck][:url][:symbol] = livecheck_url if livecheck_url.is_a?(Symbol) && livecheck_url_string + if strategy_data[:url].present? && strategy_data[:url] != url + resource_version_info[:meta][:livecheck][:url][:strategy] = strategy_data[:url] + end + resource_version_info[:meta][:livecheck][:url][:final] = strategy_data[:final_url] if strategy_data[:final_url] + resource_version_info[:meta][:livecheck][:url][:homebrew_curl] = homebrew_curl if homebrew_curl.present? + resource_version_info[:meta][:livecheck][:strategy] = strategy.present? ? strategy_name : nil + resource_version_info[:meta][:livecheck][:strategies] = strategies.map { |s| livecheck_strategy_names[s] } if strategies.present? + resource_version_info[:meta][:livecheck][:regex] = regex.inspect if regex.present? + resource_version_info[:meta][:livecheck][:cached] = true if strategy_data[:cached] == true + + end resource_version_info[:meta][:url] = {} - resource_version_info[:meta][:url][:symbol] = livecheck_url if livecheck_url.is_a?(Symbol) && livecheck_url_string resource_version_info[:meta][:url][:original] = original_url resource_version_info[:meta][:url][:processed] = url if url != original_url - if strategy_data[:url].present? && strategy_data[:url] != url - resource_version_info[:meta][:url][:strategy] = strategy_data[:url] - end - resource_version_info[:meta][:url][:final] = strategy_data[:final_url] if strategy_data[:final_url] - resource_version_info[:meta][:url][:homebrew_curl] = homebrew_curl if homebrew_curl.present? - resource_version_info[:meta][:strategy] = strategy.present? ? strategy_name : nil - resource_version_info[:meta][:strategies] = strategies.map { |s| livecheck_strategy_names[s] } if strategies.present? - resource_version_info[:meta][:regex] = regex.inspect if regex.present? - resource_version_info[:meta][:cached] = true if strategy_data[:cached] == true end - resources_version << resource_version_info end + resources_version << resource_version_info + else + # If there's no livecheck block in resource + resource_version_info[:version][:latest] = resource.version + if json && verbose + resource_version_info[:meta] = {} + resource_version_info[:meta][:url] = resource.url.to_s + end + resources_version << resource_version_info end end resources_version end - #================================================================================== - # Identifies the latest version of the formula and returns a Hash containing # the version information. Returns nil if a latest version couldn't be found. # rubocop:disable Metrics/CyclomaticComplexity @@ -984,10 +997,7 @@ module Homebrew &livecheck_strategy_block ) - # p strategy_data - match_version_map = strategy_data[:matches] - # p "match_version_map: #{match_version_map}" regex = strategy_data[:regex] messages = strategy_data[:messages] checked_urls << url From 08cd9cebbb50305285ba2a37bbaaa474e6baeb98 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Wed, 27 Jul 2022 19:11:13 +0200 Subject: [PATCH 032/138] Revert back some changes --- .gitignore | 2 +- .vscode/settings.json | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/.gitignore b/.gitignore index 17c761af71..10401ee27f 100644 --- a/.gitignore +++ b/.gitignore @@ -17,7 +17,7 @@ /Library/Homebrew/test/junit /Library/Homebrew/test/fs_leak_log /Library/Homebrew/vendor/portable-ruby -#/Library/Taps +/Library/Taps /Library/PinnedTaps /Library/Homebrew/.byebug_history /Library/Homebrew/sorbet/rbi/hidden-definitions/errors.txt diff --git a/.vscode/settings.json b/.vscode/settings.json index fe8a066e21..865fc53af2 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -23,7 +23,5 @@ "editor.codeActionsOnSave": { "source.fixAll.shellcheck": true, } - }, - "git.mergeEditor": true, - "merge-conflict.autoNavigateNextConflict.enabled": true + } } From 23ec9142c9999726a70aae87922ff15f62d40d3d Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Wed, 27 Jul 2022 19:16:02 +0200 Subject: [PATCH 033/138] Removed unnecessary files --- .../lib/sorbet-runtime.rb | 116 -- .../lib/types/_types.rb | 316 ----- .../lib/types/abstract_utils.rb | 50 - .../lib/types/boolean.rb | 8 - .../lib/types/compatibility_patches.rb | 93 -- .../lib/types/configuration.rb | 591 -------- .../lib/types/enum.rb | 377 ------ .../lib/types/generic.rb | 22 - .../lib/types/helpers.rb | 58 - .../lib/types/interface_wrapper.rb | 158 --- .../lib/types/non_forcing_constants.rb | 65 - .../lib/types/private/abstract/data.rb | 36 - .../lib/types/private/abstract/declare.rb | 53 - .../lib/types/private/abstract/hooks.rb | 42 - .../lib/types/private/abstract/validate.rb | 128 -- .../lib/types/private/casts.rb | 41 - .../lib/types/private/class_utils.rb | 110 -- .../lib/types/private/compiler.rb | 24 - .../lib/types/private/decl_state.rb | 30 - .../lib/types/private/final.rb | 50 - .../lib/types/private/methods/_methods.rb | 581 -------- .../types/private/methods/call_validation.rb | 221 --- .../private/methods/call_validation_2_6.rb | 1203 ----------------- .../private/methods/call_validation_2_7.rb | 1203 ----------------- .../lib/types/private/methods/decl_builder.rb | 232 ---- .../lib/types/private/methods/modes.rb | 28 - .../lib/types/private/methods/signature.rb | 225 --- .../private/methods/signature_validation.rb | 225 --- .../lib/types/private/mixins/mixins.rb | 27 - .../lib/types/private/retry.rb | 10 - .../lib/types/private/runtime_levels.rb | 62 - .../lib/types/private/sealed.rb | 91 -- .../lib/types/private/types/not_typed.rb | 23 - .../lib/types/private/types/string_holder.rb | 26 - .../lib/types/private/types/type_alias.rb | 31 - .../lib/types/private/types/void.rb | 34 - .../lib/types/props/_props.rb | 169 --- .../lib/types/props/constructor.rb | 40 - .../lib/types/props/custom_type.rb | 108 -- .../lib/types/props/decorator.rb | 669 --------- .../lib/types/props/errors.rb | 8 - .../types/props/generated_code_validation.rb | 277 ---- .../props/has_lazily_specialized_methods.rb | 140 -- .../lib/types/props/optional.rb | 89 -- .../lib/types/props/plugin.rb | 37 - .../lib/types/props/pretty_printable.rb | 107 -- .../lib/types/props/private/apply_default.rb | 170 --- .../props/private/deserializer_generator.rb | 160 --- .../lib/types/props/private/parser.rb | 32 - .../types/props/private/serde_transform.rb | 186 --- .../props/private/serializer_generator.rb | 76 -- .../lib/types/props/private/setter_factory.rb | 197 --- .../lib/types/props/serializable.rb | 374 ----- .../lib/types/props/type_validation.rb | 111 -- .../lib/types/props/utils.rb | 59 - .../lib/types/props/weak_constructor.rb | 67 - .../sorbet-runtime-0.5.10132/lib/types/sig.rb | 30 - .../lib/types/struct.rb | 18 - .../lib/types/types/attached_class.rb | 37 - .../lib/types/types/base.rb | 172 --- .../lib/types/types/class_of.rb | 40 - .../lib/types/types/enum.rb | 40 - .../lib/types/types/fixed_array.rb | 86 -- .../lib/types/types/fixed_hash.rb | 74 - .../lib/types/types/intersection.rb | 42 - .../lib/types/types/noreturn.rb | 29 - .../lib/types/types/proc.rb | 51 - .../lib/types/types/self_type.rb | 35 - .../lib/types/types/simple.rb | 94 -- .../lib/types/types/t_enum.rb | 38 - .../lib/types/types/type_member.rb | 7 - .../lib/types/types/type_parameter.rb | 23 - .../lib/types/types/type_template.rb | 7 - .../lib/types/types/type_variable.rb | 34 - .../lib/types/types/typed_array.rb | 39 - .../lib/types/types/typed_enumerable.rb | 176 --- .../lib/types/types/typed_enumerator.rb | 41 - .../lib/types/types/typed_enumerator_lazy.rb | 41 - .../lib/types/types/typed_hash.rb | 48 - .../lib/types/types/typed_range.rb | 31 - .../lib/types/types/typed_set.rb | 53 - .../lib/types/types/union.rb | 91 -- .../lib/types/types/untyped.rb | 29 - .../lib/types/utils.rb | 209 --- 84 files changed, 11281 deletions(-) delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/sorbet-runtime.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/_types.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/abstract_utils.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/boolean.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/compatibility_patches.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/configuration.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/enum.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/generic.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/helpers.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/interface_wrapper.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/non_forcing_constants.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/abstract/data.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/abstract/declare.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/abstract/hooks.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/abstract/validate.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/casts.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/class_utils.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/compiler.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/decl_state.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/final.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/_methods.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/call_validation.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/call_validation_2_6.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/call_validation_2_7.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/decl_builder.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/modes.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/signature.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/signature_validation.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/mixins/mixins.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/retry.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/runtime_levels.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/sealed.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/types/not_typed.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/types/string_holder.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/types/type_alias.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/types/void.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/_props.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/constructor.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/custom_type.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/decorator.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/errors.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/generated_code_validation.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/has_lazily_specialized_methods.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/optional.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/plugin.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/pretty_printable.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/private/apply_default.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/private/deserializer_generator.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/private/parser.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/private/serde_transform.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/private/serializer_generator.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/private/setter_factory.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/serializable.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/type_validation.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/utils.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/weak_constructor.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/sig.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/struct.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/attached_class.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/base.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/class_of.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/enum.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/fixed_array.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/fixed_hash.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/intersection.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/noreturn.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/proc.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/self_type.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/simple.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/t_enum.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/type_member.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/type_parameter.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/type_template.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/type_variable.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/typed_array.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/typed_enumerable.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/typed_enumerator.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/typed_enumerator_lazy.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/typed_hash.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/typed_range.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/typed_set.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/union.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/untyped.rb delete mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/utils.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/sorbet-runtime.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/sorbet-runtime.rb deleted file mode 100644 index c2ad5678d0..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/sorbet-runtime.rb +++ /dev/null @@ -1,116 +0,0 @@ -# frozen_string_literal: true -# typed: true - -# This file is hand-crafted to encode the dependencies. They load the whole type -# system since there is such a high chance of it being used, using an autoloader -# wouldn't buy us any startup time saving. - -# Namespaces without any implementation -module T; end -module T::Helpers; end -module T::Private; end -module T::Private::Abstract; end -module T::Private::Types; end - -# Each section is a group that I believe need a fixed ordering. There is also -# an ordering between groups. - -# These are pre-reqs for almost everything in here. -require_relative 'types/configuration' -require_relative 'types/_types' -require_relative 'types/private/decl_state' -require_relative 'types/private/class_utils' -require_relative 'types/private/runtime_levels' -require_relative 'types/private/methods/_methods' -require_relative 'types/sig' -require_relative 'types/helpers' -require_relative 'types/private/final' -require_relative 'types/private/sealed' - -# The types themselves. First base classes -require_relative 'types/types/base' -require_relative 'types/types/typed_enumerable' -# Everything else -require_relative 'types/types/class_of' -require_relative 'types/types/enum' -require_relative 'types/types/fixed_array' -require_relative 'types/types/fixed_hash' -require_relative 'types/types/intersection' -require_relative 'types/types/noreturn' -require_relative 'types/types/proc' -require_relative 'types/types/attached_class' -require_relative 'types/types/self_type' -require_relative 'types/types/simple' -require_relative 'types/types/t_enum' -require_relative 'types/types/type_parameter' -require_relative 'types/types/typed_array' -require_relative 'types/types/typed_enumerator' -require_relative 'types/types/typed_enumerator_lazy' -require_relative 'types/types/typed_hash' -require_relative 'types/types/typed_range' -require_relative 'types/types/typed_set' -require_relative 'types/types/union' -require_relative 'types/types/untyped' -require_relative 'types/private/types/not_typed' -require_relative 'types/private/types/void' -require_relative 'types/private/types/string_holder' -require_relative 'types/private/types/type_alias' - -require_relative 'types/types/type_variable' -require_relative 'types/types/type_member' -require_relative 'types/types/type_template' - -# Call validation -require_relative 'types/private/methods/modes' -require_relative 'types/private/methods/call_validation' - -# Signature validation -require_relative 'types/private/methods/signature_validation' -require_relative 'types/abstract_utils' -require_relative 'types/private/abstract/validate' - -# Catch all. Sort of built by `cd extn; find types -type f | grep -v test | sort` -require_relative 'types/generic' -require_relative 'types/interface_wrapper' -require_relative 'types/private/abstract/declare' -require_relative 'types/private/abstract/hooks' -require_relative 'types/private/casts' -require_relative 'types/private/methods/decl_builder' -require_relative 'types/private/methods/signature' -require_relative 'types/private/retry' -require_relative 'types/utils' -require_relative 'types/boolean' - -# Props dependencies -require_relative 'types/private/abstract/data' -require_relative 'types/private/mixins/mixins' -require_relative 'types/props/_props' -require_relative 'types/props/custom_type' -require_relative 'types/props/decorator' -require_relative 'types/props/errors' -require_relative 'types/props/plugin' -require_relative 'types/props/utils' -require_relative 'types/enum' -# Props that run sigs statically so have to be after all the others :( -require_relative 'types/props/private/setter_factory' -require_relative 'types/props/private/apply_default' -require_relative 'types/props/has_lazily_specialized_methods' -require_relative 'types/props/optional' -require_relative 'types/props/weak_constructor' -require_relative 'types/props/constructor' -require_relative 'types/props/pretty_printable' -require_relative 'types/props/private/serde_transform' -require_relative 'types/props/private/deserializer_generator' -require_relative 'types/props/private/serializer_generator' -require_relative 'types/props/serializable' -require_relative 'types/props/type_validation' -require_relative 'types/props/private/parser' -require_relative 'types/props/generated_code_validation' - -require_relative 'types/struct' -require_relative 'types/non_forcing_constants' - -require_relative 'types/compatibility_patches' - -# Sorbet Compiler support module -require_relative 'types/private/compiler' diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/_types.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/_types.rb deleted file mode 100644 index 20a0e641e0..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/_types.rb +++ /dev/null @@ -1,316 +0,0 @@ -# frozen_string_literal: true -# typed: true -# This is where we define the shortcuts, so we can't use them here - -# _____ -# |_ _| _ _ __ ___ ___ -# | || | | | '_ \ / _ \/ __| -# | || |_| | |_) | __/\__ \ -# |_| \__, | .__/ \___||___/ -# |___/|_| -# -# Docs at https://sorbet.org/docs/sigs -# -# Types that you can pass to `sig`: -# -# - a Ruby class -# -# - [, , ...] -- to specify a "tuple"; a fixed-size array with known types for each member -# -# - {key: , key2: , ...} -- to speicfy a "shape"; a fixed-size hash -# with known keys and type values -# -# - Any of the `T.foo` methods below - -module T - # T.any(, , ...) -- matches any of the types listed - def self.any(type_a, type_b, *types) - type_a = T::Utils.coerce(type_a) - type_b = T::Utils.coerce(type_b) - types = types.map {|t| T::Utils.coerce(t)} if !types.empty? - T::Types::Union::Private::Pool.union_of_types(type_a, type_b, types) - end - - # Shorthand for T.any(type, NilClass) - def self.nilable(type) - T::Types::Union::Private::Pool.union_of_types(T::Utils.coerce(type), T::Utils::Nilable::NIL_TYPE) - end - - # Matches any object. In the static checker, T.untyped allows any - # method calls or operations. - def self.untyped - T::Types::Untyped::Private::INSTANCE - end - - # Indicates a function never returns (e.g. "Kernel#raise") - def self.noreturn - T::Types::NoReturn::Private::INSTANCE - end - - # T.all(, , ...) -- matches an object that has all of the types listed - def self.all(type_a, type_b, *types) - T::Types::Intersection.new([type_a, type_b] + types) - end - - # Matches any of the listed values - # @deprecated Use T::Enum instead. - def self.deprecated_enum(values) - T::Types::Enum.new(values) - end - - # Creates a proc type - def self.proc - T::Private::Methods.start_proc - end - - # Matches `self`: - def self.self_type - T::Types::SelfType::Private::INSTANCE - end - - # Matches the instance type in a singleton-class context - def self.attached_class - T::Types::AttachedClassType::Private::INSTANCE - end - - # Matches any class that subclasses or includes the provided class - # or module - def self.class_of(klass) - T::Types::ClassOf.new(klass) - end - - ## END OF THE METHODS TO PASS TO `sig`. - - # Constructs a type alias. Used to create a short name for a larger type. In Ruby this returns a - # wrapper that contains a proc that is evaluated to get the underlying type. This syntax however - # is needed for support by the static checker. - # - # @example - # NilableString = T.type_alias {T.nilable(String)} - # - # sig {params(arg: NilableString, default: String).returns(String)} - # def or_else(arg, default) - # arg || default - # end - # - # The name of the type alias is not preserved; Error messages will - # be printed with reference to the underlying type. - # - # TODO Remove `type` parameter. This was left in to make life easier while migrating. - def self.type_alias(type=nil, &blk) - if blk - T::Private::Types::TypeAlias.new(blk) - else - T::Utils.coerce(type) - end - end - - # References a type parameter which was previously defined with - # `type_parameters`. - # - # This is used for generic methods. - # - # @example - # sig - # .type_parameters(:U) - # .params( - # blk: T.proc.params(arg0: Elem).returns(T.type_parameter(:U)), - # ) - # .returns(T::Array[T.type_parameter(:U)]) - # def map(&blk); end - def self.type_parameter(name) - T::Types::TypeParameter.new(name) - end - - # Tells the typechecker that `value` is of type `type`. Use this to get additional checking after - # an expression that the typechecker is unable to analyze. If `checked` is true, raises an - # exception at runtime if the value doesn't match the type. - # - # Compared to `T.let`, `T.cast` is _trusted_ by static system. - def self.cast(value, type, checked: true) - return value unless checked - - Private::Casts.cast(value, type, cast_method: "T.cast") - end - - # Tells the typechecker to declare a variable of type `type`. Use - # like: - # - # seconds = T.let(0.0, Float) - # - # Compared to `T.cast`, `T.let` is _checked_ by static system. - # - # If `checked` is true, raises an exception at runtime if the value - # doesn't match the type. - def self.let(value, type, checked: true) - return value unless checked - - Private::Casts.cast(value, type, cast_method: "T.let") - end - - # Tells the type checker to treat `self` in the current block as `type`. - # Useful for blocks that are captured and executed later with instance_exec. - # Use like: - # - # seconds = lambda do - # T.bind(self, NewBinding) - # ... - # end - # - # `T.bind` behaves like `T.cast` in that it is assumed to be true statically. - # - # If `checked` is true, raises an exception at runtime if the value - # doesn't match the type (this is the default). - def self.bind(value, type, checked: true) - return value unless checked - - Private::Casts.cast(value, type, cast_method: "T.bind") - end - - # Tells the typechecker to ensure that `value` is of type `type` (if not, the typechecker will - # fail). Use this for debugging typechecking errors, or to ensure that type information is - # statically known and being checked appropriately. If `checked` is true, raises an exception at - # runtime if the value doesn't match the type. - def self.assert_type!(value, type, checked: true) - return value unless checked - - Private::Casts.cast(value, type, cast_method: "T.assert_type!") - end - - # For the static type checker, strips all type information from a value - # and returns the same value, but statically-typed as `T.untyped`. - # Can be used to tell the static checker to "trust you" by discarding type information - # you know to be incorrect. Use with care! - # (This has no effect at runtime.) - # - # We can't actually write this sig because we ourselves are inside - # the `T::` module and doing this would create a bootstrapping - # cycle. However, we also don't actually need to do so; An untyped - # identity method works just as well here. - # - # `sig {params(value: T.untyped).returns(T.untyped)}` - def self.unsafe(value) - value - end - - # A convenience method to `raise` when the argument is `nil` and return it - # otherwise. - # - # Intended to be used as: - # - # needs_foo(T.must(maybe_gives_foo)) - # - # Equivalent to: - # - # foo = maybe_gives_foo - # raise "nil" if foo.nil? - # needs_foo(foo) - # - # Intended to be used to promise sorbet that a given nilable value happens - # to contain a non-nil value at this point. - # - # `sig {params(arg: T.nilable(A)).returns(A)}` - def self.must(arg) - return arg if arg - return arg if arg == false - - begin - raise TypeError.new("Passed `nil` into T.must") - rescue TypeError => e # raise into rescue to ensure e.backtrace is populated - T::Configuration.inline_type_error_handler(e, {kind: 'T.must', value: arg, type: nil}) - end - end - - # A way to ask Sorbet to show what type it thinks an expression has. - # This can be useful for debugging and checking assumptions. - # In the runtime, merely returns the value passed in. - def self.reveal_type(value) - value - end - - # A way to ask Sorbet to prove that a certain branch of control flow never - # happens. Commonly used to assert that a case or if statement exhausts all - # possible cases. - def self.absurd(value) - msg = "Control flow reached T.absurd." - - case value - when Kernel - msg += " Got value: #{value}" - end - - begin - raise TypeError.new(msg) - rescue TypeError => e # raise into rescue to ensure e.backtrace is populated - T::Configuration.inline_type_error_handler(e, {kind: 'T.absurd', value: value, type: nil}) - end - end - - ### Generic classes ### - - module Array - def self.[](type) - if type.is_a?(T::Types::Untyped) - T::Types::TypedArray::Untyped.new - else - T::Types::TypedArray.new(type) - end - end - end - - module Hash - def self.[](keys, values) - if keys.is_a?(T::Types::Untyped) && values.is_a?(T::Types::Untyped) - T::Types::TypedHash::Untyped.new - else - T::Types::TypedHash.new(keys: keys, values: values) - end - end - end - - module Enumerable - def self.[](type) - if type.is_a?(T::Types::Untyped) - T::Types::TypedEnumerable::Untyped.new - else - T::Types::TypedEnumerable.new(type) - end - end - end - - module Enumerator - def self.[](type) - if type.is_a?(T::Types::Untyped) - T::Types::TypedEnumerator::Untyped.new - else - T::Types::TypedEnumerator.new(type) - end - end - - module Lazy - def self.[](type) - if type.is_a?(T::Types::Untyped) - T::Types::TypedEnumeratorLazy::Untyped.new - else - T::Types::TypedEnumeratorLazy.new(type) - end - end - end - end - - module Range - def self.[](type) - T::Types::TypedRange.new(type) - end - end - - module Set - def self.[](type) - if type.is_a?(T::Types::Untyped) - T::Types::TypedSet::Untyped.new - else - T::Types::TypedSet.new(type) - end - end - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/abstract_utils.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/abstract_utils.rb deleted file mode 100644 index 721bd4e0a7..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/abstract_utils.rb +++ /dev/null @@ -1,50 +0,0 @@ -# frozen_string_literal: true -# typed: true - -module T::AbstractUtils - Methods = T::Private::Methods - - # Returns whether a module is declared as abstract. After the module is finished being declared, - # this is equivalent to whether it has any abstract methods that haven't been implemented - # (because we validate that and raise an error otherwise). - # - # Note that checking `mod.is_a?(Abstract::Hooks)` is not a safe substitute for this method; when - # a class extends `Abstract::Hooks`, all of its subclasses, including the eventual concrete - # ones, will still have `Abstract::Hooks` as an ancestor. - def self.abstract_module?(mod) - !T::Private::Abstract::Data.get(mod, :abstract_type).nil? - end - - def self.abstract_method?(method) - signature = Methods.signature_for_method(method) - signature&.mode == Methods::Modes.abstract - end - - # Given a module, returns the set of methods declared as abstract (in itself or ancestors) - # that have not been implemented. - def self.abstract_methods_for(mod) - declared_methods = declared_abstract_methods_for(mod) - declared_methods.select do |declared_method| - actual_method = mod.instance_method(declared_method.name) - # Note that in the case where an abstract method is overridden by another abstract method, - # this method will return them both. This is intentional to ensure we validate the final - # implementation against all declarations of an abstract method (they might not all have the - # same signature). - abstract_method?(actual_method) - end - end - - # Given a module, returns the set of methods declared as abstract (in itself or ancestors) - # regardless of whether they have been implemented. - def self.declared_abstract_methods_for(mod) - methods = [] - mod.ancestors.each do |ancestor| - ancestor_methods = ancestor.private_instance_methods(false) + ancestor.instance_methods(false) - ancestor_methods.each do |method_name| - method = ancestor.instance_method(method_name) - methods << method if abstract_method?(method) - end - end - methods - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/boolean.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/boolean.rb deleted file mode 100644 index 8763d8707d..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/boolean.rb +++ /dev/null @@ -1,8 +0,0 @@ -# typed: strict -# frozen_string_literal: true - -module T - # T::Boolean is a type alias helper for the common `T.any(TrueClass, FalseClass)`. - # Defined separately from _types.rb because it has a dependency on T::Types::Union. - Boolean = T.type_alias {T.any(TrueClass, FalseClass)} -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/compatibility_patches.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/compatibility_patches.rb deleted file mode 100644 index 070b182aae..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/compatibility_patches.rb +++ /dev/null @@ -1,93 +0,0 @@ -# frozen_string_literal: true -# typed: ignore - -# Work around an interaction bug with sorbet-runtime and rspec-mocks, -# which occurs when using message expectations (*_any_instance_of, -# expect, allow) and and_call_original. -# -# When a sig is defined, sorbet-runtime will replace the sigged method -# with a wrapper that, upon first invocation, re-wraps the method with a faster -# implementation. -# -# When expect_any_instance_of is used, rspec stores a reference to the first wrapper, -# to be restored later. -# -# The first wrapper is invoked as part of the test and sorbet-runtime replaces -# the method definition with the second wrapper. -# -# But when mocks are cleaned up, rspec restores back to the first wrapper. -# Upon subsequent invocations, the first wrapper is called, and sorbet-runtime -# throws a runtime error, since this is an unexpected state. -# -# We work around this by forcing re-wrapping before rspec stores a reference -# to the method. -if defined? ::RSpec::Mocks - module T - module CompatibilityPatches - module RSpecCompatibility - module RecorderExtensions - def observe!(method_name) - method = @klass.instance_method(method_name.to_sym) - T::Private::Methods.maybe_run_sig_block_for_method(method) - super(method_name) - end - end - ::RSpec::Mocks::AnyInstance::Recorder.prepend(RecorderExtensions) if defined?(::RSpec::Mocks::AnyInstance::Recorder) - - module MethodDoubleExtensions - def initialize(object, method_name, proxy) - if ::Kernel.instance_method(:respond_to?).bind(object).call(method_name, true) - method = ::RSpec::Support.method_handle_for(object, method_name) - T::Private::Methods.maybe_run_sig_block_for_method(method) - end - super(object, method_name, proxy) - end - end - ::RSpec::Mocks::MethodDouble.prepend(MethodDoubleExtensions) if defined?(::RSpec::Mocks::MethodDouble) - end - end - end -end - -# Work around for sorbet-runtime wrapped methods. -# -# When a sig is defined, sorbet-runtime will replace the sigged method -# with a wrapper. Those wrapper methods look like `foo(*args, &blk)` -# so that wrappers can handle and pass on all the arguments supplied. -# -# However, that creates a problem with runtime reflection on the methods, -# since when a sigged method is introspected, it will always return its -# `arity` as `-1`, its `parameters` as `[[:rest, :args], [:block, :blk]]`, -# and its `source_location` as `[, ]`. -# -# This might be a problem for some applications that rely on getting the -# correct information from these methods. -# -# This compatibility module, when prepended to the `Method` class, would fix -# the return values of `arity`, `parameters` and `source_location`. -# -# @example -# require 'sorbet-runtime' -# ::Method.prepend(T::CompatibilityPatches::MethodExtensions) -module T - module CompatibilityPatches - module MethodExtensions - def arity - arity = super - return arity if arity != -1 || self.is_a?(Proc) - sig = T::Private::Methods.signature_for_method(self) - sig ? sig.method.arity : arity - end - - def source_location - sig = T::Private::Methods.signature_for_method(self) - sig ? sig.method.source_location : super - end - - def parameters - sig = T::Private::Methods.signature_for_method(self) - sig ? sig.method.parameters : super - end - end - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/configuration.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/configuration.rb deleted file mode 100644 index c012b6e8b6..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/configuration.rb +++ /dev/null @@ -1,591 +0,0 @@ -# typed: true -# frozen_string_literal: true - -module T::Configuration - # Cache this comparisonn to avoid two allocations all over the place. - AT_LEAST_RUBY_2_7 = Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.7') - - # Announces to Sorbet that we are currently in a test environment, so it - # should treat any sigs which are marked `.checked(:tests)` as if they were - # just a normal sig. - # - # If this method is not called, sigs marked `.checked(:tests)` will not be - # checked. In fact, such methods won't even be wrapped--the runtime will put - # back the original method. - # - # Note: Due to the way sigs are evaluated and methods are wrapped, this - # method MUST be called before any code calls `sig`. This method raises if - # it has been called too late. - def self.enable_checking_for_sigs_marked_checked_tests - T::Private::RuntimeLevels.enable_checking_in_tests - end - - # Announce to Sorbet that we would like the final checks to be enabled when - # including and extending modules. Iff this is not called, then the following - # example will not raise an error. - # - # ```ruby - # module M - # extend T::Sig - # sig(:final) {void} - # def foo; end - # end - # class C - # include M - # def foo; end - # end - # ``` - def self.enable_final_checks_on_hooks - T::Private::Methods.set_final_checks_on_hooks(true) - end - - # Undo the effects of a previous call to - # `enable_final_checks_on_hooks`. - def self.reset_final_checks_on_hooks - T::Private::Methods.set_final_checks_on_hooks(false) - end - - @include_value_in_type_errors = true - # Whether to include values in TypeError messages. - # - # Including values is useful for debugging, but can potentially leak - # sensitive information to logs. - # - # @return [T::Boolean] - def self.include_value_in_type_errors? - @include_value_in_type_errors - end - - # Configure if type errors excludes the value of the problematic type. - # - # The default is to include values in type errors: - # TypeError: Expected type Integer, got String with value "foo" - # - # When values are excluded from type errors: - # TypeError: Expected type Integer, got String - def self.exclude_value_in_type_errors - @include_value_in_type_errors = false - end - - # Opposite of exclude_value_in_type_errors. - # (Including values in type errors is the default) - def self.include_value_in_type_errors - @include_value_in_type_errors = true - end - - # Whether VM-defined prop serialization/deserialization routines can be enabled. - # - # @return [T::Boolean] - def self.can_enable_vm_prop_serde? - T::Props::Private::DeserializerGenerator.respond_to?(:generate2) - end - - @use_vm_prop_serde = false - # Whether to use VM-defined prop serialization/deserialization routines. - # - # The default is to use runtime codegen inside sorbet-runtime itself. - # - # @return [T::Boolean] - def self.use_vm_prop_serde? - @use_vm_prop_serde || false - end - - # Enable using VM-defined prop serialization/deserialization routines. - # - # This method is likely to break things outside of Stripe's systems. - def self.enable_vm_prop_serde - if !can_enable_vm_prop_serde? - hard_assert_handler('Ruby VM is not setup to use VM-defined prop serde') - end - @use_vm_prop_serde = true - end - - # Disable using VM-defined prop serialization/deserialization routines. - def self.disable_vm_prop_serde - @use_vm_prop_serde = false - end - - # Configure the default checked level for a sig with no explicit `.checked` - # builder. When unset, the default checked level is `:always`. - # - # Note: setting this option is potentially dangerous! Sorbet can't check all - # code statically. The runtime checks complement the checks that Sorbet does - # statically, so that methods don't have to guard themselves from being - # called incorrectly by untyped code. - # - # @param [:never, :compiled, :tests, :always] default_checked_level - def self.default_checked_level=(default_checked_level) - T::Private::RuntimeLevels.default_checked_level = default_checked_level - end - - @inline_type_error_handler = nil - # Set a handler to handle `TypeError`s raised by any in-line type assertions, - # including `T.must`, `T.let`, `T.cast`, and `T.assert_type!`. - # - # By default, any `TypeError`s detected by this gem will be raised. Setting - # inline_type_error_handler to an object that implements :call (e.g. proc or - # lambda) allows users to customize the behavior when a `TypeError` is - # raised on any inline type assertion. - # - # @param [Lambda, Proc, Object, nil] value Proc that handles the error (pass - # nil to reset to default behavior) - # - # Parameters passed to value.call: - # - # @param [TypeError] error TypeError that was raised - # @param [Hash] opts A hash containing contextual information on the error: - # @option opts [String] :kind One of: - # ['T.cast', 'T.let', 'T.bind', 'T.assert_type!', 'T.must', 'T.absurd'] - # @option opts [Object, nil] :type Expected param/return value type - # @option opts [Object] :value Actual param/return value - # - # @example - # T::Configuration.inline_type_error_handler = lambda do |error, opts| - # puts error.message - # end - def self.inline_type_error_handler=(value) - validate_lambda_given!(value) - @inline_type_error_handler = value - end - - private_class_method def self.inline_type_error_handler_default(error, opts) - raise error - end - - def self.inline_type_error_handler(error, opts={}) - if @inline_type_error_handler - # Backwards compatibility before `inline_type_error_handler` took a second arg - if @inline_type_error_handler.arity == 1 - @inline_type_error_handler.call(error) - else - @inline_type_error_handler.call(error, opts) - end - else - inline_type_error_handler_default(error, opts) - end - nil - end - - @sig_builder_error_handler = nil - # Set a handler to handle errors that occur when the builder methods in the - # body of a sig are executed. The sig builder methods are inside a proc so - # that they can be lazily evaluated the first time the method being sig'd is - # called. - # - # By default, improper use of the builder methods within the body of a sig - # cause an ArgumentError to be raised. Setting sig_builder_error_handler to an - # object that implements :call (e.g. proc or lambda) allows users to - # customize the behavior when a sig can't be built for some reason. - # - # @param [Lambda, Proc, Object, nil] value Proc that handles the error (pass - # nil to reset to default behavior) - # - # Parameters passed to value.call: - # - # @param [StandardError] error The error that was raised - # @param [Thread::Backtrace::Location] location Location of the error - # - # @example - # T::Configuration.sig_builder_error_handler = lambda do |error, location| - # puts error.message - # end - def self.sig_builder_error_handler=(value) - validate_lambda_given!(value) - @sig_builder_error_handler = value - end - - private_class_method def self.sig_builder_error_handler_default(error, location) - raise ArgumentError.new("#{location.path}:#{location.lineno}: Error interpreting `sig`:\n #{error.message}\n\n") - end - - def self.sig_builder_error_handler(error, location) - if @sig_builder_error_handler - @sig_builder_error_handler.call(error, location) - else - sig_builder_error_handler_default(error, location) - end - nil - end - - @sig_validation_error_handler = nil - # Set a handler to handle sig validation errors. - # - # Sig validation errors include things like abstract checks, override checks, - # and type compatibility of arguments. They happen after a sig has been - # successfully built, but the built sig is incompatible with other sigs in - # some way. - # - # By default, sig validation errors cause an exception to be raised. - # Setting sig_validation_error_handler to an object that implements :call - # (e.g. proc or lambda) allows users to customize the behavior when a method - # signature's build fails. - # - # @param [Lambda, Proc, Object, nil] value Proc that handles the error (pass - # nil to reset to default behavior) - # - # Parameters passed to value.call: - # - # @param [StandardError] error The error that was raised - # @param [Hash] opts A hash containing contextual information on the error: - # @option opts [Method, UnboundMethod] :method Method on which the signature build failed - # @option opts [T::Private::Methods::Declaration] :declaration Method - # signature declaration struct - # @option opts [T::Private::Methods::Signature, nil] :signature Signature - # that failed (nil if sig build failed before Signature initialization) - # @option opts [T::Private::Methods::Signature, nil] :super_signature Super - # method's signature (nil if method is not an override or super method - # does not have a method signature) - # - # @example - # T::Configuration.sig_validation_error_handler = lambda do |error, opts| - # puts error.message - # end - def self.sig_validation_error_handler=(value) - validate_lambda_given!(value) - @sig_validation_error_handler = value - end - - private_class_method def self.sig_validation_error_handler_default(error, opts) - raise error - end - - def self.sig_validation_error_handler(error, opts={}) - if @sig_validation_error_handler - @sig_validation_error_handler.call(error, opts) - else - sig_validation_error_handler_default(error, opts) - end - nil - end - - @call_validation_error_handler = nil - # Set a handler for type errors that result from calling a method. - # - # By default, errors from calling a method cause an exception to be raised. - # Setting call_validation_error_handler to an object that implements :call - # (e.g. proc or lambda) allows users to customize the behavior when a method - # is called with invalid parameters, or returns an invalid value. - # - # @param [Lambda, Proc, Object, nil] value Proc that handles the error - # report (pass nil to reset to default behavior) - # - # Parameters passed to value.call: - # - # @param [T::Private::Methods::Signature] signature Signature that failed - # @param [Hash] opts A hash containing contextual information on the error: - # @option opts [String] :message Error message - # @option opts [String] :kind One of: - # ['Parameter', 'Block parameter', 'Return value'] - # @option opts [Symbol] :name Param or block param name (nil for return - # value) - # @option opts [Object] :type Expected param/return value type - # @option opts [Object] :value Actual param/return value - # @option opts [Thread::Backtrace::Location] :location Location of the - # caller - # - # @example - # T::Configuration.call_validation_error_handler = lambda do |signature, opts| - # puts opts[:message] - # end - def self.call_validation_error_handler=(value) - validate_lambda_given!(value) - @call_validation_error_handler = value - end - - private_class_method def self.call_validation_error_handler_default(signature, opts) - raise TypeError.new(opts[:pretty_message]) - end - - def self.call_validation_error_handler(signature, opts={}) - if @call_validation_error_handler - @call_validation_error_handler.call(signature, opts) - else - call_validation_error_handler_default(signature, opts) - end - nil - end - - @log_info_handler = nil - # Set a handler for logging - # - # @param [Lambda, Proc, Object, nil] value Proc that handles the error - # report (pass nil to reset to default behavior) - # - # Parameters passed to value.call: - # - # @param [String] str Message to be logged - # @param [Hash] extra A hash containing additional parameters to be passed along to the logger. - # - # @example - # T::Configuration.log_info_handler = lambda do |str, extra| - # puts "#{str}, context: #{extra}" - # end - def self.log_info_handler=(value) - validate_lambda_given!(value) - @log_info_handler = value - end - - private_class_method def self.log_info_handler_default(str, extra) - puts "#{str}, extra: #{extra}" - end - - def self.log_info_handler(str, extra) - if @log_info_handler - @log_info_handler.call(str, extra) - else - log_info_handler_default(str, extra) - end - end - - @soft_assert_handler = nil - # Set a handler for soft assertions - # - # These generally shouldn't stop execution of the program, but rather inform - # some party of the assertion to action on later. - # - # @param [Lambda, Proc, Object, nil] value Proc that handles the error - # report (pass nil to reset to default behavior) - # - # Parameters passed to value.call: - # - # @param [String] str Assertion message - # @param [Hash] extra A hash containing additional parameters to be passed along to the handler. - # - # @example - # T::Configuration.soft_assert_handler = lambda do |str, extra| - # puts "#{str}, context: #{extra}" - # end - def self.soft_assert_handler=(value) - validate_lambda_given!(value) - @soft_assert_handler = value - end - - private_class_method def self.soft_assert_handler_default(str, extra) - puts "#{str}, extra: #{extra}" - end - - def self.soft_assert_handler(str, extra) - if @soft_assert_handler - @soft_assert_handler.call(str, extra) - else - soft_assert_handler_default(str, extra) - end - end - - @hard_assert_handler = nil - # Set a handler for hard assertions - # - # These generally should stop execution of the program, and optionally inform - # some party of the assertion. - # - # @param [Lambda, Proc, Object, nil] value Proc that handles the error - # report (pass nil to reset to default behavior) - # - # Parameters passed to value.call: - # - # @param [String] str Assertion message - # @param [Hash] extra A hash containing additional parameters to be passed along to the handler. - # - # @example - # T::Configuration.hard_assert_handler = lambda do |str, extra| - # raise "#{str}, context: #{extra}" - # end - def self.hard_assert_handler=(value) - validate_lambda_given!(value) - @hard_assert_handler = value - end - - private_class_method def self.hard_assert_handler_default(str, _) - raise str - end - - def self.hard_assert_handler(str, extra={}) - if @hard_assert_handler - @hard_assert_handler.call(str, extra) - else - hard_assert_handler_default(str, extra) - end - end - - @scalar_types = nil - # Set a list of class strings that are to be considered scalar. - # (pass nil to reset to default behavior) - # - # @param [String] values Class name. - # - # @example - # T::Configuration.scalar_types = ["NilClass", "TrueClass", "FalseClass", ...] - def self.scalar_types=(values) - if values.nil? - @scalar_types = values - else - bad_values = values.reject {|v| v.class == String} - unless bad_values.empty? - raise ArgumentError.new("Provided values must all be class name strings.") - end - - @scalar_types = values.each_with_object({}) {|x, acc| acc[x] = true}.freeze - end - end - - @default_scalar_types = { - "NilClass" => true, - "TrueClass" => true, - "FalseClass" => true, - "Integer" => true, - "Float" => true, - "String" => true, - "Symbol" => true, - "Time" => true, - "T::Enum" => true, - }.freeze - - def self.scalar_types - @scalar_types || @default_scalar_types - end - - # Guard against overrides of `name` or `to_s` - MODULE_NAME = Module.instance_method(:name) - private_constant :MODULE_NAME - - @default_module_name_mangler = if T::Configuration::AT_LEAST_RUBY_2_7 - ->(type) {MODULE_NAME.bind_call(type)} - else - ->(type) {MODULE_NAME.bind(type).call} - end - - @module_name_mangler = nil - - def self.module_name_mangler - @module_name_mangler || @default_module_name_mangler - end - - # Set to override the default behavior for converting types - # to names in generated code. Used by the runtime implementation - # associated with `--stripe-packages` mode. - # - # @param [Lambda, Proc, nil] handler Proc that converts a type (Class/Module) - # to a String (pass nil to reset to default behavior) - def self.module_name_mangler=(handler) - @module_name_mangler = handler - end - - @sensitivity_and_pii_handler = nil - # Set to a PII handler function. This will be called with the `sensitivity:` - # annotations on things that use `T::Props` and can modify them ahead-of-time. - # - # @param [Lambda, Proc, nil] handler Proc that takes a hash mapping symbols to the - # prop values. Pass nil to avoid changing `sensitivity:` annotations. - def self.normalize_sensitivity_and_pii_handler=(handler) - @sensitivity_and_pii_handler = handler - end - - def self.normalize_sensitivity_and_pii_handler - @sensitivity_and_pii_handler - end - - @redaction_handler = nil - # Set to a redaction handling function. This will be called when the - # `_redacted` version of a prop reader is used. By default this is set to - # `nil` and will raise an exception when the redacted version of a prop is - # accessed. - # - # @param [Lambda, Proc, nil] handler Proc that converts a value into its - # redacted version according to the spec passed as the second argument. - def self.redaction_handler=(handler) - @redaction_handler = handler - end - - def self.redaction_handler - @redaction_handler - end - - @class_owner_finder = nil - # Set to a function which can get the 'owner' of a class. This is - # used in reporting deserialization errors - # - # @param [Lambda, Proc, nil] handler Proc that takes a class and - # produces its owner, or `nil` if it does not have one. - def self.class_owner_finder=(handler) - @class_owner_finder = handler - end - - def self.class_owner_finder - @class_owner_finder - end - - # Temporarily disable ruby warnings while executing the given block. This is - # useful when doing something that would normally cause a warning to be - # emitted in Ruby verbose mode ($VERBOSE = true). - # - # @yield - # - def self.without_ruby_warnings - if $VERBOSE - begin - original_verbose = $VERBOSE - $VERBOSE = false - yield - ensure - $VERBOSE = original_verbose - end - else - yield - end - end - - @legacy_t_enum_migration_mode = false - def self.enable_legacy_t_enum_migration_mode - @legacy_t_enum_migration_mode = true - end - def self.disable_legacy_t_enum_migration_mode - @legacy_t_enum_migration_mode = false - end - def self.legacy_t_enum_migration_mode? - @legacy_t_enum_migration_mode || false - end - - @prop_freeze_handler = ->(instance, prop_name) {} - - def self.prop_freeze_handler=(handler) - @prop_freeze_handler = handler - end - - def self.prop_freeze_handler - @prop_freeze_handler - end - - @sealed_violation_whitelist = nil - # @param [Array] sealed_violation_whitelist An array of Regexp to validate - # whether inheriting /including a sealed module outside the defining module - # should be allowed. Useful to whitelist benign violations, like shim files - # generated for an autoloader. - def self.sealed_violation_whitelist=(sealed_violation_whitelist) - if !@sealed_violation_whitelist.nil? - raise ArgumentError.new("Cannot overwrite sealed_violation_whitelist after setting it") - end - - case sealed_violation_whitelist - when Array - sealed_violation_whitelist.each do |x| - case x - when Regexp then nil - else raise TypeError.new("sealed_violation_whitelist accepts an Array of Regexp") - end - end - else - raise TypeError.new("sealed_violation_whitelist= accepts an Array of Regexp") - end - - @sealed_violation_whitelist = sealed_violation_whitelist - end - def self.sealed_violation_whitelist - @sealed_violation_whitelist - end - - private_class_method def self.validate_lambda_given!(value) - if !value.nil? && !value.respond_to?(:call) - raise ArgumentError.new("Provided value must respond to :call") - end - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/enum.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/enum.rb deleted file mode 100644 index c2de09abaf..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/enum.rb +++ /dev/null @@ -1,377 +0,0 @@ -# frozen_string_literal: true -# typed: strict - -# Enumerations allow for type-safe declarations of a fixed set of values. -# -# Every value is a singleton instance of the class (i.e. `Suit::SPADE.is_a?(Suit) == true`). -# -# Each value has a corresponding serialized value. By default this is the constant's name converted -# to lowercase (e.g. `Suit::Club.serialize == 'club'`); however a custom value may be passed to the -# constructor. Enum will `freeze` the serialized value. -# -# @example Declaring an Enum: -# class Suit < T::Enum -# enums do -# CLUB = new -# SPADE = new -# DIAMOND = new -# HEART = new -# end -# end -# -# @example Custom serialization value: -# class Status < T::Enum -# enums do -# READY = new('rdy') -# ... -# end -# end -# -# @example Accessing values: -# Suit::SPADE -# -# @example Converting from serialized value to enum instance: -# Suit.deserialize('club') == Suit::CLUB -# -# @example Using enums in type signatures: -# sig {params(suit: Suit).returns(Boolean)} -# def is_red?(suit); ...; end -# -# WARNING: Enum instances are singletons that are shared among all their users. Their internals -# should be kept immutable to avoid unpredictable action at a distance. -class T::Enum - extend T::Sig - extend T::Props::CustomType - - # TODO(jez) Might want to restrict this, or make subclasses provide this type - SerializedVal = T.type_alias {T.untyped} - private_constant :SerializedVal - - ### Enum class methods ### - sig {returns(T::Array[T.attached_class])} - def self.values - if @values.nil? - raise "Attempting to access values of #{self.class} before it has been initialized." \ - " Enums are not initialized until the 'enums do' block they are defined in has finished running." - end - @values - end - - # This exists for compatibility with the interface of `Hash` & mostly to support - # the HashEachMethods Rubocop. - sig {params(blk: T.nilable(T.proc.params(arg0: T.attached_class).void)).returns(T.any(T::Enumerator[T.attached_class], T::Array[T.attached_class]))} - def self.each_value(&blk) - if blk - values.each(&blk) - else - values.each - end - end - - # Convert from serialized value to enum instance - # - # Note: It would have been nice to make this method final before people started overriding it. - # Note: Failed CriticalMethodsNoRuntimeTypingTest - sig {params(serialized_val: SerializedVal).returns(T.nilable(T.attached_class)).checked(:never)} - def self.try_deserialize(serialized_val) - if @mapping.nil? - raise "Attempting to access serialization map of #{self.class} before it has been initialized." \ - " Enums are not initialized until the 'enums do' block they are defined in has finished running." - end - @mapping[serialized_val] - end - - # Convert from serialized value to enum instance. - # - # Note: It would have been nice to make this method final before people started overriding it. - # Note: Failed CriticalMethodsNoRuntimeTypingTest - # - # @return [self] - # @raise [KeyError] if serialized value does not match any instance. - sig {overridable.params(serialized_val: SerializedVal).returns(T.attached_class).checked(:never)} - def self.from_serialized(serialized_val) - res = try_deserialize(serialized_val) - if res.nil? - raise KeyError.new("Enum #{self} key not found: #{serialized_val.inspect}") - end - res - end - - # Note: It would have been nice to make this method final before people started overriding it. - # @return [Boolean] Does the given serialized value correspond with any of this enum's values. - sig {overridable.params(serialized_val: SerializedVal).returns(T::Boolean).checked(:never)} - def self.has_serialized?(serialized_val) - if @mapping.nil? - raise "Attempting to access serialization map of #{self.class} before it has been initialized." \ - " Enums are not initialized until the 'enums do' block they are defined in has finished running." - end - @mapping.include?(serialized_val) - end - - # Note: Failed CriticalMethodsNoRuntimeTypingTest - sig {override.params(instance: T.nilable(T::Enum)).returns(SerializedVal).checked(:never)} - def self.serialize(instance) - # This is needed otherwise if a Chalk::ODM::Document with a property of the shape - # T::Hash[T.nilable(MyEnum), Integer] and a value that looks like {nil => 0} is - # serialized, we throw the error on L102. - return nil if instance.nil? - - if self == T::Enum - raise "Cannot call T::Enum.serialize directly. You must call on a specific child class." - end - if instance.class != self - raise "Cannot call #serialize on a value that is not an instance of #{self}." - end - instance.serialize - end - - # Note: Failed CriticalMethodsNoRuntimeTypingTest - sig {override.params(mongo_value: SerializedVal).returns(T.attached_class).checked(:never)} - def self.deserialize(mongo_value) - if self == T::Enum - raise "Cannot call T::Enum.deserialize directly. You must call on a specific child class." - end - self.from_serialized(mongo_value) - end - - ### Enum instance methods ### - - sig {returns(T.self_type)} - def dup - self - end - - sig {returns(T.self_type).checked(:tests)} - def clone - self - end - - # Note: Failed CriticalMethodsNoRuntimeTypingTest - sig {returns(SerializedVal).checked(:never)} - def serialize - assert_bound! - @serialized_val - end - - sig {params(args: T.untyped).returns(T.untyped)} - def to_json(*args) - serialize.to_json(*args) - end - - sig {params(args: T.untyped).returns(T.untyped)} - def as_json(*args) - serialized_val = serialize - return serialized_val unless serialized_val.respond_to?(:as_json) - serialized_val.as_json(*args) - end - - sig {returns(String)} - def to_s - inspect - end - - sig {returns(String)} - def inspect - "#<#{self.class.name}::#{@const_name || '__UNINITIALIZED__'}>" - end - - sig {params(other: BasicObject).returns(T.nilable(Integer))} - def <=>(other) - case other - when self.class - self.serialize <=> other.serialize - else - nil - end - end - - # NB: Do not call this method. This exists to allow for a safe migration path in places where enum - # values are compared directly against string values. - # - # Ruby's string has a weird quirk where `'my_string' == obj` calls obj.==('my_string') if obj - # responds to the `to_str` method. It does not actually call `to_str` however. - # - # See https://ruby-doc.org/core-2.4.0/String.html#method-i-3D-3D - sig {returns(String)} - def to_str - msg = 'Implicit conversion of Enum instances to strings is not allowed. Call #serialize instead.' - if T::Configuration.legacy_t_enum_migration_mode? - T::Configuration.soft_assert_handler( - msg, - storytime: {class: self.class.name}, - ) - serialize.to_s - else - raise NoMethodError.new(msg) - end - end - - sig {params(other: BasicObject).returns(T::Boolean).checked(:never)} - def ==(other) - case other - when String - if T::Configuration.legacy_t_enum_migration_mode? - comparison_assertion_failed(:==, other) - self.serialize == other - else - false - end - else - super(other) - end - end - - sig {params(other: BasicObject).returns(T::Boolean).checked(:never)} - def ===(other) - case other - when String - if T::Configuration.legacy_t_enum_migration_mode? - comparison_assertion_failed(:===, other) - self.serialize == other - else - false - end - else - super(other) - end - end - - sig {params(method: Symbol, other: T.untyped).void} - private def comparison_assertion_failed(method, other) - T::Configuration.soft_assert_handler( - 'Enum to string comparison not allowed. Compare to the Enum instance directly instead. See go/enum-migration', - storytime: { - class: self.class.name, - self: self.inspect, - other: other, - other_class: other.class.name, - method: method, - } - ) - end - - ### Private implementation ### - - sig {params(serialized_val: SerializedVal).void} - def initialize(serialized_val=nil) - raise 'T::Enum is abstract' if self.class == T::Enum - if !self.class.started_initializing? - raise "Must instantiate all enum values of #{self.class} inside 'enums do'." - end - if self.class.fully_initialized? - raise "Cannot instantiate a new enum value of #{self.class} after it has been initialized." - end - - serialized_val = serialized_val.frozen? ? serialized_val : serialized_val.dup.freeze - @serialized_val = T.let(serialized_val, T.nilable(SerializedVal)) - @const_name = T.let(nil, T.nilable(Symbol)) - self.class._register_instance(self) - end - - sig {returns(NilClass).checked(:never)} - private def assert_bound! - if @const_name.nil? - raise "Attempting to access Enum value on #{self.class} before it has been initialized." \ - " Enums are not initialized until the 'enums do' block they are defined in has finished running." - end - end - - sig {params(const_name: Symbol).void} - def _bind_name(const_name) - @const_name = const_name - @serialized_val = const_to_serialized_val(const_name) if @serialized_val.nil? - freeze - end - - sig {params(const_name: Symbol).returns(String)} - private def const_to_serialized_val(const_name) - # Historical note: We convert to lowercase names because the majority of existing calls to - # `make_accessible` were arrays of lowercase strings. Doing this conversion allowed for the - # least amount of repetition in migrated declarations. - -const_name.to_s.downcase.freeze - end - - sig {returns(T::Boolean)} - def self.started_initializing? - unless defined?(@started_initializing) - @started_initializing = T.let(false, T.nilable(T::Boolean)) - end - T.must(@started_initializing) - end - - sig {returns(T::Boolean)} - def self.fully_initialized? - unless defined?(@fully_initialized) - @fully_initialized = T.let(false, T.nilable(T::Boolean)) - end - T.must(@fully_initialized) - end - - # Maintains the order in which values are defined - sig {params(instance: T.untyped).void} - def self._register_instance(instance) - @values ||= [] - @values << T.cast(instance, T.attached_class) - end - - # Entrypoint for allowing people to register new enum values. - # All enum values must be defined within this block. - sig {params(blk: T.proc.void).void} - def self.enums(&blk) - raise "enums cannot be defined for T::Enum" if self == T::Enum - raise "Enum #{self} was already initialized" if fully_initialized? - raise "Enum #{self} is still initializing" if started_initializing? - - @started_initializing = true - - @values = T.let(nil, T.nilable(T::Array[T.attached_class])) - - yield - - @mapping = T.let(nil, T.nilable(T::Hash[SerializedVal, T.attached_class])) - @mapping = {} - - # Freeze the Enum class and bind the constant names into each of the instances. - self.constants(false).each do |const_name| - instance = self.const_get(const_name, false) - if !instance.is_a?(self) - raise "Invalid constant #{self}::#{const_name} on enum. " \ - "All constants defined for an enum must be instances itself (e.g. `Foo = new`)." - end - - instance._bind_name(const_name) - serialized = instance.serialize - if @mapping.include?(serialized) - raise "Enum values must have unique serializations. Value '#{serialized}' is repeated on #{self}." - end - @mapping[serialized] = instance - end - @values.freeze - @mapping.freeze - - orphaned_instances = T.must(@values) - @mapping.values - if !orphaned_instances.empty? - raise "Enum values must be assigned to constants: #{orphaned_instances.map {|v| v.instance_variable_get('@serialized_val')}}" - end - - @fully_initialized = true - end - - sig {params(child_class: Module).void} - def self.inherited(child_class) - super - - raise "Inheriting from children of T::Enum is prohibited" if self != T::Enum - end - - # Marshal support - sig {params(_level: Integer).returns(String)} - def _dump(_level) - Marshal.dump(serialize) - end - - sig {params(args: String).returns(T.attached_class)} - def self._load(args) - deserialize(Marshal.load(args)) # rubocop:disable Security/MarshalLoad - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/generic.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/generic.rb deleted file mode 100644 index 58def7aa1a..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/generic.rb +++ /dev/null @@ -1,22 +0,0 @@ -# frozen_string_literal: true -# typed: true - -# Use as a mixin with extend (`extend T::Generic`). -module T::Generic - include T::Helpers - include Kernel - - ### Class/Module Helpers ### - - def [](*types) - self - end - - def type_member(variance=:invariant, &blk) - T::Types::TypeMember.new(variance) - end - - def type_template(variance=:invariant, &blk) - T::Types::TypeTemplate.new(variance) - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/helpers.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/helpers.rb deleted file mode 100644 index 7f326e7384..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/helpers.rb +++ /dev/null @@ -1,58 +0,0 @@ -# frozen_string_literal: true -# typed: true - -# Use as a mixin with extend (`extend T::Helpers`). -# Docs at https://sorbet.org/docs/ -module T::Helpers - extend T::Sig - - Private = T::Private - - ### Class/Module Helpers ### - - def abstract! - Private::Abstract::Declare.declare_abstract(self, type: :abstract) - end - - def interface! - Private::Abstract::Declare.declare_abstract(self, type: :interface) - end - - def final! - Private::Final.declare(self) - end - - def sealed! - Private::Sealed.declare(self, Kernel.caller(1..1)&.first&.split(':')&.first) - end - - # Causes a mixin to also mix in class methods from the named module. - # - # Nearly equivalent to - # - # def self.included(other) - # other.extend(mod) - # end - # - # Except that it is statically analyzed by sorbet. - def mixes_in_class_methods(mod, *mods) - Private::Mixins.declare_mixes_in_class_methods(self, [mod].concat(mods)) - end - - # Specify an inclusion or inheritance requirement for `self`. - # - # Example: - # - # module MyHelper - # extend T::Helpers - # - # requires_ancestor { Kernel } - # end - # - # class MyClass < BasicObject # error: `MyClass` must include `Kernel` (required by `MyHelper`) - # include MyHelper - # end - # - # TODO: implement the checks in sorbet-runtime. - def requires_ancestor(&block); end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/interface_wrapper.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/interface_wrapper.rb deleted file mode 100644 index 82998667f7..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/interface_wrapper.rb +++ /dev/null @@ -1,158 +0,0 @@ -# frozen_string_literal: true -# typed: false - -# Wraps an object, exposing only the methods defined on a given class/module. The idea is that, in -# the absence of a static type checker that would prevent you from calling non-Bar methods on a -# variable of type Bar, we can use these wrappers as a way of enforcing it at runtime. -# -# Once we ship static type checking, we should get rid of this entirely. -class T::InterfaceWrapper - extend T::Sig - - module Helpers - def wrap_instance(obj) - T::InterfaceWrapper.wrap_instance(obj, self) - end - - def wrap_instances(arr) - T::InterfaceWrapper.wrap_instances(arr, self) - end - end - - private_class_method :new # use `wrap_instance` - - def self.wrap_instance(obj, interface_mod) - wrapper = wrapped_dynamic_cast(obj, interface_mod) - if wrapper.nil? - raise "#{obj.class} cannot be cast to #{interface_mod}" - end - wrapper - end - - sig do - params( - arr: Array, - interface_mod: T.untyped - ) - .returns(Array) - end - def self.wrap_instances(arr, interface_mod) - arr.map {|instance| self.wrap_instance(instance, interface_mod)} - end - - def initialize(target_obj, interface_mod) - if target_obj.is_a?(T::InterfaceWrapper) - # wrapped_dynamic_cast should guarantee this never happens. - raise "Unexpected: wrapping a wrapper. Please report this bug at https://github.com/sorbet/sorbet/issues" - end - - if !target_obj.is_a?(interface_mod) - # wrapped_dynamic_cast should guarantee this never happens. - raise "Unexpected: `is_a?` failed. Please report this bug at https://github.com/sorbet/sorbet/issues" - end - - if target_obj.class == interface_mod - # wrapped_dynamic_cast should guarantee this never happens. - raise "Unexpected: exact class match. Please report this bug at https://github.com/sorbet/sorbet/issues" - end - - @target_obj = target_obj - @interface_mod = interface_mod - self_methods = self.class.self_methods - - # If perf becomes an issue, we can define these on an anonymous subclass, and keep a cache - # so we only need to do it once per unique `interface_mod` - T::Utils.methods_excluding_object(interface_mod).each do |method_name| - if self_methods.include?(method_name) - raise "interface_mod has a method that conflicts with #{self.class}: #{method_name}" - end - - define_singleton_method(method_name) do |*args, &blk| - target_obj.send(method_name, *args, &blk) - end - - if target_obj.singleton_class.public_method_defined?(method_name) - # no-op, it's already public - elsif target_obj.singleton_class.protected_method_defined?(method_name) - singleton_class.send(:protected, method_name) - elsif target_obj.singleton_class.private_method_defined?(method_name) - singleton_class.send(:private, method_name) - else - raise "This should never happen. Report this bug at https://github.com/sorbet/sorbet/issues" - end - end - end - - def kind_of?(other) - is_a?(other) - end - - def is_a?(other) - if !other.is_a?(Module) - raise TypeError.new("class or module required") - end - - # This makes is_a? return true for T::InterfaceWrapper (and its ancestors), - # as well as for @interface_mod and its ancestors. - self.class <= other || @interface_mod <= other - end - - # Prefixed because we're polluting the namespace of the interface we're wrapping, and we don't - # want anyone else (besides dynamic_cast) calling it. - def __target_obj_DO_NOT_USE # rubocop:disable Naming/MethodName - @target_obj - end - - # Prefixed because we're polluting the namespace of the interface we're wrapping, and we don't - # want anyone else (besides wrapped_dynamic_cast) calling it. - def __interface_mod_DO_NOT_USE # rubocop:disable Naming/MethodName - @interface_mod - end - - # "Cast" an object to another type. If `obj` is an InterfaceWrapper, returns the the wrapped - # object if that matches `type`. Otherwise, returns `obj` if it matches `type`. Otherwise, - # returns nil. - # - # @param obj [Object] object to cast - # @param mod [Module] type to cast `obj` to - # - # @example - # if (impl = T::InterfaceWrapper.dynamic_cast(iface, MyImplementation)) - # impl.do_things - # end - def self.dynamic_cast(obj, mod) - if obj.is_a?(T::InterfaceWrapper) - target_obj = obj.__target_obj_DO_NOT_USE - target_obj.is_a?(mod) ? target_obj : nil - elsif obj.is_a?(mod) - obj - else - nil - end - end - - # Like dynamic_cast, but puts the result in its own wrapper if necessary. - # - # @param obj [Object] object to cast - # @param mod [Module] type to cast `obj` to - def self.wrapped_dynamic_cast(obj, mod) - # Avoid unwrapping and creating an equivalent wrapper. - if obj.is_a?(T::InterfaceWrapper) && obj.__interface_mod_DO_NOT_USE == mod - return obj - end - - cast_obj = dynamic_cast(obj, mod) - if cast_obj.nil? - nil - elsif cast_obj.class == mod - # Nothing to wrap, they want the full class - cast_obj - else - new(cast_obj, mod) - end - end - - def self.self_methods - @self_methods ||= self.instance_methods(false).to_set - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/non_forcing_constants.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/non_forcing_constants.rb deleted file mode 100644 index 96445357cb..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/non_forcing_constants.rb +++ /dev/null @@ -1,65 +0,0 @@ -# frozen_string_literal: true -# typed: strict - -module T::NonForcingConstants - # NOTE: This method is documented on the RBI in Sorbet's payload, so that it - # shows up in the hover/completion documentation via LSP. - T::Sig::WithoutRuntime.sig {params(val: BasicObject, klass: String, package: T.nilable(String)).returns(T::Boolean)} - def self.non_forcing_is_a?(val, klass, package: nil) - method_name = "T::NonForcingConstants.non_forcing_is_a?" - if klass.empty? - raise ArgumentError.new("The string given to `#{method_name}` must not be empty") - end - - # We don't treat packages differently at runtime, but the static - # type-checker still needs to have the package and constant - # separated out. This just re-assembles the string as needed - if !package.nil? - klass = "::#{package}::#{klass}" - end - - current_klass = T.let(nil, T.nilable(Module)) - current_prefix = T.let(nil, T.nilable(String)) - - parts = klass.split('::') - parts.each do |part| - if current_klass.nil? - # First iteration - if part != "" && package.nil? - # if we've supplied a package, we're probably running in - # package mode, which means absolute references are - # meaningless - raise ArgumentError.new("The string given to `#{method_name}` must be an absolute constant reference that starts with `::`") - end - - current_klass = Object - current_prefix = '' - - # if this had a :: prefix, then there's no more loading to - # do---skip to the next one - next if part == "" - end - - if current_klass.autoload?(part) - # There's an autoload registered for that constant, which means it's not - # yet loaded. `value` can't be an instance of something not yet loaded. - return false - end - - # Sorbet guarantees that the string is an absolutely resolved name. - search_inheritance_chain = false - if !current_klass.const_defined?(part, search_inheritance_chain) - return false - end - - current_klass = current_klass.const_get(part) - current_prefix = "#{current_prefix}::#{part}" - - if !Module.===(current_klass) - raise ArgumentError.new("#{current_prefix} is not a class or module") - end - end - - current_klass.===(val) - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/abstract/data.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/abstract/data.rb deleted file mode 100644 index 2692858ddf..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/abstract/data.rb +++ /dev/null @@ -1,36 +0,0 @@ -# frozen_string_literal: true -# typed: true - -# We need to associate data with abstract modules. We could add instance methods to them that -# access ivars, but those methods will unnecessarily pollute the module namespace, and they'd -# have access to other private state and methods that they don't actually need. We also need to -# associate data with arbitrary classes/modules that implement abstract mixins, where we don't -# control the interface at all. So, we access data via these `get` and `set` methods. -# -# Using instance_variable_get/set here is gross, but the alternative is to use a hash keyed on -# `mod`, and we can't trust that arbitrary modules can be added to those, because there are lurky -# modules that override the `hash` method with something completely broken. -module T::Private::Abstract::Data - def self.get(mod, key) - mod.instance_variable_get("@opus_abstract__#{key}") if key?(mod, key) - end - - def self.set(mod, key, value) - mod.instance_variable_set("@opus_abstract__#{key}", value) - end - - def self.key?(mod, key) - mod.instance_variable_defined?("@opus_abstract__#{key}") - end - - # Works like `setdefault` in Python. If key has already been set, return its value. If not, - # insert `key` with a value of `default` and return `default`. - def self.set_default(mod, key, default) - if self.key?(mod, key) - self.get(mod, key) - else - self.set(mod, key, default) - default - end - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/abstract/declare.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/abstract/declare.rb deleted file mode 100644 index ce8ddf9531..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/abstract/declare.rb +++ /dev/null @@ -1,53 +0,0 @@ -# frozen_string_literal: true -# typed: true - -module T::Private::Abstract::Declare - Abstract = T::Private::Abstract - AbstractUtils = T::AbstractUtils - - def self.declare_abstract(mod, type:) - if AbstractUtils.abstract_module?(mod) - raise "#{mod} is already declared as abstract" - end - if T::Private::Final.final_module?(mod) - raise "#{mod} was already declared as final and cannot be declared as abstract" - end - - Abstract::Data.set(mod, :can_have_abstract_methods, true) - Abstract::Data.set(mod.singleton_class, :can_have_abstract_methods, true) - Abstract::Data.set(mod, :abstract_type, type) - - mod.extend(Abstract::Hooks) - mod.extend(T::InterfaceWrapper::Helpers) - - if mod.is_a?(Class) - if type == :interface - # Since `interface!` is just `abstract!` with some extra validation, we could technically - # allow this, but it's unclear there are good use cases, and it might be confusing. - raise "Classes can't be interfaces. Use `abstract!` instead of `interface!`." - end - - if mod.instance_method(:initialize).owner == mod - raise "You must call `abstract!` *before* defining an initialize method" - end - - # Don't need to silence warnings via without_ruby_warnings when calling - # define_method because of the guard above - - mod.send(:define_method, :initialize) do |*args, &blk| - if self.class == mod - raise "#{mod} is declared as abstract; it cannot be instantiated" - end - super(*args, &blk) - end - - # Ruby doesn not emit "method redefined" warnings for aliased methods - # (more robust than undef_method that would create a small window in which the method doesn't exist) - mod.send(:alias_method, :initialize, :initialize) - - if mod.respond_to?(:ruby2_keywords, true) - mod.send(:ruby2_keywords, :initialize) - end - end - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/abstract/hooks.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/abstract/hooks.rb deleted file mode 100644 index fae9593ae8..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/abstract/hooks.rb +++ /dev/null @@ -1,42 +0,0 @@ -# frozen_string_literal: true -# typed: true - -module T::Private::Abstract::Hooks - # This will become the self.extend_object method on a module that extends Abstract::Hooks. - # It gets called when *that* module gets extended in another class/module (similar to the - # `extended` hook, but this gets calls before the ancestors of `other` get modified, which - # is important for our validation). - private def extend_object(other) - T::Private::Abstract::Data.set(self, :last_used_by, other) - super - end - - # This will become the self.append_features method on a module that extends Abstract::Hooks. - # It gets called when *that* module gets included in another class/module (similar to the - # `included` hook, but this gets calls before the ancestors of `other` get modified, which - # is important for our validation). - private def append_features(other) - T::Private::Abstract::Data.set(self, :last_used_by, other) - super - end - - # This will become the self.inherited method on a class that extends Abstract::Hooks. - # It gets called when *that* class gets inherited by another class. - private def inherited(other) - super - # `self` may not actually be abstract -- it could be a concrete class that inherited from an - # abstract class. We only need to check this in `inherited` because, for modules being included - # or extended, the concrete ones won't have these hooks at all. This is just an optimization. - return if !T::AbstractUtils.abstract_module?(self) - - T::Private::Abstract::Data.set(self, :last_used_by, other) - end - - # This will become the self.prepended method on a module that extends Abstract::Hooks. - # It will get called when *that* module gets prepended in another class/module. - private def prepended(other) - # Prepending abstract methods is weird. You'd only be able to override them via other prepended - # modules, or in subclasses. Punt until we have a use case. - Kernel.raise "Prepending abstract mixins is not currently supported." - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/abstract/validate.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/abstract/validate.rb deleted file mode 100644 index ba0b57775c..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/abstract/validate.rb +++ /dev/null @@ -1,128 +0,0 @@ -# frozen_string_literal: true -# typed: true - -module T::Private::Abstract::Validate - Abstract = T::Private::Abstract - AbstractUtils = T::AbstractUtils - Methods = T::Private::Methods - SignatureValidation = T::Private::Methods::SignatureValidation - - def self.validate_abstract_module(mod) - type = Abstract::Data.get(mod, :abstract_type) - validate_interface(mod) if type == :interface - end - - # Validates a class/module with an abstract class/module as an ancestor. This must be called - # after all methods on `mod` have been defined. - def self.validate_subclass(mod) - can_have_abstract_methods = !T::Private::Abstract::Data.get(mod, :can_have_abstract_methods) - unimplemented_methods = [] - - T::AbstractUtils.declared_abstract_methods_for(mod).each do |abstract_method| - implementation_method = mod.instance_method(abstract_method.name) - if AbstractUtils.abstract_method?(implementation_method) - # Note that when we end up here, implementation_method might not be the same as - # abstract_method; the latter could've been overridden by another abstract method. In either - # case, if we have a concrete definition in an ancestor, that will end up as the effective - # implementation (see CallValidation.wrap_method_if_needed), so that's what we'll validate - # against. - implementation_method = T.unsafe(nil) - mod.ancestors.each do |ancestor| - if ancestor.instance_methods.include?(abstract_method.name) - method = ancestor.instance_method(abstract_method.name) - T::Private::Methods.maybe_run_sig_block_for_method(method) - if !T::AbstractUtils.abstract_method?(method) - implementation_method = method - break - end - end - end - if !implementation_method - # There's no implementation - if can_have_abstract_methods - unimplemented_methods << describe_method(abstract_method) - end - next # Nothing to validate - end - end - - implementation_signature = Methods.signature_for_method(implementation_method) - # When a signature exists and the method is defined directly on `mod`, we skip the validation - # here, because it will have already been done when the method was defined (by - # T::Private::Methods._on_method_added). - next if implementation_signature&.owner == mod - - # We validate the remaining cases here: (a) methods defined directly on `mod` without a - # signature and (b) methods from ancestors (note that these ancestors can come before or - # after the abstract module in the inheritance chain -- the former coming from - # walking `mod.ancestors` above). - abstract_signature = Methods.signature_for_method(abstract_method) - # We allow implementation methods to be defined without a signature. - # In that case, get its untyped signature. - implementation_signature ||= Methods::Signature.new_untyped( - method: implementation_method, - mode: Methods::Modes.override - ) - SignatureValidation.validate_override_shape(implementation_signature, abstract_signature) - SignatureValidation.validate_override_types(implementation_signature, abstract_signature) - end - - method_type = mod.singleton_class? ? "class" : "instance" - if !unimplemented_methods.empty? - raise "Missing implementation for abstract #{method_type} method(s) in #{mod}:\n" \ - "#{unimplemented_methods.join("\n")}\n" \ - "If #{mod} is meant to be an abstract class/module, you can call " \ - "`abstract!` or `interface!`. Otherwise, you must implement the method(s)." - end - end - - private_class_method def self.validate_interface_all_abstract(mod, method_names) - violations = method_names.map do |method_name| - method = mod.instance_method(method_name) - if !AbstractUtils.abstract_method?(method) - describe_method(method, show_owner: false) - end - end.compact - - if !violations.empty? - raise "`#{mod}` is declared as an interface, but the following methods are not declared " \ - "with `abstract`:\n#{violations.join("\n")}" - end - end - - private_class_method def self.validate_interface(mod) - interface_methods = T::Utils.methods_excluding_object(mod) - validate_interface_all_abstract(mod, interface_methods) - validate_interface_all_public(mod, interface_methods) - end - - private_class_method def self.validate_interface_all_public(mod, method_names) - violations = method_names.map do |method_name| - if !mod.public_method_defined?(method_name) - describe_method(mod.instance_method(method_name), show_owner: false) - end - end.compact - - if !violations.empty? - raise "All methods on an interface must be public. If you intend to have non-public " \ - "methods, declare your class/module using `abstract!` instead of `interface!`. " \ - "The following methods on `#{mod}` are not public: \n#{violations.join("\n")}" - end - end - - private_class_method def self.describe_method(method, show_owner: true) - loc = if method.source_location - method.source_location.join(':') - else - "" - end - - owner = if show_owner - " declared in #{method.owner}" - else - "" - end - - " * `#{method.name}`#{owner} at #{loc}" - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/casts.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/casts.rb deleted file mode 100644 index f771090814..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/casts.rb +++ /dev/null @@ -1,41 +0,0 @@ -# frozen_string_literal: true -# typed: false - -module T::Private - module Casts - def self.cast(value, type, cast_method:) - begin - error = T::Utils.coerce(type).error_message_for_obj(value) - return value unless error - - caller_loc = T.must(caller_locations(2..2)).first - - suffix = "Caller: #{T.must(caller_loc).path}:#{T.must(caller_loc).lineno}" - - raise TypeError.new("#{cast_method}: #{error}\n#{suffix}") - rescue TypeError => e # raise into rescue to ensure e.backtrace is populated - T::Configuration.inline_type_error_handler(e, {kind: cast_method, value: value, type: type}) - value - end - end - - # there's a lot of shared logic with the above one, but factoring - # it out like this makes it easier to hopefully one day delete - # this one - def self.cast_recursive(value, type, cast_method:) - begin - error = T::Utils.coerce(type).error_message_for_obj_recursive(value) - return value unless error - - caller_loc = T.must(caller_locations(2..2)).first - - suffix = "Caller: #{T.must(caller_loc).path}:#{T.must(caller_loc).lineno}" - - raise TypeError.new("#{cast_method}: #{error}\n#{suffix}") - rescue TypeError => e # raise into rescue to ensure e.backtrace is populated - T::Configuration.inline_type_error_handler(e, {kind: cast_method, value: value, type: type}) - value - end - end - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/class_utils.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/class_utils.rb deleted file mode 100644 index 269b70cbee..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/class_utils.rb +++ /dev/null @@ -1,110 +0,0 @@ -# frozen_string_literal: true -# typed: false - -# Cut down version of Chalk::Tools::ClassUtils with only :replace_method functionality. -# Extracted to a separate namespace so the type system can be used standalone. -module T::Private::ClassUtils - class ReplacedMethod - def initialize(mod, old_method, new_method, overwritten, visibility) - if old_method.name != new_method.name - raise "Method names must match. old=#{old_method.name} new=#{new_method.name}" - end - @mod = mod - @old_method = old_method - @new_method = new_method - @overwritten = overwritten - @name = old_method.name - @visibility = visibility - @restored = false - end - - def restore - # The check below would also catch this, but this makes the failure mode much clearer - if @restored - raise "Method '#{@name}' on '#{@mod}' was already restored" - end - - if @mod.instance_method(@name) != @new_method - raise "Trying to restore #{@mod}##{@name} but the method has changed since the call to replace_method" - end - - @restored = true - - if @overwritten - # The original method was overwritten. Overwrite again to restore it. - T::Configuration.without_ruby_warnings do - @mod.send(:define_method, @old_method.name, @old_method) - end - else - # The original method was in an ancestor. Restore it by removing the overriding method. - @mod.send(:remove_method, @old_method.name) - end - - # Restore the visibility. Note that we need to do this even when we call remove_method - # above, because the module may have set custom visibility for a method it inherited. - @mod.send(@visibility, @old_method.name) - - nil - end - - def bind(obj) - @old_method.bind(obj) - end - - def to_s - @old_method.to_s - end - end - - # `name` must be an instance method (for class methods, pass in mod.singleton_class) - private_class_method def self.visibility_method_name(mod, name) - if mod.public_method_defined?(name) - :public - elsif mod.protected_method_defined?(name) - :protected - elsif mod.private_method_defined?(name) - :private - else - raise NameError.new("undefined method `#{name}` for `#{mod}`") - end - end - - # Replaces a method, either by overwriting it (if it is defined directly on `mod`) or by - # overriding it (if it is defined by one of mod's ancestors). Returns a ReplacedMethod instance - # on which you can call `bind(...).call(...)` to call the original method, or `restore` to - # restore the original method (by overwriting or removing the override). - def self.replace_method(mod, name, &blk) - original_method = mod.instance_method(name) - original_visibility = visibility_method_name(mod, name) - original_owner = original_method.owner - - mod.ancestors.each do |ancestor| - break if ancestor == mod - if ancestor == original_owner - # If we get here, that means the method we're trying to replace exists on a *prepended* - # mixin, which means in order to supersede it, we'd need to create a method on a new - # module that we'd prepend before `ancestor`. The problem with that approach is there'd - # be no way to remove that new module after prepending it, so we'd be left with these - # empty anonymous modules in the ancestor chain after calling `restore`. - # - # That's not necessarily a deal breaker, but for now, we're keeping it as unsupported. - raise "You're trying to replace `#{name}` on `#{mod}`, but that method exists in a " \ - "prepended module (#{ancestor}), which we don't currently support." - end - end - - overwritten = original_owner == mod - T::Configuration.without_ruby_warnings do - T::Private::DeclState.current.without_on_method_added do - mod.send(:define_method, name, &blk) - if blk.arity < 0 && mod.respond_to?(:ruby2_keywords, true) - mod.send(:ruby2_keywords, name) - end - end - end - mod.send(original_visibility, name) - new_method = mod.instance_method(name) - - ReplacedMethod.new(mod, original_method, new_method, overwritten, original_visibility) - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/compiler.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/compiler.rb deleted file mode 100644 index fed86b40f3..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/compiler.rb +++ /dev/null @@ -1,24 +0,0 @@ -# frozen_string_literal: true -# typed: true - -module T::Private - module Compiler - # If this code ever runs, the caller is running interpreted (or the - # compiler didn't see the call to `running_compiled?` statically.) - # - # The Sorbet Compiler replaces calls to this method unconditionally (no - # runtime guards) to return `true` when compiling a file. - def self.running_compiled? - false - end - - # Returns `nil` because the compiler isn't running. - # - # The Sorbet Compiler replaces calls to this method unconditionally (no - # runtime guards) to return a String showing the Sorbet Compiler's version - # string. - def self.compiler_version - nil - end - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/decl_state.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/decl_state.rb deleted file mode 100644 index 8eeae57e4c..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/decl_state.rb +++ /dev/null @@ -1,30 +0,0 @@ -# frozen_string_literal: true -# typed: true - -class T::Private::DeclState - def self.current - Thread.current[:opus_types__decl_state] ||= self.new - end - - def self.current=(other) - Thread.current[:opus_types__decl_state] = other - end - - attr_accessor :active_declaration - attr_accessor :skip_on_method_added - - def reset! - self.active_declaration = nil - end - - def without_on_method_added - begin - # explicit 'self' is needed here - old_value = self.skip_on_method_added - self.skip_on_method_added = true - yield - ensure - self.skip_on_method_added = old_value - end - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/final.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/final.rb deleted file mode 100644 index 9ca747248e..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/final.rb +++ /dev/null @@ -1,50 +0,0 @@ -# frozen_string_literal: true -# typed: false - -module T::Private::Final - module NoInherit - def inherited(arg) - super(arg) - raise "#{self} was declared as final and cannot be inherited" - end - end - - module NoIncludeExtend - def included(arg) - super(arg) - raise "#{self} was declared as final and cannot be included" - end - - def extended(arg) - super(arg) - raise "#{self} was declared as final and cannot be extended" - end - end - - def self.declare(mod) - if !mod.is_a?(Module) - raise "#{mod} is not a class or module and cannot be declared as final with `final!`" - end - if final_module?(mod) - raise "#{mod} was already declared as final and cannot be re-declared as final" - end - if T::AbstractUtils.abstract_module?(mod) - raise "#{mod} was already declared as abstract and cannot be declared as final" - end - if T::Private::Sealed.sealed_module?(mod) - raise "#{mod} was already declared as sealed and cannot be declared as final" - end - mod.extend(mod.is_a?(Class) ? NoInherit : NoIncludeExtend) - mark_as_final_module(mod) - mark_as_final_module(mod.singleton_class) - T::Private::Methods.install_hooks(mod) - end - - def self.final_module?(mod) - mod.instance_variable_defined?(:@sorbet_final_module) - end - - private_class_method def self.mark_as_final_module(mod) - mod.instance_variable_set(:@sorbet_final_module, true) - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/_methods.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/_methods.rb deleted file mode 100644 index 1720892a95..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/_methods.rb +++ /dev/null @@ -1,581 +0,0 @@ -# frozen_string_literal: true -# typed: false - -module T::Private::Methods - @installed_hooks = {} - @signatures_by_method = {} - @sig_wrappers = {} - @sigs_that_raised = {} - # stores method names that were declared final without regard for where. - # enables early rejection of names that we know can't induce final method violations. - @was_ever_final_names = {} - # maps from a module's object_id to the set of final methods declared in that module. - # we also overload entries slightly: if the value is nil, that means that the - # module has final methods somewhere along its ancestor chain, but does not itself - # have any final methods. - # - # we need the latter information to know whether we need to check along the ancestor - # chain for final method violations. we need the former information because we - # care about exactly where a final method is defined (e.g. including the same module - # twice is permitted). we could do this with two tables, but it seems slightly - # cleaner with a single table. - # Effectively T::Hash[Module, T.nilable(Set))] - @modules_with_final = Hash.new {|hash, key| hash[key] = nil} - # this stores the old [included, extended] hooks for Module and inherited hook for Class that we override when - # enabling final checks for when those hooks are called. the 'hooks' here don't have anything to do with the 'hooks' - # in installed_hooks. - @old_hooks = nil - - ARG_NOT_PROVIDED = Object.new - PROC_TYPE = Object.new - - DeclarationBlock = Struct.new(:mod, :loc, :blk, :final, :raw) - - def self.declare_sig(mod, loc, arg, &blk) - T::Private::DeclState.current.active_declaration = _declare_sig_internal(mod, loc, arg, &blk) - - nil - end - - # See tests for how to use this. But you shouldn't be using this. - def self._declare_sig(mod, arg=nil, &blk) - _declare_sig_internal(mod, caller_locations(1, 1).first, arg, raw: true, &blk) - end - - private_class_method def self._declare_sig_internal(mod, loc, arg, raw: false, &blk) - install_hooks(mod) - - if T::Private::DeclState.current.active_declaration - T::Private::DeclState.current.reset! - raise "You called sig twice without declaring a method in between" - end - - if !arg.nil? && arg != :final - raise "Invalid argument to `sig`: #{arg}" - end - - DeclarationBlock.new(mod, loc, blk, arg == :final, raw) - end - - def self._with_declared_signature(mod, declblock, &blk) - # If declblock is provided, this code is equivalent to the check in - # _declare_sig_internal, above. - # If declblock is not provided and we have an active declaration, we are - # obviously doing something wrong. - if T::Private::DeclState.current.active_declaration - T::Private::DeclState.current.reset! - raise "You called sig twice without declaring a method in between" - end - if declblock - T::Private::DeclState.current.active_declaration = declblock - end - mod.module_exec(&blk) - end - - def self.start_proc - DeclBuilder.new(PROC_TYPE, false) - end - - def self.finalize_proc(decl) - decl.finalized = true - - if decl.mode != Modes.standard - raise "Procs cannot have override/abstract modifiers" - end - if decl.mod != PROC_TYPE - raise "You are passing a DeclBuilder as a type. Did you accidentally use `self` inside a `sig` block?" - end - if decl.returns == ARG_NOT_PROVIDED - raise "Procs must specify a return type" - end - if decl.on_failure != ARG_NOT_PROVIDED - raise "Procs cannot use .on_failure" - end - - if decl.params == ARG_NOT_PROVIDED - decl.params = {} - end - - T::Types::Proc.new(decl.params, decl.returns) - end - - # Returns the signature for a method whose definition was preceded by `sig`. - # - # @param method [UnboundMethod] - # @return [T::Private::Methods::Signature] - def self.signature_for_method(method) - signature_for_key(method_to_key(method)) - end - - private_class_method def self.signature_for_key(key) - maybe_run_sig_block_for_key(key) - - # If a subclass Sub inherits a method `foo` from Base, then - # Sub.instance_method(:foo) != Base.instance_method(:foo) even though they resolve to the - # same method. Similarly, Foo.method(:bar) != Foo.singleton_class.instance_method(:bar). - # So, we always do the look up by the method on the owner (Base in this example). - @signatures_by_method[key] - end - - # when target includes a module with instance methods source_method_names, ensure there is zero intersection between - # the final instance methods of target and source_method_names. so, for every m in source_method_names, check if there - # is already a method defined on one of target_ancestors with the same name that is final. - # - # we assume that source_method_names has already been filtered to only include method - # names that were declared final at one point. - def self._check_final_ancestors(target, target_ancestors, source_method_names, source) - source_ancestors = nil - # use reverse_each to check farther-up ancestors first, for better error messages. - target_ancestors.reverse_each do |ancestor| - final_methods = @modules_with_final.fetch(ancestor.object_id, nil) - # In this case, either ancestor didn't have any final methods anywhere in its - # ancestor chain, or ancestor did have final methods somewhere in its ancestor - # chain, but no final methods defined in ancestor itself. Either way, there - # are no final methods to check here, so we can move on to the next ancestor. - next unless final_methods - source_method_names.each do |method_name| - next unless final_methods.include?(method_name) - - # If we get here, we are defining a method that some ancestor declared as - # final. however, we permit a final method to be defined multiple - # times if it is the same final method being defined each time. - if source - if !source_ancestors - source_ancestors = source.ancestors - # filter out things without actual final methods just to make sure that - # the below checks (which should be uncommon) go as quickly as possible. - source_ancestors.select! do |a| - @modules_with_final.fetch(a.object_id, nil) - end - end - # final-ness means that there should be no more than one index for which - # the below block returns true. - defining_ancestor_idx = source_ancestors.index do |a| - @modules_with_final.fetch(a.object_id).include?(method_name) - end - next if defining_ancestor_idx && source_ancestors[defining_ancestor_idx] == ancestor - end - - definition_file, definition_line = T::Private::Methods.signature_for_method(ancestor.instance_method(method_name)).method.source_location - is_redefined = target == ancestor - caller_loc = caller_locations&.find {|l| !l.to_s.match?(%r{sorbet-runtime[^/]*/lib/})} - extra_info = "\n" - if caller_loc - extra_info = (is_redefined ? "Redefined" : "Overridden") + " here: #{caller_loc.path}:#{caller_loc.lineno}\n" - end - - error_message = "The method `#{method_name}` on #{ancestor} was declared as final and cannot be " + - (is_redefined ? "redefined" : "overridden in #{target}") - pretty_message = "#{error_message}\n" \ - "Made final here: #{definition_file}:#{definition_line}\n" \ - "#{extra_info}" - - begin - raise pretty_message - rescue => e - # sig_validation_error_handler raises by default; on the off chance that - # it doesn't raise, we need to ensure that the rest of signature building - # sees a consistent state. This sig failed to validate, so we should get - # rid of it. If we don't do this, errors of the form "You called sig - # twice without declaring a method in between" will non-deterministically - # crop up in tests. - T::Private::DeclState.current.reset! - T::Configuration.sig_validation_error_handler(e, {}) - end - end - end - end - - def self.add_module_with_final_method(mod, method_name, is_singleton_method) - m = is_singleton_method ? mod.singleton_class : mod - mid = m.object_id - methods = @modules_with_final[mid] - if methods.nil? - methods = {} - @modules_with_final[mid] = methods - end - methods[method_name] = true - nil - end - - def self.note_module_deals_with_final(mod) - # Side-effectfully initialize the value if it's not already there - @modules_with_final[mod.object_id] - @modules_with_final[mod.singleton_class.object_id] - end - - # Only public because it needs to get called below inside the replace_method blocks below. - def self._on_method_added(hook_mod, method_name, is_singleton_method: false) - if T::Private::DeclState.current.skip_on_method_added - return - end - - current_declaration = T::Private::DeclState.current.active_declaration - mod = is_singleton_method ? hook_mod.singleton_class : hook_mod - - if T::Private::Final.final_module?(mod) && (current_declaration.nil? || !current_declaration.final) - raise "#{mod} was declared as final but its method `#{method_name}` was not declared as final" - end - # Don't compute mod.ancestors if we don't need to bother checking final-ness. - if @was_ever_final_names.include?(method_name) && @modules_with_final.include?(mod.object_id) - _check_final_ancestors(mod, mod.ancestors, [method_name], nil) - # We need to fetch the active declaration again, as _check_final_ancestors - # may have reset it (see the comment in that method for details). - current_declaration = T::Private::DeclState.current.active_declaration - end - - if current_declaration.nil? - return - end - T::Private::DeclState.current.reset! - - if method_name == :method_added || method_name == :singleton_method_added - raise( - "Putting a `sig` on `#{method_name}` is not supported" \ - " (sorbet-runtime uses this method internally to perform `sig` validation logic)" - ) - end - - original_method = mod.instance_method(method_name) - sig_block = lambda do - T::Private::Methods.run_sig(hook_mod, method_name, original_method, current_declaration) - end - - # Always replace the original method with this wrapper, - # which is called only on the *first* invocation. - # This wrapper is very slow, so it will subsequently re-wrap with a much faster wrapper - # (or unwrap back to the original method). - key = method_owner_and_name_to_key(mod, method_name) - unless current_declaration.raw - T::Private::ClassUtils.replace_method(mod, method_name) do |*args, &blk| - method_sig = T::Private::Methods.maybe_run_sig_block_for_key(key) - method_sig ||= T::Private::Methods._handle_missing_method_signature( - self, - original_method, - __callee__, - ) - - # Should be the same logic as CallValidation.wrap_method_if_needed but we - # don't want that extra layer of indirection in the callstack - if method_sig.mode == T::Private::Methods::Modes.abstract - # We're in an interface method, keep going up the chain - if defined?(super) - super(*args, &blk) - else - raise NotImplementedError.new("The method `#{method_sig.method_name}` on #{mod} is declared as `abstract`. It does not have an implementation.") - end - # Note, this logic is duplicated (intentionally, for micro-perf) at `CallValidation.wrap_method_if_needed`, - # make sure to keep changes in sync. - elsif method_sig.check_level == :always || (method_sig.check_level == :tests && T::Private::RuntimeLevels.check_tests?) - CallValidation.validate_call(self, original_method, method_sig, args, blk) - elsif T::Configuration::AT_LEAST_RUBY_2_7 - original_method.bind_call(self, *args, &blk) - else - original_method.bind(self).call(*args, &blk) - end - end - end - - @sig_wrappers[key] = sig_block - if current_declaration.final - @was_ever_final_names[method_name] = true - # use hook_mod, not mod, because for example, we want class C to be marked as having final if we def C.foo as - # final. change this to mod to see some final_method tests fail. - note_module_deals_with_final(hook_mod) - add_module_with_final_method(hook_mod, method_name, is_singleton_method) - end - end - - def self._handle_missing_method_signature(receiver, original_method, callee) - method_sig = T::Private::Methods.signature_for_method(original_method) - if !method_sig - raise "`sig` not present for method `#{callee}` on #{receiver.inspect} but you're trying to run it anyways. " \ - "This should only be executed if you used `alias_method` to grab a handle to a method after `sig`ing it, but that clearly isn't what you are doing. " \ - "Maybe look to see if an exception was thrown in your `sig` lambda or somehow else your `sig` wasn't actually applied to the method." - end - - if receiver.class <= original_method.owner - receiving_class = receiver.class - elsif receiver.singleton_class <= original_method.owner - receiving_class = receiver.singleton_class - elsif receiver.is_a?(Module) && receiver <= original_method.owner - receiving_class = receiver - else - raise "#{receiver} is not related to #{original_method} - how did we get here?" - end - - # Check for a case where `alias` or `alias_method` was called for a - # method which had already had a `sig` applied. In that case, we want - # to avoid hitting this slow path again, by moving to a faster validator - # just like we did or will for the original method. - # - # If this isn't an `alias` or `alias_method` case, we're probably in the - # middle of some metaprogramming using a Method object, e.g. a pattern like - # `arr.map(&method(:foo))`. There's nothing really we can do to optimize - # that here. - receiving_method = receiving_class.instance_method(callee) - if receiving_method != original_method && receiving_method.original_name == original_method.name - aliasing_mod = receiving_method.owner - method_sig = method_sig.as_alias(callee) - unwrap_method(aliasing_mod, method_sig, original_method) - end - - method_sig - end - - # Executes the `sig` block, and converts the resulting Declaration - # to a Signature. - def self.run_sig(hook_mod, method_name, original_method, declaration_block) - current_declaration = - begin - run_builder(declaration_block) - rescue DeclBuilder::BuilderError => e - T::Configuration.sig_builder_error_handler(e, declaration_block.loc) - nil - end - - signature = - if current_declaration - build_sig(hook_mod, method_name, original_method, current_declaration, declaration_block.loc) - else - Signature.new_untyped(method: original_method) - end - - unwrap_method(signature.method.owner, signature, original_method) - signature - end - - def self.run_builder(declaration_block) - builder = DeclBuilder.new(declaration_block.mod, declaration_block.raw) - builder - .instance_exec(&declaration_block.blk) - .finalize! - .decl - end - - def self.build_sig(hook_mod, method_name, original_method, current_declaration, loc) - begin - # We allow `sig` in the current module's context (normal case) and - if hook_mod != current_declaration.mod && - # inside `class << self`, and - hook_mod.singleton_class != current_declaration.mod && - # on `self` at the top level of a file - current_declaration.mod != TOP_SELF - raise "A method (#{method_name}) is being added on a different class/module (#{hook_mod}) than the " \ - "last call to `sig` (#{current_declaration.mod}). Make sure each call " \ - "to `sig` is immediately followed by a method definition on the same " \ - "class/module." - end - - signature = Signature.new( - method: original_method, - method_name: method_name, - raw_arg_types: current_declaration.params, - raw_return_type: current_declaration.returns, - bind: current_declaration.bind, - mode: current_declaration.mode, - check_level: current_declaration.checked, - on_failure: current_declaration.on_failure, - override_allow_incompatible: current_declaration.override_allow_incompatible, - defined_raw: current_declaration.raw, - ) - - SignatureValidation.validate(signature) - signature - rescue => e - super_method = original_method&.super_method - super_signature = signature_for_method(super_method) if super_method - - T::Configuration.sig_validation_error_handler( - e, - method: original_method, - declaration: current_declaration, - signature: signature, - super_signature: super_signature - ) - - Signature.new_untyped(method: original_method) - end - end - - def self.unwrap_method(mod, signature, original_method) - maybe_wrapped_method = CallValidation.wrap_method_if_needed(mod, signature, original_method) - @signatures_by_method[method_to_key(maybe_wrapped_method)] = signature - end - - def self.has_sig_block_for_method(method) - has_sig_block_for_key(method_to_key(method)) - end - - private_class_method def self.has_sig_block_for_key(key) - @sig_wrappers.key?(key) - end - - def self.maybe_run_sig_block_for_method(method) - maybe_run_sig_block_for_key(method_to_key(method)) - end - - # Only public so that it can be accessed in the closure for _on_method_added - def self.maybe_run_sig_block_for_key(key) - run_sig_block_for_key(key) if has_sig_block_for_key(key) - end - - def self.run_sig_block_for_method(method) - run_sig_block_for_key(method_to_key(method)) - end - - private_class_method def self.run_sig_block_for_key(key) - blk = @sig_wrappers[key] - if !blk - sig = @signatures_by_method[key] - if sig - # We already ran the sig block, perhaps in another thread. - return sig - else - raise "No `sig` wrapper for #{key_to_method(key)}" - end - end - - begin - sig = blk.call - rescue - @sigs_that_raised[key] = true - raise - end - if @sigs_that_raised[key] - raise "A previous invocation of #{key_to_method(key)} raised, and the current one succeeded. Please don't do that." - end - - @sig_wrappers.delete(key) - sig - end - - def self.run_all_sig_blocks - loop do - break if @sig_wrappers.empty? - key, = @sig_wrappers.first - run_sig_block_for_key(key) - end - end - - def self.all_checked_tests_sigs - @signatures_by_method.values.select {|sig| sig.check_level == :tests} - end - - # the module target is adding the methods from the module source to itself. we need to check that for all instance - # methods M on source, M is not defined on any of target's ancestors. - def self._hook_impl(target, singleton_class, source) - # we do not need to call add_was_ever_final here, because we have already marked - # any such methods when source was originally defined. - if !@modules_with_final.include?(target.object_id) - if !@modules_with_final.include?(source.object_id) - return - end - note_module_deals_with_final(target) - install_hooks(target) - return - end - - methods = source.instance_methods - methods.select! do |method_name| - @was_ever_final_names.include?(method_name) - end - if methods.empty? - return - end - - target_ancestors = singleton_class ? target.singleton_class.ancestors : target.ancestors - _check_final_ancestors(target, target_ancestors, methods, source) - end - - def self.set_final_checks_on_hooks(enable) - is_enabled = !@old_hooks.nil? - if enable == is_enabled - return - end - if is_enabled - @old_hooks.each(&:restore) - @old_hooks = nil - else - old_included = T::Private::ClassUtils.replace_method(Module, :included) do |arg| - old_included.bind(self).call(arg) - ::T::Private::Methods._hook_impl(arg, false, self) - end - old_extended = T::Private::ClassUtils.replace_method(Module, :extended) do |arg| - old_extended.bind(self).call(arg) - ::T::Private::Methods._hook_impl(arg, true, self) - end - old_inherited = T::Private::ClassUtils.replace_method(Class, :inherited) do |arg| - old_inherited.bind(self).call(arg) - ::T::Private::Methods._hook_impl(arg, false, self) - end - @old_hooks = [old_included, old_extended, old_inherited] - end - end - - module MethodHooks - def method_added(name) - super(name) - ::T::Private::Methods._on_method_added(self, name, is_singleton_method: false) - end - end - - module SingletonMethodHooks - def singleton_method_added(name) - super(name) - ::T::Private::Methods._on_method_added(self, name, is_singleton_method: true) - end - end - - def self.install_hooks(mod) - return if @installed_hooks.include?(mod) - @installed_hooks[mod] = true - - if mod == TOP_SELF - # self at the top-level of a file is weirdly special in Ruby - # The Ruby VM on startup creates an `Object.new` and stashes it. - # Unlike when we're using sig inside a module, `self` is actually a - # normal object, not an instance of Module. - # - # Thus we can't ask things like mod.singleton_class? (since that's - # defined only on Module, not on Object) and even if we could, the places - # where we need to install the hooks are special. - mod.extend(SingletonMethodHooks) # def self.foo; end (at top level) - Object.extend(MethodHooks) # def foo; end (at top level) - return - end - - # See https://github.com/sorbet/sorbet/pull/3964 for an explanation of why this - # check (which theoretically should not be needed) is actually needed. - if !mod.is_a?(Module) - return - end - - if mod.singleton_class? - mod.include(SingletonMethodHooks) - else - mod.extend(MethodHooks) - end - mod.extend(SingletonMethodHooks) - end - - # use this directly if you don't want/need to box up the method into an object to pass to method_to_key. - private_class_method def self.method_owner_and_name_to_key(owner, name) - "#{owner.object_id}##{name}" - end - - private_class_method def self.method_to_key(method) - method_owner_and_name_to_key(method.owner, method.name) - end - - private_class_method def self.key_to_method(key) - id, name = key.split("#") - obj = ObjectSpace._id2ref(id.to_i) - obj.instance_method(name) - end -end - -# This has to be here, and can't be nested inside `T::Private::Methods`, -# because the value of `self` depends on lexical (nesting) scope, and we -# specifically need a reference to the file-level self, i.e. `main:Object` -T::Private::Methods::TOP_SELF = self diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/call_validation.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/call_validation.rb deleted file mode 100644 index 1889daa991..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/call_validation.rb +++ /dev/null @@ -1,221 +0,0 @@ -# frozen_string_literal: true -# typed: false - -module T::Private::Methods::CallValidation - CallValidation = T::Private::Methods::CallValidation - Modes = T::Private::Methods::Modes - - # Wraps a method with a layer of validation for the given type signature. - # This wrapper is meant to be fast, and is applied by a previous wrapper, - # which was placed by `_on_method_added`. - # - # @param method_sig [T::Private::Methods::Signature] - # @return [UnboundMethod] the new wrapper method (or the original one if we didn't wrap it) - def self.wrap_method_if_needed(mod, method_sig, original_method) - original_visibility = visibility_method_name(mod, method_sig.method_name) - if method_sig.mode == T::Private::Methods::Modes.abstract - T::Private::ClassUtils.replace_method(mod, method_sig.method_name) do |*args, &blk| - # TODO: write a cop to ensure that abstract methods have an empty body - # - # We allow abstract methods to be implemented by things further down the ancestor chain. - # So, if a super method exists, call it. - if defined?(super) - super(*args, &blk) - else - raise NotImplementedError.new( - "The method `#{method_sig.method_name}` on #{mod} is declared as `abstract`. It does not have an implementation." - ) - end - end - # Do nothing in this case; this method was not wrapped in _on_method_added. - elsif method_sig.defined_raw - # Note, this logic is duplicated (intentionally, for micro-perf) at `Methods._on_method_added`, - # make sure to keep changes in sync. - # This is a trapdoor point for each method: - # if a given method is wrapped, it stays wrapped; and if not, it's never wrapped. - # (Therefore, we need the `@wrapped_tests_with_validation` check in `T::RuntimeLevels`.) - elsif method_sig.check_level == :always || (method_sig.check_level == :tests && T::Private::RuntimeLevels.check_tests?) - create_validator_method(mod, original_method, method_sig, original_visibility) - else - T::Configuration.without_ruby_warnings do - # get all the shims out of the way and put back the original method - T::Private::DeclState.current.without_on_method_added do - mod.send(:define_method, method_sig.method_name, original_method) - end - mod.send(original_visibility, method_sig.method_name) - end - end - # Return the newly created method (or the original one if we didn't replace it) - mod.instance_method(method_sig.method_name) - end - - @is_allowed_to_have_fast_path = true - def self.is_allowed_to_have_fast_path - @is_allowed_to_have_fast_path - end - - def self.disable_fast_path - @is_allowed_to_have_fast_path = false - end - - def self.create_validator_method(mod, original_method, method_sig, original_visibility) - has_fixed_arity = method_sig.kwarg_types.empty? && !method_sig.has_rest && !method_sig.has_keyrest && - original_method.parameters.all? {|(kind, _name)| kind == :req} - ok_for_fast_path = has_fixed_arity && !method_sig.bind && method_sig.arg_types.length < 5 && is_allowed_to_have_fast_path - - all_args_are_simple = ok_for_fast_path && method_sig.arg_types.all? {|_name, type| type.is_a?(T::Types::Simple)} - simple_method = all_args_are_simple && method_sig.return_type.is_a?(T::Types::Simple) - simple_procedure = all_args_are_simple && method_sig.return_type.is_a?(T::Private::Types::Void) - - T::Configuration.without_ruby_warnings do - T::Private::DeclState.current.without_on_method_added do - if simple_method - create_validator_method_fast(mod, original_method, method_sig) - elsif simple_procedure - create_validator_procedure_fast(mod, original_method, method_sig) - elsif ok_for_fast_path && method_sig.return_type.is_a?(T::Private::Types::Void) - create_validator_procedure_medium(mod, original_method, method_sig) - elsif ok_for_fast_path - create_validator_method_medium(mod, original_method, method_sig) - else - create_validator_slow(mod, original_method, method_sig) - end - end - end - mod.send(original_visibility, method_sig.method_name) - end - - def self.create_validator_slow(mod, original_method, method_sig) - mod.send(:define_method, method_sig.method_name) do |*args, &blk| - CallValidation.validate_call(self, original_method, method_sig, args, blk) - end - if mod.respond_to?(:ruby2_keywords, true) - mod.send(:ruby2_keywords, method_sig.method_name) - end - end - - def self.validate_call(instance, original_method, method_sig, args, blk) - # This method is called for every `sig`. It's critical to keep it fast and - # reduce number of allocations that happen here. - - if method_sig.bind - message = method_sig.bind.error_message_for_obj(instance) - if message - CallValidation.report_error( - method_sig, - message, - 'Bind', - nil, - method_sig.bind, - instance - ) - end - end - - # NOTE: We don't bother validating for missing or extra kwargs; - # the method call itself will take care of that. - method_sig.each_args_value_type(args) do |name, arg, type| - message = type.error_message_for_obj(arg) - if message - CallValidation.report_error( - method_sig, - message, - 'Parameter', - name, - type, - arg, - caller_offset: 2 - ) - end - end - - if method_sig.block_type - message = method_sig.block_type.error_message_for_obj(blk) - if message - CallValidation.report_error( - method_sig, - message, - 'Block parameter', - method_sig.block_name, - method_sig.block_type, - blk - ) - end - end - - # The following line breaks are intentional to show nice pry message - - - - - - - - - - - # PRY note: - # this code is sig validation code. - # Please issue `finish` to step out of it - - return_value = T::Configuration::AT_LEAST_RUBY_2_7 ? original_method.bind_call(instance, *args, &blk) : original_method.bind(instance).call(*args, &blk) - - # The only type that is allowed to change the return value is `.void`. - # It ignores what you returned and changes it to be a private singleton. - if method_sig.return_type.is_a?(T::Private::Types::Void) - T::Private::Types::Void::VOID - else - message = method_sig.return_type.error_message_for_obj(return_value) - if message - CallValidation.report_error( - method_sig, - message, - 'Return value', - nil, - method_sig.return_type, - return_value, - ) - end - return_value - end - end - - def self.report_error(method_sig, error_message, kind, name, type, value, caller_offset: 0) - caller_loc = T.must(caller_locations(3 + caller_offset, 1))[0] - definition_file, definition_line = method_sig.method.source_location - - pretty_message = "#{kind}#{name ? " '#{name}'" : ''}: #{error_message}\n" \ - "Caller: #{caller_loc.path}:#{caller_loc.lineno}\n" \ - "Definition: #{definition_file}:#{definition_line}" - - T::Configuration.call_validation_error_handler( - method_sig, - message: error_message, - pretty_message: pretty_message, - kind: kind, - name: name, - type: type, - value: value, - location: caller_loc - ) - end - - # `name` must be an instance method (for class methods, pass in mod.singleton_class) - private_class_method def self.visibility_method_name(mod, name) - if mod.public_method_defined?(name) - :public - elsif mod.protected_method_defined?(name) - :protected - elsif mod.private_method_defined?(name) - :private - else - raise NameError.new("undefined method `#{name}` for `#{mod}`") - end - end -end - -if T::Configuration::AT_LEAST_RUBY_2_7 - require_relative './call_validation_2_7' -else - require_relative './call_validation_2_6' -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/call_validation_2_6.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/call_validation_2_6.rb deleted file mode 100644 index 753580dc36..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/call_validation_2_6.rb +++ /dev/null @@ -1,1203 +0,0 @@ -# frozen_string_literal: true -# typed: false - -# DO NOT EDIT. This file is autogenerated. To regenerate, run: -# -# bazel test //gems/sorbet-runtime:update_call_validation - -module T::Private::Methods::CallValidation - def self.create_validator_method_fast(mod, original_method, method_sig) - if method_sig.return_type.is_a?(T::Private::Types::Void) - raise 'Should have used create_validator_procedure_fast' - end - # trampoline to reduce stack frame size - if method_sig.arg_types.empty? - create_validator_method_fast0(mod, original_method, method_sig, method_sig.return_type.raw_type) - elsif method_sig.arg_types.length == 1 - create_validator_method_fast1(mod, original_method, method_sig, method_sig.return_type.raw_type, - method_sig.arg_types[0][1].raw_type) - elsif method_sig.arg_types.length == 2 - create_validator_method_fast2(mod, original_method, method_sig, method_sig.return_type.raw_type, - method_sig.arg_types[0][1].raw_type, - method_sig.arg_types[1][1].raw_type) - elsif method_sig.arg_types.length == 3 - create_validator_method_fast3(mod, original_method, method_sig, method_sig.return_type.raw_type, - method_sig.arg_types[0][1].raw_type, - method_sig.arg_types[1][1].raw_type, - method_sig.arg_types[2][1].raw_type) - elsif method_sig.arg_types.length == 4 - create_validator_method_fast4(mod, original_method, method_sig, method_sig.return_type.raw_type, - method_sig.arg_types[0][1].raw_type, - method_sig.arg_types[1][1].raw_type, - method_sig.arg_types[2][1].raw_type, - method_sig.arg_types[3][1].raw_type) - else - raise 'should not happen' - end - end - - def self.create_validator_method_fast0(mod, original_method, method_sig, return_type) - mod.send(:define_method, method_sig.method_name) do |&blk| - # This method is a manually sped-up version of more general code in `validate_call` - # The following line breaks are intentional to show nice pry message - - - - - - - - - - - # PRY note: - # this code is sig validation code. - # Please issue `finish` to step out of it - - return_value = original_method.bind(self).call(&blk) - unless return_value.is_a?(return_type) - message = method_sig.return_type.error_message_for_obj(return_value) - if message - CallValidation.report_error( - method_sig, - message, - 'Return value', - nil, - method_sig.return_type, - return_value, - caller_offset: -1 - ) - end - end - return_value - end - end - - def self.create_validator_method_fast1(mod, original_method, method_sig, return_type, arg0_type) - mod.send(:define_method, method_sig.method_name) do |arg0, &blk| - # This method is a manually sped-up version of more general code in `validate_call` - unless arg0.is_a?(arg0_type) - CallValidation.report_error( - method_sig, - method_sig.arg_types[0][1].error_message_for_obj(arg0), - 'Parameter', - method_sig.arg_types[0][0], - arg0_type, - arg0, - caller_offset: -1 - ) - end - - # The following line breaks are intentional to show nice pry message - - - - - - - - - - - # PRY note: - # this code is sig validation code. - # Please issue `finish` to step out of it - - return_value = original_method.bind(self).call(arg0, &blk) - unless return_value.is_a?(return_type) - message = method_sig.return_type.error_message_for_obj(return_value) - if message - CallValidation.report_error( - method_sig, - message, - 'Return value', - nil, - method_sig.return_type, - return_value, - caller_offset: -1 - ) - end - end - return_value - end - end - - def self.create_validator_method_fast2(mod, original_method, method_sig, return_type, arg0_type, arg1_type) - mod.send(:define_method, method_sig.method_name) do |arg0, arg1, &blk| - # This method is a manually sped-up version of more general code in `validate_call` - unless arg0.is_a?(arg0_type) - CallValidation.report_error( - method_sig, - method_sig.arg_types[0][1].error_message_for_obj(arg0), - 'Parameter', - method_sig.arg_types[0][0], - arg0_type, - arg0, - caller_offset: -1 - ) - end - - unless arg1.is_a?(arg1_type) - CallValidation.report_error( - method_sig, - method_sig.arg_types[1][1].error_message_for_obj(arg1), - 'Parameter', - method_sig.arg_types[1][0], - arg1_type, - arg1, - caller_offset: -1 - ) - end - - # The following line breaks are intentional to show nice pry message - - - - - - - - - - - # PRY note: - # this code is sig validation code. - # Please issue `finish` to step out of it - - return_value = original_method.bind(self).call(arg0, arg1, &blk) - unless return_value.is_a?(return_type) - message = method_sig.return_type.error_message_for_obj(return_value) - if message - CallValidation.report_error( - method_sig, - message, - 'Return value', - nil, - method_sig.return_type, - return_value, - caller_offset: -1 - ) - end - end - return_value - end - end - - def self.create_validator_method_fast3(mod, original_method, method_sig, return_type, arg0_type, arg1_type, arg2_type) - mod.send(:define_method, method_sig.method_name) do |arg0, arg1, arg2, &blk| - # This method is a manually sped-up version of more general code in `validate_call` - unless arg0.is_a?(arg0_type) - CallValidation.report_error( - method_sig, - method_sig.arg_types[0][1].error_message_for_obj(arg0), - 'Parameter', - method_sig.arg_types[0][0], - arg0_type, - arg0, - caller_offset: -1 - ) - end - - unless arg1.is_a?(arg1_type) - CallValidation.report_error( - method_sig, - method_sig.arg_types[1][1].error_message_for_obj(arg1), - 'Parameter', - method_sig.arg_types[1][0], - arg1_type, - arg1, - caller_offset: -1 - ) - end - - unless arg2.is_a?(arg2_type) - CallValidation.report_error( - method_sig, - method_sig.arg_types[2][1].error_message_for_obj(arg2), - 'Parameter', - method_sig.arg_types[2][0], - arg2_type, - arg2, - caller_offset: -1 - ) - end - - # The following line breaks are intentional to show nice pry message - - - - - - - - - - - # PRY note: - # this code is sig validation code. - # Please issue `finish` to step out of it - - return_value = original_method.bind(self).call(arg0, arg1, arg2, &blk) - unless return_value.is_a?(return_type) - message = method_sig.return_type.error_message_for_obj(return_value) - if message - CallValidation.report_error( - method_sig, - message, - 'Return value', - nil, - method_sig.return_type, - return_value, - caller_offset: -1 - ) - end - end - return_value - end - end - - def self.create_validator_method_fast4(mod, original_method, method_sig, return_type, arg0_type, arg1_type, arg2_type, arg3_type) - mod.send(:define_method, method_sig.method_name) do |arg0, arg1, arg2, arg3, &blk| - # This method is a manually sped-up version of more general code in `validate_call` - unless arg0.is_a?(arg0_type) - CallValidation.report_error( - method_sig, - method_sig.arg_types[0][1].error_message_for_obj(arg0), - 'Parameter', - method_sig.arg_types[0][0], - arg0_type, - arg0, - caller_offset: -1 - ) - end - - unless arg1.is_a?(arg1_type) - CallValidation.report_error( - method_sig, - method_sig.arg_types[1][1].error_message_for_obj(arg1), - 'Parameter', - method_sig.arg_types[1][0], - arg1_type, - arg1, - caller_offset: -1 - ) - end - - unless arg2.is_a?(arg2_type) - CallValidation.report_error( - method_sig, - method_sig.arg_types[2][1].error_message_for_obj(arg2), - 'Parameter', - method_sig.arg_types[2][0], - arg2_type, - arg2, - caller_offset: -1 - ) - end - - unless arg3.is_a?(arg3_type) - CallValidation.report_error( - method_sig, - method_sig.arg_types[3][1].error_message_for_obj(arg3), - 'Parameter', - method_sig.arg_types[3][0], - arg3_type, - arg3, - caller_offset: -1 - ) - end - - # The following line breaks are intentional to show nice pry message - - - - - - - - - - - # PRY note: - # this code is sig validation code. - # Please issue `finish` to step out of it - - return_value = original_method.bind(self).call(arg0, arg1, arg2, arg3, &blk) - unless return_value.is_a?(return_type) - message = method_sig.return_type.error_message_for_obj(return_value) - if message - CallValidation.report_error( - method_sig, - message, - 'Return value', - nil, - method_sig.return_type, - return_value, - caller_offset: -1 - ) - end - end - return_value - end - end - - def self.create_validator_procedure_fast(mod, original_method, method_sig) - # trampoline to reduce stack frame size - if method_sig.arg_types.empty? - create_validator_procedure_fast0(mod, original_method, method_sig) - elsif method_sig.arg_types.length == 1 - create_validator_procedure_fast1(mod, original_method, method_sig, - method_sig.arg_types[0][1].raw_type) - elsif method_sig.arg_types.length == 2 - create_validator_procedure_fast2(mod, original_method, method_sig, - method_sig.arg_types[0][1].raw_type, - method_sig.arg_types[1][1].raw_type) - elsif method_sig.arg_types.length == 3 - create_validator_procedure_fast3(mod, original_method, method_sig, - method_sig.arg_types[0][1].raw_type, - method_sig.arg_types[1][1].raw_type, - method_sig.arg_types[2][1].raw_type) - elsif method_sig.arg_types.length == 4 - create_validator_procedure_fast4(mod, original_method, method_sig, - method_sig.arg_types[0][1].raw_type, - method_sig.arg_types[1][1].raw_type, - method_sig.arg_types[2][1].raw_type, - method_sig.arg_types[3][1].raw_type) - else - raise 'should not happen' - end - end - - def self.create_validator_procedure_fast0(mod, original_method, method_sig) - mod.send(:define_method, method_sig.method_name) do |&blk| - # This method is a manually sped-up version of more general code in `validate_call` - # The following line breaks are intentional to show nice pry message - - - - - - - - - - - # PRY note: - # this code is sig validation code. - # Please issue `finish` to step out of it - - original_method.bind(self).call(&blk) - T::Private::Types::Void::VOID - end - end - - def self.create_validator_procedure_fast1(mod, original_method, method_sig, arg0_type) - mod.send(:define_method, method_sig.method_name) do |arg0, &blk| - # This method is a manually sped-up version of more general code in `validate_call` - unless arg0.is_a?(arg0_type) - CallValidation.report_error( - method_sig, - method_sig.arg_types[0][1].error_message_for_obj(arg0), - 'Parameter', - method_sig.arg_types[0][0], - arg0_type, - arg0, - caller_offset: -1 - ) - end - - # The following line breaks are intentional to show nice pry message - - - - - - - - - - - # PRY note: - # this code is sig validation code. - # Please issue `finish` to step out of it - - original_method.bind(self).call(arg0, &blk) - T::Private::Types::Void::VOID - end - end - - def self.create_validator_procedure_fast2(mod, original_method, method_sig, arg0_type, arg1_type) - mod.send(:define_method, method_sig.method_name) do |arg0, arg1, &blk| - # This method is a manually sped-up version of more general code in `validate_call` - unless arg0.is_a?(arg0_type) - CallValidation.report_error( - method_sig, - method_sig.arg_types[0][1].error_message_for_obj(arg0), - 'Parameter', - method_sig.arg_types[0][0], - arg0_type, - arg0, - caller_offset: -1 - ) - end - - unless arg1.is_a?(arg1_type) - CallValidation.report_error( - method_sig, - method_sig.arg_types[1][1].error_message_for_obj(arg1), - 'Parameter', - method_sig.arg_types[1][0], - arg1_type, - arg1, - caller_offset: -1 - ) - end - - # The following line breaks are intentional to show nice pry message - - - - - - - - - - - # PRY note: - # this code is sig validation code. - # Please issue `finish` to step out of it - - original_method.bind(self).call(arg0, arg1, &blk) - T::Private::Types::Void::VOID - end - end - - def self.create_validator_procedure_fast3(mod, original_method, method_sig, arg0_type, arg1_type, arg2_type) - mod.send(:define_method, method_sig.method_name) do |arg0, arg1, arg2, &blk| - # This method is a manually sped-up version of more general code in `validate_call` - unless arg0.is_a?(arg0_type) - CallValidation.report_error( - method_sig, - method_sig.arg_types[0][1].error_message_for_obj(arg0), - 'Parameter', - method_sig.arg_types[0][0], - arg0_type, - arg0, - caller_offset: -1 - ) - end - - unless arg1.is_a?(arg1_type) - CallValidation.report_error( - method_sig, - method_sig.arg_types[1][1].error_message_for_obj(arg1), - 'Parameter', - method_sig.arg_types[1][0], - arg1_type, - arg1, - caller_offset: -1 - ) - end - - unless arg2.is_a?(arg2_type) - CallValidation.report_error( - method_sig, - method_sig.arg_types[2][1].error_message_for_obj(arg2), - 'Parameter', - method_sig.arg_types[2][0], - arg2_type, - arg2, - caller_offset: -1 - ) - end - - # The following line breaks are intentional to show nice pry message - - - - - - - - - - - # PRY note: - # this code is sig validation code. - # Please issue `finish` to step out of it - - original_method.bind(self).call(arg0, arg1, arg2, &blk) - T::Private::Types::Void::VOID - end - end - - def self.create_validator_procedure_fast4(mod, original_method, method_sig, arg0_type, arg1_type, arg2_type, arg3_type) - mod.send(:define_method, method_sig.method_name) do |arg0, arg1, arg2, arg3, &blk| - # This method is a manually sped-up version of more general code in `validate_call` - unless arg0.is_a?(arg0_type) - CallValidation.report_error( - method_sig, - method_sig.arg_types[0][1].error_message_for_obj(arg0), - 'Parameter', - method_sig.arg_types[0][0], - arg0_type, - arg0, - caller_offset: -1 - ) - end - - unless arg1.is_a?(arg1_type) - CallValidation.report_error( - method_sig, - method_sig.arg_types[1][1].error_message_for_obj(arg1), - 'Parameter', - method_sig.arg_types[1][0], - arg1_type, - arg1, - caller_offset: -1 - ) - end - - unless arg2.is_a?(arg2_type) - CallValidation.report_error( - method_sig, - method_sig.arg_types[2][1].error_message_for_obj(arg2), - 'Parameter', - method_sig.arg_types[2][0], - arg2_type, - arg2, - caller_offset: -1 - ) - end - - unless arg3.is_a?(arg3_type) - CallValidation.report_error( - method_sig, - method_sig.arg_types[3][1].error_message_for_obj(arg3), - 'Parameter', - method_sig.arg_types[3][0], - arg3_type, - arg3, - caller_offset: -1 - ) - end - - # The following line breaks are intentional to show nice pry message - - - - - - - - - - - # PRY note: - # this code is sig validation code. - # Please issue `finish` to step out of it - - original_method.bind(self).call(arg0, arg1, arg2, arg3, &blk) - T::Private::Types::Void::VOID - end - end - - def self.create_validator_method_medium(mod, original_method, method_sig) - if method_sig.return_type.is_a?(T::Private::Types::Void) - raise 'Should have used create_validator_procedure_medium' - end - # trampoline to reduce stack frame size - if method_sig.arg_types.empty? - create_validator_method_medium0(mod, original_method, method_sig, method_sig.return_type) - elsif method_sig.arg_types.length == 1 - create_validator_method_medium1(mod, original_method, method_sig, method_sig.return_type, - method_sig.arg_types[0][1]) - elsif method_sig.arg_types.length == 2 - create_validator_method_medium2(mod, original_method, method_sig, method_sig.return_type, - method_sig.arg_types[0][1], - method_sig.arg_types[1][1]) - elsif method_sig.arg_types.length == 3 - create_validator_method_medium3(mod, original_method, method_sig, method_sig.return_type, - method_sig.arg_types[0][1], - method_sig.arg_types[1][1], - method_sig.arg_types[2][1]) - elsif method_sig.arg_types.length == 4 - create_validator_method_medium4(mod, original_method, method_sig, method_sig.return_type, - method_sig.arg_types[0][1], - method_sig.arg_types[1][1], - method_sig.arg_types[2][1], - method_sig.arg_types[3][1]) - else - raise 'should not happen' - end - end - - def self.create_validator_method_medium0(mod, original_method, method_sig, return_type) - mod.send(:define_method, method_sig.method_name) do |&blk| - # This method is a manually sped-up version of more general code in `validate_call` - # The following line breaks are intentional to show nice pry message - - - - - - - - - - - # PRY note: - # this code is sig validation code. - # Please issue `finish` to step out of it - - return_value = original_method.bind(self).call(&blk) - unless return_type.valid?(return_value) - message = method_sig.return_type.error_message_for_obj(return_value) - if message - CallValidation.report_error( - method_sig, - message, - 'Return value', - nil, - method_sig.return_type, - return_value, - caller_offset: -1 - ) - end - end - return_value - end - end - - def self.create_validator_method_medium1(mod, original_method, method_sig, return_type, arg0_type) - mod.send(:define_method, method_sig.method_name) do |arg0, &blk| - # This method is a manually sped-up version of more general code in `validate_call` - unless arg0_type.valid?(arg0) - CallValidation.report_error( - method_sig, - method_sig.arg_types[0][1].error_message_for_obj(arg0), - 'Parameter', - method_sig.arg_types[0][0], - arg0_type, - arg0, - caller_offset: -1 - ) - end - - # The following line breaks are intentional to show nice pry message - - - - - - - - - - - # PRY note: - # this code is sig validation code. - # Please issue `finish` to step out of it - - return_value = original_method.bind(self).call(arg0, &blk) - unless return_type.valid?(return_value) - message = method_sig.return_type.error_message_for_obj(return_value) - if message - CallValidation.report_error( - method_sig, - message, - 'Return value', - nil, - method_sig.return_type, - return_value, - caller_offset: -1 - ) - end - end - return_value - end - end - - def self.create_validator_method_medium2(mod, original_method, method_sig, return_type, arg0_type, arg1_type) - mod.send(:define_method, method_sig.method_name) do |arg0, arg1, &blk| - # This method is a manually sped-up version of more general code in `validate_call` - unless arg0_type.valid?(arg0) - CallValidation.report_error( - method_sig, - method_sig.arg_types[0][1].error_message_for_obj(arg0), - 'Parameter', - method_sig.arg_types[0][0], - arg0_type, - arg0, - caller_offset: -1 - ) - end - - unless arg1_type.valid?(arg1) - CallValidation.report_error( - method_sig, - method_sig.arg_types[1][1].error_message_for_obj(arg1), - 'Parameter', - method_sig.arg_types[1][0], - arg1_type, - arg1, - caller_offset: -1 - ) - end - - # The following line breaks are intentional to show nice pry message - - - - - - - - - - - # PRY note: - # this code is sig validation code. - # Please issue `finish` to step out of it - - return_value = original_method.bind(self).call(arg0, arg1, &blk) - unless return_type.valid?(return_value) - message = method_sig.return_type.error_message_for_obj(return_value) - if message - CallValidation.report_error( - method_sig, - message, - 'Return value', - nil, - method_sig.return_type, - return_value, - caller_offset: -1 - ) - end - end - return_value - end - end - - def self.create_validator_method_medium3(mod, original_method, method_sig, return_type, arg0_type, arg1_type, arg2_type) - mod.send(:define_method, method_sig.method_name) do |arg0, arg1, arg2, &blk| - # This method is a manually sped-up version of more general code in `validate_call` - unless arg0_type.valid?(arg0) - CallValidation.report_error( - method_sig, - method_sig.arg_types[0][1].error_message_for_obj(arg0), - 'Parameter', - method_sig.arg_types[0][0], - arg0_type, - arg0, - caller_offset: -1 - ) - end - - unless arg1_type.valid?(arg1) - CallValidation.report_error( - method_sig, - method_sig.arg_types[1][1].error_message_for_obj(arg1), - 'Parameter', - method_sig.arg_types[1][0], - arg1_type, - arg1, - caller_offset: -1 - ) - end - - unless arg2_type.valid?(arg2) - CallValidation.report_error( - method_sig, - method_sig.arg_types[2][1].error_message_for_obj(arg2), - 'Parameter', - method_sig.arg_types[2][0], - arg2_type, - arg2, - caller_offset: -1 - ) - end - - # The following line breaks are intentional to show nice pry message - - - - - - - - - - - # PRY note: - # this code is sig validation code. - # Please issue `finish` to step out of it - - return_value = original_method.bind(self).call(arg0, arg1, arg2, &blk) - unless return_type.valid?(return_value) - message = method_sig.return_type.error_message_for_obj(return_value) - if message - CallValidation.report_error( - method_sig, - message, - 'Return value', - nil, - method_sig.return_type, - return_value, - caller_offset: -1 - ) - end - end - return_value - end - end - - def self.create_validator_method_medium4(mod, original_method, method_sig, return_type, arg0_type, arg1_type, arg2_type, arg3_type) - mod.send(:define_method, method_sig.method_name) do |arg0, arg1, arg2, arg3, &blk| - # This method is a manually sped-up version of more general code in `validate_call` - unless arg0_type.valid?(arg0) - CallValidation.report_error( - method_sig, - method_sig.arg_types[0][1].error_message_for_obj(arg0), - 'Parameter', - method_sig.arg_types[0][0], - arg0_type, - arg0, - caller_offset: -1 - ) - end - - unless arg1_type.valid?(arg1) - CallValidation.report_error( - method_sig, - method_sig.arg_types[1][1].error_message_for_obj(arg1), - 'Parameter', - method_sig.arg_types[1][0], - arg1_type, - arg1, - caller_offset: -1 - ) - end - - unless arg2_type.valid?(arg2) - CallValidation.report_error( - method_sig, - method_sig.arg_types[2][1].error_message_for_obj(arg2), - 'Parameter', - method_sig.arg_types[2][0], - arg2_type, - arg2, - caller_offset: -1 - ) - end - - unless arg3_type.valid?(arg3) - CallValidation.report_error( - method_sig, - method_sig.arg_types[3][1].error_message_for_obj(arg3), - 'Parameter', - method_sig.arg_types[3][0], - arg3_type, - arg3, - caller_offset: -1 - ) - end - - # The following line breaks are intentional to show nice pry message - - - - - - - - - - - # PRY note: - # this code is sig validation code. - # Please issue `finish` to step out of it - - return_value = original_method.bind(self).call(arg0, arg1, arg2, arg3, &blk) - unless return_type.valid?(return_value) - message = method_sig.return_type.error_message_for_obj(return_value) - if message - CallValidation.report_error( - method_sig, - message, - 'Return value', - nil, - method_sig.return_type, - return_value, - caller_offset: -1 - ) - end - end - return_value - end - end - - def self.create_validator_procedure_medium(mod, original_method, method_sig) - # trampoline to reduce stack frame size - if method_sig.arg_types.empty? - create_validator_procedure_medium0(mod, original_method, method_sig) - elsif method_sig.arg_types.length == 1 - create_validator_procedure_medium1(mod, original_method, method_sig, - method_sig.arg_types[0][1]) - elsif method_sig.arg_types.length == 2 - create_validator_procedure_medium2(mod, original_method, method_sig, - method_sig.arg_types[0][1], - method_sig.arg_types[1][1]) - elsif method_sig.arg_types.length == 3 - create_validator_procedure_medium3(mod, original_method, method_sig, - method_sig.arg_types[0][1], - method_sig.arg_types[1][1], - method_sig.arg_types[2][1]) - elsif method_sig.arg_types.length == 4 - create_validator_procedure_medium4(mod, original_method, method_sig, - method_sig.arg_types[0][1], - method_sig.arg_types[1][1], - method_sig.arg_types[2][1], - method_sig.arg_types[3][1]) - else - raise 'should not happen' - end - end - - def self.create_validator_procedure_medium0(mod, original_method, method_sig) - mod.send(:define_method, method_sig.method_name) do |&blk| - # This method is a manually sped-up version of more general code in `validate_call` - # The following line breaks are intentional to show nice pry message - - - - - - - - - - - # PRY note: - # this code is sig validation code. - # Please issue `finish` to step out of it - - original_method.bind(self).call(&blk) - T::Private::Types::Void::VOID - end - end - - def self.create_validator_procedure_medium1(mod, original_method, method_sig, arg0_type) - mod.send(:define_method, method_sig.method_name) do |arg0, &blk| - # This method is a manually sped-up version of more general code in `validate_call` - unless arg0_type.valid?(arg0) - CallValidation.report_error( - method_sig, - method_sig.arg_types[0][1].error_message_for_obj(arg0), - 'Parameter', - method_sig.arg_types[0][0], - arg0_type, - arg0, - caller_offset: -1 - ) - end - - # The following line breaks are intentional to show nice pry message - - - - - - - - - - - # PRY note: - # this code is sig validation code. - # Please issue `finish` to step out of it - - original_method.bind(self).call(arg0, &blk) - T::Private::Types::Void::VOID - end - end - - def self.create_validator_procedure_medium2(mod, original_method, method_sig, arg0_type, arg1_type) - mod.send(:define_method, method_sig.method_name) do |arg0, arg1, &blk| - # This method is a manually sped-up version of more general code in `validate_call` - unless arg0_type.valid?(arg0) - CallValidation.report_error( - method_sig, - method_sig.arg_types[0][1].error_message_for_obj(arg0), - 'Parameter', - method_sig.arg_types[0][0], - arg0_type, - arg0, - caller_offset: -1 - ) - end - - unless arg1_type.valid?(arg1) - CallValidation.report_error( - method_sig, - method_sig.arg_types[1][1].error_message_for_obj(arg1), - 'Parameter', - method_sig.arg_types[1][0], - arg1_type, - arg1, - caller_offset: -1 - ) - end - - # The following line breaks are intentional to show nice pry message - - - - - - - - - - - # PRY note: - # this code is sig validation code. - # Please issue `finish` to step out of it - - original_method.bind(self).call(arg0, arg1, &blk) - T::Private::Types::Void::VOID - end - end - - def self.create_validator_procedure_medium3(mod, original_method, method_sig, arg0_type, arg1_type, arg2_type) - mod.send(:define_method, method_sig.method_name) do |arg0, arg1, arg2, &blk| - # This method is a manually sped-up version of more general code in `validate_call` - unless arg0_type.valid?(arg0) - CallValidation.report_error( - method_sig, - method_sig.arg_types[0][1].error_message_for_obj(arg0), - 'Parameter', - method_sig.arg_types[0][0], - arg0_type, - arg0, - caller_offset: -1 - ) - end - - unless arg1_type.valid?(arg1) - CallValidation.report_error( - method_sig, - method_sig.arg_types[1][1].error_message_for_obj(arg1), - 'Parameter', - method_sig.arg_types[1][0], - arg1_type, - arg1, - caller_offset: -1 - ) - end - - unless arg2_type.valid?(arg2) - CallValidation.report_error( - method_sig, - method_sig.arg_types[2][1].error_message_for_obj(arg2), - 'Parameter', - method_sig.arg_types[2][0], - arg2_type, - arg2, - caller_offset: -1 - ) - end - - # The following line breaks are intentional to show nice pry message - - - - - - - - - - - # PRY note: - # this code is sig validation code. - # Please issue `finish` to step out of it - - original_method.bind(self).call(arg0, arg1, arg2, &blk) - T::Private::Types::Void::VOID - end - end - - def self.create_validator_procedure_medium4(mod, original_method, method_sig, arg0_type, arg1_type, arg2_type, arg3_type) - mod.send(:define_method, method_sig.method_name) do |arg0, arg1, arg2, arg3, &blk| - # This method is a manually sped-up version of more general code in `validate_call` - unless arg0_type.valid?(arg0) - CallValidation.report_error( - method_sig, - method_sig.arg_types[0][1].error_message_for_obj(arg0), - 'Parameter', - method_sig.arg_types[0][0], - arg0_type, - arg0, - caller_offset: -1 - ) - end - - unless arg1_type.valid?(arg1) - CallValidation.report_error( - method_sig, - method_sig.arg_types[1][1].error_message_for_obj(arg1), - 'Parameter', - method_sig.arg_types[1][0], - arg1_type, - arg1, - caller_offset: -1 - ) - end - - unless arg2_type.valid?(arg2) - CallValidation.report_error( - method_sig, - method_sig.arg_types[2][1].error_message_for_obj(arg2), - 'Parameter', - method_sig.arg_types[2][0], - arg2_type, - arg2, - caller_offset: -1 - ) - end - - unless arg3_type.valid?(arg3) - CallValidation.report_error( - method_sig, - method_sig.arg_types[3][1].error_message_for_obj(arg3), - 'Parameter', - method_sig.arg_types[3][0], - arg3_type, - arg3, - caller_offset: -1 - ) - end - - # The following line breaks are intentional to show nice pry message - - - - - - - - - - - # PRY note: - # this code is sig validation code. - # Please issue `finish` to step out of it - - original_method.bind(self).call(arg0, arg1, arg2, arg3, &blk) - T::Private::Types::Void::VOID - end - end - -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/call_validation_2_7.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/call_validation_2_7.rb deleted file mode 100644 index 1686db8977..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/call_validation_2_7.rb +++ /dev/null @@ -1,1203 +0,0 @@ -# frozen_string_literal: true -# typed: false - -# DO NOT EDIT. This file is autogenerated. To regenerate, run: -# -# bazel test //gems/sorbet-runtime:update_call_validation - -module T::Private::Methods::CallValidation - def self.create_validator_method_fast(mod, original_method, method_sig) - if method_sig.return_type.is_a?(T::Private::Types::Void) - raise 'Should have used create_validator_procedure_fast' - end - # trampoline to reduce stack frame size - if method_sig.arg_types.empty? - create_validator_method_fast0(mod, original_method, method_sig, method_sig.return_type.raw_type) - elsif method_sig.arg_types.length == 1 - create_validator_method_fast1(mod, original_method, method_sig, method_sig.return_type.raw_type, - method_sig.arg_types[0][1].raw_type) - elsif method_sig.arg_types.length == 2 - create_validator_method_fast2(mod, original_method, method_sig, method_sig.return_type.raw_type, - method_sig.arg_types[0][1].raw_type, - method_sig.arg_types[1][1].raw_type) - elsif method_sig.arg_types.length == 3 - create_validator_method_fast3(mod, original_method, method_sig, method_sig.return_type.raw_type, - method_sig.arg_types[0][1].raw_type, - method_sig.arg_types[1][1].raw_type, - method_sig.arg_types[2][1].raw_type) - elsif method_sig.arg_types.length == 4 - create_validator_method_fast4(mod, original_method, method_sig, method_sig.return_type.raw_type, - method_sig.arg_types[0][1].raw_type, - method_sig.arg_types[1][1].raw_type, - method_sig.arg_types[2][1].raw_type, - method_sig.arg_types[3][1].raw_type) - else - raise 'should not happen' - end - end - - def self.create_validator_method_fast0(mod, original_method, method_sig, return_type) - mod.send(:define_method, method_sig.method_name) do |&blk| - # This method is a manually sped-up version of more general code in `validate_call` - # The following line breaks are intentional to show nice pry message - - - - - - - - - - - # PRY note: - # this code is sig validation code. - # Please issue `finish` to step out of it - - return_value = original_method.bind_call(self, &blk) - unless return_value.is_a?(return_type) - message = method_sig.return_type.error_message_for_obj(return_value) - if message - CallValidation.report_error( - method_sig, - message, - 'Return value', - nil, - method_sig.return_type, - return_value, - caller_offset: -1 - ) - end - end - return_value - end - end - - def self.create_validator_method_fast1(mod, original_method, method_sig, return_type, arg0_type) - mod.send(:define_method, method_sig.method_name) do |arg0, &blk| - # This method is a manually sped-up version of more general code in `validate_call` - unless arg0.is_a?(arg0_type) - CallValidation.report_error( - method_sig, - method_sig.arg_types[0][1].error_message_for_obj(arg0), - 'Parameter', - method_sig.arg_types[0][0], - arg0_type, - arg0, - caller_offset: -1 - ) - end - - # The following line breaks are intentional to show nice pry message - - - - - - - - - - - # PRY note: - # this code is sig validation code. - # Please issue `finish` to step out of it - - return_value = original_method.bind_call(self, arg0, &blk) - unless return_value.is_a?(return_type) - message = method_sig.return_type.error_message_for_obj(return_value) - if message - CallValidation.report_error( - method_sig, - message, - 'Return value', - nil, - method_sig.return_type, - return_value, - caller_offset: -1 - ) - end - end - return_value - end - end - - def self.create_validator_method_fast2(mod, original_method, method_sig, return_type, arg0_type, arg1_type) - mod.send(:define_method, method_sig.method_name) do |arg0, arg1, &blk| - # This method is a manually sped-up version of more general code in `validate_call` - unless arg0.is_a?(arg0_type) - CallValidation.report_error( - method_sig, - method_sig.arg_types[0][1].error_message_for_obj(arg0), - 'Parameter', - method_sig.arg_types[0][0], - arg0_type, - arg0, - caller_offset: -1 - ) - end - - unless arg1.is_a?(arg1_type) - CallValidation.report_error( - method_sig, - method_sig.arg_types[1][1].error_message_for_obj(arg1), - 'Parameter', - method_sig.arg_types[1][0], - arg1_type, - arg1, - caller_offset: -1 - ) - end - - # The following line breaks are intentional to show nice pry message - - - - - - - - - - - # PRY note: - # this code is sig validation code. - # Please issue `finish` to step out of it - - return_value = original_method.bind_call(self, arg0, arg1, &blk) - unless return_value.is_a?(return_type) - message = method_sig.return_type.error_message_for_obj(return_value) - if message - CallValidation.report_error( - method_sig, - message, - 'Return value', - nil, - method_sig.return_type, - return_value, - caller_offset: -1 - ) - end - end - return_value - end - end - - def self.create_validator_method_fast3(mod, original_method, method_sig, return_type, arg0_type, arg1_type, arg2_type) - mod.send(:define_method, method_sig.method_name) do |arg0, arg1, arg2, &blk| - # This method is a manually sped-up version of more general code in `validate_call` - unless arg0.is_a?(arg0_type) - CallValidation.report_error( - method_sig, - method_sig.arg_types[0][1].error_message_for_obj(arg0), - 'Parameter', - method_sig.arg_types[0][0], - arg0_type, - arg0, - caller_offset: -1 - ) - end - - unless arg1.is_a?(arg1_type) - CallValidation.report_error( - method_sig, - method_sig.arg_types[1][1].error_message_for_obj(arg1), - 'Parameter', - method_sig.arg_types[1][0], - arg1_type, - arg1, - caller_offset: -1 - ) - end - - unless arg2.is_a?(arg2_type) - CallValidation.report_error( - method_sig, - method_sig.arg_types[2][1].error_message_for_obj(arg2), - 'Parameter', - method_sig.arg_types[2][0], - arg2_type, - arg2, - caller_offset: -1 - ) - end - - # The following line breaks are intentional to show nice pry message - - - - - - - - - - - # PRY note: - # this code is sig validation code. - # Please issue `finish` to step out of it - - return_value = original_method.bind_call(self, arg0, arg1, arg2, &blk) - unless return_value.is_a?(return_type) - message = method_sig.return_type.error_message_for_obj(return_value) - if message - CallValidation.report_error( - method_sig, - message, - 'Return value', - nil, - method_sig.return_type, - return_value, - caller_offset: -1 - ) - end - end - return_value - end - end - - def self.create_validator_method_fast4(mod, original_method, method_sig, return_type, arg0_type, arg1_type, arg2_type, arg3_type) - mod.send(:define_method, method_sig.method_name) do |arg0, arg1, arg2, arg3, &blk| - # This method is a manually sped-up version of more general code in `validate_call` - unless arg0.is_a?(arg0_type) - CallValidation.report_error( - method_sig, - method_sig.arg_types[0][1].error_message_for_obj(arg0), - 'Parameter', - method_sig.arg_types[0][0], - arg0_type, - arg0, - caller_offset: -1 - ) - end - - unless arg1.is_a?(arg1_type) - CallValidation.report_error( - method_sig, - method_sig.arg_types[1][1].error_message_for_obj(arg1), - 'Parameter', - method_sig.arg_types[1][0], - arg1_type, - arg1, - caller_offset: -1 - ) - end - - unless arg2.is_a?(arg2_type) - CallValidation.report_error( - method_sig, - method_sig.arg_types[2][1].error_message_for_obj(arg2), - 'Parameter', - method_sig.arg_types[2][0], - arg2_type, - arg2, - caller_offset: -1 - ) - end - - unless arg3.is_a?(arg3_type) - CallValidation.report_error( - method_sig, - method_sig.arg_types[3][1].error_message_for_obj(arg3), - 'Parameter', - method_sig.arg_types[3][0], - arg3_type, - arg3, - caller_offset: -1 - ) - end - - # The following line breaks are intentional to show nice pry message - - - - - - - - - - - # PRY note: - # this code is sig validation code. - # Please issue `finish` to step out of it - - return_value = original_method.bind_call(self, arg0, arg1, arg2, arg3, &blk) - unless return_value.is_a?(return_type) - message = method_sig.return_type.error_message_for_obj(return_value) - if message - CallValidation.report_error( - method_sig, - message, - 'Return value', - nil, - method_sig.return_type, - return_value, - caller_offset: -1 - ) - end - end - return_value - end - end - - def self.create_validator_procedure_fast(mod, original_method, method_sig) - # trampoline to reduce stack frame size - if method_sig.arg_types.empty? - create_validator_procedure_fast0(mod, original_method, method_sig) - elsif method_sig.arg_types.length == 1 - create_validator_procedure_fast1(mod, original_method, method_sig, - method_sig.arg_types[0][1].raw_type) - elsif method_sig.arg_types.length == 2 - create_validator_procedure_fast2(mod, original_method, method_sig, - method_sig.arg_types[0][1].raw_type, - method_sig.arg_types[1][1].raw_type) - elsif method_sig.arg_types.length == 3 - create_validator_procedure_fast3(mod, original_method, method_sig, - method_sig.arg_types[0][1].raw_type, - method_sig.arg_types[1][1].raw_type, - method_sig.arg_types[2][1].raw_type) - elsif method_sig.arg_types.length == 4 - create_validator_procedure_fast4(mod, original_method, method_sig, - method_sig.arg_types[0][1].raw_type, - method_sig.arg_types[1][1].raw_type, - method_sig.arg_types[2][1].raw_type, - method_sig.arg_types[3][1].raw_type) - else - raise 'should not happen' - end - end - - def self.create_validator_procedure_fast0(mod, original_method, method_sig) - mod.send(:define_method, method_sig.method_name) do |&blk| - # This method is a manually sped-up version of more general code in `validate_call` - # The following line breaks are intentional to show nice pry message - - - - - - - - - - - # PRY note: - # this code is sig validation code. - # Please issue `finish` to step out of it - - original_method.bind_call(self, &blk) - T::Private::Types::Void::VOID - end - end - - def self.create_validator_procedure_fast1(mod, original_method, method_sig, arg0_type) - mod.send(:define_method, method_sig.method_name) do |arg0, &blk| - # This method is a manually sped-up version of more general code in `validate_call` - unless arg0.is_a?(arg0_type) - CallValidation.report_error( - method_sig, - method_sig.arg_types[0][1].error_message_for_obj(arg0), - 'Parameter', - method_sig.arg_types[0][0], - arg0_type, - arg0, - caller_offset: -1 - ) - end - - # The following line breaks are intentional to show nice pry message - - - - - - - - - - - # PRY note: - # this code is sig validation code. - # Please issue `finish` to step out of it - - original_method.bind_call(self, arg0, &blk) - T::Private::Types::Void::VOID - end - end - - def self.create_validator_procedure_fast2(mod, original_method, method_sig, arg0_type, arg1_type) - mod.send(:define_method, method_sig.method_name) do |arg0, arg1, &blk| - # This method is a manually sped-up version of more general code in `validate_call` - unless arg0.is_a?(arg0_type) - CallValidation.report_error( - method_sig, - method_sig.arg_types[0][1].error_message_for_obj(arg0), - 'Parameter', - method_sig.arg_types[0][0], - arg0_type, - arg0, - caller_offset: -1 - ) - end - - unless arg1.is_a?(arg1_type) - CallValidation.report_error( - method_sig, - method_sig.arg_types[1][1].error_message_for_obj(arg1), - 'Parameter', - method_sig.arg_types[1][0], - arg1_type, - arg1, - caller_offset: -1 - ) - end - - # The following line breaks are intentional to show nice pry message - - - - - - - - - - - # PRY note: - # this code is sig validation code. - # Please issue `finish` to step out of it - - original_method.bind_call(self, arg0, arg1, &blk) - T::Private::Types::Void::VOID - end - end - - def self.create_validator_procedure_fast3(mod, original_method, method_sig, arg0_type, arg1_type, arg2_type) - mod.send(:define_method, method_sig.method_name) do |arg0, arg1, arg2, &blk| - # This method is a manually sped-up version of more general code in `validate_call` - unless arg0.is_a?(arg0_type) - CallValidation.report_error( - method_sig, - method_sig.arg_types[0][1].error_message_for_obj(arg0), - 'Parameter', - method_sig.arg_types[0][0], - arg0_type, - arg0, - caller_offset: -1 - ) - end - - unless arg1.is_a?(arg1_type) - CallValidation.report_error( - method_sig, - method_sig.arg_types[1][1].error_message_for_obj(arg1), - 'Parameter', - method_sig.arg_types[1][0], - arg1_type, - arg1, - caller_offset: -1 - ) - end - - unless arg2.is_a?(arg2_type) - CallValidation.report_error( - method_sig, - method_sig.arg_types[2][1].error_message_for_obj(arg2), - 'Parameter', - method_sig.arg_types[2][0], - arg2_type, - arg2, - caller_offset: -1 - ) - end - - # The following line breaks are intentional to show nice pry message - - - - - - - - - - - # PRY note: - # this code is sig validation code. - # Please issue `finish` to step out of it - - original_method.bind_call(self, arg0, arg1, arg2, &blk) - T::Private::Types::Void::VOID - end - end - - def self.create_validator_procedure_fast4(mod, original_method, method_sig, arg0_type, arg1_type, arg2_type, arg3_type) - mod.send(:define_method, method_sig.method_name) do |arg0, arg1, arg2, arg3, &blk| - # This method is a manually sped-up version of more general code in `validate_call` - unless arg0.is_a?(arg0_type) - CallValidation.report_error( - method_sig, - method_sig.arg_types[0][1].error_message_for_obj(arg0), - 'Parameter', - method_sig.arg_types[0][0], - arg0_type, - arg0, - caller_offset: -1 - ) - end - - unless arg1.is_a?(arg1_type) - CallValidation.report_error( - method_sig, - method_sig.arg_types[1][1].error_message_for_obj(arg1), - 'Parameter', - method_sig.arg_types[1][0], - arg1_type, - arg1, - caller_offset: -1 - ) - end - - unless arg2.is_a?(arg2_type) - CallValidation.report_error( - method_sig, - method_sig.arg_types[2][1].error_message_for_obj(arg2), - 'Parameter', - method_sig.arg_types[2][0], - arg2_type, - arg2, - caller_offset: -1 - ) - end - - unless arg3.is_a?(arg3_type) - CallValidation.report_error( - method_sig, - method_sig.arg_types[3][1].error_message_for_obj(arg3), - 'Parameter', - method_sig.arg_types[3][0], - arg3_type, - arg3, - caller_offset: -1 - ) - end - - # The following line breaks are intentional to show nice pry message - - - - - - - - - - - # PRY note: - # this code is sig validation code. - # Please issue `finish` to step out of it - - original_method.bind_call(self, arg0, arg1, arg2, arg3, &blk) - T::Private::Types::Void::VOID - end - end - - def self.create_validator_method_medium(mod, original_method, method_sig) - if method_sig.return_type.is_a?(T::Private::Types::Void) - raise 'Should have used create_validator_procedure_medium' - end - # trampoline to reduce stack frame size - if method_sig.arg_types.empty? - create_validator_method_medium0(mod, original_method, method_sig, method_sig.return_type) - elsif method_sig.arg_types.length == 1 - create_validator_method_medium1(mod, original_method, method_sig, method_sig.return_type, - method_sig.arg_types[0][1]) - elsif method_sig.arg_types.length == 2 - create_validator_method_medium2(mod, original_method, method_sig, method_sig.return_type, - method_sig.arg_types[0][1], - method_sig.arg_types[1][1]) - elsif method_sig.arg_types.length == 3 - create_validator_method_medium3(mod, original_method, method_sig, method_sig.return_type, - method_sig.arg_types[0][1], - method_sig.arg_types[1][1], - method_sig.arg_types[2][1]) - elsif method_sig.arg_types.length == 4 - create_validator_method_medium4(mod, original_method, method_sig, method_sig.return_type, - method_sig.arg_types[0][1], - method_sig.arg_types[1][1], - method_sig.arg_types[2][1], - method_sig.arg_types[3][1]) - else - raise 'should not happen' - end - end - - def self.create_validator_method_medium0(mod, original_method, method_sig, return_type) - mod.send(:define_method, method_sig.method_name) do |&blk| - # This method is a manually sped-up version of more general code in `validate_call` - # The following line breaks are intentional to show nice pry message - - - - - - - - - - - # PRY note: - # this code is sig validation code. - # Please issue `finish` to step out of it - - return_value = original_method.bind_call(self, &blk) - unless return_type.valid?(return_value) - message = method_sig.return_type.error_message_for_obj(return_value) - if message - CallValidation.report_error( - method_sig, - message, - 'Return value', - nil, - method_sig.return_type, - return_value, - caller_offset: -1 - ) - end - end - return_value - end - end - - def self.create_validator_method_medium1(mod, original_method, method_sig, return_type, arg0_type) - mod.send(:define_method, method_sig.method_name) do |arg0, &blk| - # This method is a manually sped-up version of more general code in `validate_call` - unless arg0_type.valid?(arg0) - CallValidation.report_error( - method_sig, - method_sig.arg_types[0][1].error_message_for_obj(arg0), - 'Parameter', - method_sig.arg_types[0][0], - arg0_type, - arg0, - caller_offset: -1 - ) - end - - # The following line breaks are intentional to show nice pry message - - - - - - - - - - - # PRY note: - # this code is sig validation code. - # Please issue `finish` to step out of it - - return_value = original_method.bind_call(self, arg0, &blk) - unless return_type.valid?(return_value) - message = method_sig.return_type.error_message_for_obj(return_value) - if message - CallValidation.report_error( - method_sig, - message, - 'Return value', - nil, - method_sig.return_type, - return_value, - caller_offset: -1 - ) - end - end - return_value - end - end - - def self.create_validator_method_medium2(mod, original_method, method_sig, return_type, arg0_type, arg1_type) - mod.send(:define_method, method_sig.method_name) do |arg0, arg1, &blk| - # This method is a manually sped-up version of more general code in `validate_call` - unless arg0_type.valid?(arg0) - CallValidation.report_error( - method_sig, - method_sig.arg_types[0][1].error_message_for_obj(arg0), - 'Parameter', - method_sig.arg_types[0][0], - arg0_type, - arg0, - caller_offset: -1 - ) - end - - unless arg1_type.valid?(arg1) - CallValidation.report_error( - method_sig, - method_sig.arg_types[1][1].error_message_for_obj(arg1), - 'Parameter', - method_sig.arg_types[1][0], - arg1_type, - arg1, - caller_offset: -1 - ) - end - - # The following line breaks are intentional to show nice pry message - - - - - - - - - - - # PRY note: - # this code is sig validation code. - # Please issue `finish` to step out of it - - return_value = original_method.bind_call(self, arg0, arg1, &blk) - unless return_type.valid?(return_value) - message = method_sig.return_type.error_message_for_obj(return_value) - if message - CallValidation.report_error( - method_sig, - message, - 'Return value', - nil, - method_sig.return_type, - return_value, - caller_offset: -1 - ) - end - end - return_value - end - end - - def self.create_validator_method_medium3(mod, original_method, method_sig, return_type, arg0_type, arg1_type, arg2_type) - mod.send(:define_method, method_sig.method_name) do |arg0, arg1, arg2, &blk| - # This method is a manually sped-up version of more general code in `validate_call` - unless arg0_type.valid?(arg0) - CallValidation.report_error( - method_sig, - method_sig.arg_types[0][1].error_message_for_obj(arg0), - 'Parameter', - method_sig.arg_types[0][0], - arg0_type, - arg0, - caller_offset: -1 - ) - end - - unless arg1_type.valid?(arg1) - CallValidation.report_error( - method_sig, - method_sig.arg_types[1][1].error_message_for_obj(arg1), - 'Parameter', - method_sig.arg_types[1][0], - arg1_type, - arg1, - caller_offset: -1 - ) - end - - unless arg2_type.valid?(arg2) - CallValidation.report_error( - method_sig, - method_sig.arg_types[2][1].error_message_for_obj(arg2), - 'Parameter', - method_sig.arg_types[2][0], - arg2_type, - arg2, - caller_offset: -1 - ) - end - - # The following line breaks are intentional to show nice pry message - - - - - - - - - - - # PRY note: - # this code is sig validation code. - # Please issue `finish` to step out of it - - return_value = original_method.bind_call(self, arg0, arg1, arg2, &blk) - unless return_type.valid?(return_value) - message = method_sig.return_type.error_message_for_obj(return_value) - if message - CallValidation.report_error( - method_sig, - message, - 'Return value', - nil, - method_sig.return_type, - return_value, - caller_offset: -1 - ) - end - end - return_value - end - end - - def self.create_validator_method_medium4(mod, original_method, method_sig, return_type, arg0_type, arg1_type, arg2_type, arg3_type) - mod.send(:define_method, method_sig.method_name) do |arg0, arg1, arg2, arg3, &blk| - # This method is a manually sped-up version of more general code in `validate_call` - unless arg0_type.valid?(arg0) - CallValidation.report_error( - method_sig, - method_sig.arg_types[0][1].error_message_for_obj(arg0), - 'Parameter', - method_sig.arg_types[0][0], - arg0_type, - arg0, - caller_offset: -1 - ) - end - - unless arg1_type.valid?(arg1) - CallValidation.report_error( - method_sig, - method_sig.arg_types[1][1].error_message_for_obj(arg1), - 'Parameter', - method_sig.arg_types[1][0], - arg1_type, - arg1, - caller_offset: -1 - ) - end - - unless arg2_type.valid?(arg2) - CallValidation.report_error( - method_sig, - method_sig.arg_types[2][1].error_message_for_obj(arg2), - 'Parameter', - method_sig.arg_types[2][0], - arg2_type, - arg2, - caller_offset: -1 - ) - end - - unless arg3_type.valid?(arg3) - CallValidation.report_error( - method_sig, - method_sig.arg_types[3][1].error_message_for_obj(arg3), - 'Parameter', - method_sig.arg_types[3][0], - arg3_type, - arg3, - caller_offset: -1 - ) - end - - # The following line breaks are intentional to show nice pry message - - - - - - - - - - - # PRY note: - # this code is sig validation code. - # Please issue `finish` to step out of it - - return_value = original_method.bind_call(self, arg0, arg1, arg2, arg3, &blk) - unless return_type.valid?(return_value) - message = method_sig.return_type.error_message_for_obj(return_value) - if message - CallValidation.report_error( - method_sig, - message, - 'Return value', - nil, - method_sig.return_type, - return_value, - caller_offset: -1 - ) - end - end - return_value - end - end - - def self.create_validator_procedure_medium(mod, original_method, method_sig) - # trampoline to reduce stack frame size - if method_sig.arg_types.empty? - create_validator_procedure_medium0(mod, original_method, method_sig) - elsif method_sig.arg_types.length == 1 - create_validator_procedure_medium1(mod, original_method, method_sig, - method_sig.arg_types[0][1]) - elsif method_sig.arg_types.length == 2 - create_validator_procedure_medium2(mod, original_method, method_sig, - method_sig.arg_types[0][1], - method_sig.arg_types[1][1]) - elsif method_sig.arg_types.length == 3 - create_validator_procedure_medium3(mod, original_method, method_sig, - method_sig.arg_types[0][1], - method_sig.arg_types[1][1], - method_sig.arg_types[2][1]) - elsif method_sig.arg_types.length == 4 - create_validator_procedure_medium4(mod, original_method, method_sig, - method_sig.arg_types[0][1], - method_sig.arg_types[1][1], - method_sig.arg_types[2][1], - method_sig.arg_types[3][1]) - else - raise 'should not happen' - end - end - - def self.create_validator_procedure_medium0(mod, original_method, method_sig) - mod.send(:define_method, method_sig.method_name) do |&blk| - # This method is a manually sped-up version of more general code in `validate_call` - # The following line breaks are intentional to show nice pry message - - - - - - - - - - - # PRY note: - # this code is sig validation code. - # Please issue `finish` to step out of it - - original_method.bind_call(self, &blk) - T::Private::Types::Void::VOID - end - end - - def self.create_validator_procedure_medium1(mod, original_method, method_sig, arg0_type) - mod.send(:define_method, method_sig.method_name) do |arg0, &blk| - # This method is a manually sped-up version of more general code in `validate_call` - unless arg0_type.valid?(arg0) - CallValidation.report_error( - method_sig, - method_sig.arg_types[0][1].error_message_for_obj(arg0), - 'Parameter', - method_sig.arg_types[0][0], - arg0_type, - arg0, - caller_offset: -1 - ) - end - - # The following line breaks are intentional to show nice pry message - - - - - - - - - - - # PRY note: - # this code is sig validation code. - # Please issue `finish` to step out of it - - original_method.bind_call(self, arg0, &blk) - T::Private::Types::Void::VOID - end - end - - def self.create_validator_procedure_medium2(mod, original_method, method_sig, arg0_type, arg1_type) - mod.send(:define_method, method_sig.method_name) do |arg0, arg1, &blk| - # This method is a manually sped-up version of more general code in `validate_call` - unless arg0_type.valid?(arg0) - CallValidation.report_error( - method_sig, - method_sig.arg_types[0][1].error_message_for_obj(arg0), - 'Parameter', - method_sig.arg_types[0][0], - arg0_type, - arg0, - caller_offset: -1 - ) - end - - unless arg1_type.valid?(arg1) - CallValidation.report_error( - method_sig, - method_sig.arg_types[1][1].error_message_for_obj(arg1), - 'Parameter', - method_sig.arg_types[1][0], - arg1_type, - arg1, - caller_offset: -1 - ) - end - - # The following line breaks are intentional to show nice pry message - - - - - - - - - - - # PRY note: - # this code is sig validation code. - # Please issue `finish` to step out of it - - original_method.bind_call(self, arg0, arg1, &blk) - T::Private::Types::Void::VOID - end - end - - def self.create_validator_procedure_medium3(mod, original_method, method_sig, arg0_type, arg1_type, arg2_type) - mod.send(:define_method, method_sig.method_name) do |arg0, arg1, arg2, &blk| - # This method is a manually sped-up version of more general code in `validate_call` - unless arg0_type.valid?(arg0) - CallValidation.report_error( - method_sig, - method_sig.arg_types[0][1].error_message_for_obj(arg0), - 'Parameter', - method_sig.arg_types[0][0], - arg0_type, - arg0, - caller_offset: -1 - ) - end - - unless arg1_type.valid?(arg1) - CallValidation.report_error( - method_sig, - method_sig.arg_types[1][1].error_message_for_obj(arg1), - 'Parameter', - method_sig.arg_types[1][0], - arg1_type, - arg1, - caller_offset: -1 - ) - end - - unless arg2_type.valid?(arg2) - CallValidation.report_error( - method_sig, - method_sig.arg_types[2][1].error_message_for_obj(arg2), - 'Parameter', - method_sig.arg_types[2][0], - arg2_type, - arg2, - caller_offset: -1 - ) - end - - # The following line breaks are intentional to show nice pry message - - - - - - - - - - - # PRY note: - # this code is sig validation code. - # Please issue `finish` to step out of it - - original_method.bind_call(self, arg0, arg1, arg2, &blk) - T::Private::Types::Void::VOID - end - end - - def self.create_validator_procedure_medium4(mod, original_method, method_sig, arg0_type, arg1_type, arg2_type, arg3_type) - mod.send(:define_method, method_sig.method_name) do |arg0, arg1, arg2, arg3, &blk| - # This method is a manually sped-up version of more general code in `validate_call` - unless arg0_type.valid?(arg0) - CallValidation.report_error( - method_sig, - method_sig.arg_types[0][1].error_message_for_obj(arg0), - 'Parameter', - method_sig.arg_types[0][0], - arg0_type, - arg0, - caller_offset: -1 - ) - end - - unless arg1_type.valid?(arg1) - CallValidation.report_error( - method_sig, - method_sig.arg_types[1][1].error_message_for_obj(arg1), - 'Parameter', - method_sig.arg_types[1][0], - arg1_type, - arg1, - caller_offset: -1 - ) - end - - unless arg2_type.valid?(arg2) - CallValidation.report_error( - method_sig, - method_sig.arg_types[2][1].error_message_for_obj(arg2), - 'Parameter', - method_sig.arg_types[2][0], - arg2_type, - arg2, - caller_offset: -1 - ) - end - - unless arg3_type.valid?(arg3) - CallValidation.report_error( - method_sig, - method_sig.arg_types[3][1].error_message_for_obj(arg3), - 'Parameter', - method_sig.arg_types[3][0], - arg3_type, - arg3, - caller_offset: -1 - ) - end - - # The following line breaks are intentional to show nice pry message - - - - - - - - - - - # PRY note: - # this code is sig validation code. - # Please issue `finish` to step out of it - - original_method.bind_call(self, arg0, arg1, arg2, arg3, &blk) - T::Private::Types::Void::VOID - end - end - -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/decl_builder.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/decl_builder.rb deleted file mode 100644 index b48b1d5b68..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/decl_builder.rb +++ /dev/null @@ -1,232 +0,0 @@ -# frozen_string_literal: true -# typed: true - -module T::Private::Methods - Declaration = Struct.new(:mod, :params, :returns, :bind, :mode, :checked, :finalized, :on_failure, :override_allow_incompatible, :type_parameters, :raw) - - class DeclBuilder - attr_reader :decl - - class BuilderError < StandardError; end - - private def check_live! - if decl.finalized - raise BuilderError.new("You can't modify a signature declaration after it has been used.") - end - end - - def initialize(mod, raw) - # TODO RUBYPLAT-1278 - with ruby 2.5, use kwargs here - @decl = Declaration.new( - mod, - ARG_NOT_PROVIDED, # params - ARG_NOT_PROVIDED, # returns - ARG_NOT_PROVIDED, # bind - Modes.standard, # mode - ARG_NOT_PROVIDED, # checked - false, # finalized - ARG_NOT_PROVIDED, # on_failure - nil, # override_allow_incompatible - ARG_NOT_PROVIDED, # type_parameters - raw - ) - end - - def params(**params) - check_live! - if !decl.params.equal?(ARG_NOT_PROVIDED) - raise BuilderError.new("You can't call .params twice") - end - - if params.empty? - raise BuilderError.new("params expects keyword arguments") - end - decl.params = params - - self - end - - def returns(type) - check_live! - if decl.returns.is_a?(T::Private::Types::Void) - raise BuilderError.new("You can't call .returns after calling .void.") - end - if !decl.returns.equal?(ARG_NOT_PROVIDED) - raise BuilderError.new("You can't call .returns multiple times in a signature.") - end - - decl.returns = type - - self - end - - def void - check_live! - if !decl.returns.equal?(ARG_NOT_PROVIDED) - raise BuilderError.new("You can't call .void after calling .returns.") - end - - decl.returns = T::Private::Types::Void.new - - self - end - - def bind(type) - check_live! - if !decl.bind.equal?(ARG_NOT_PROVIDED) - raise BuilderError.new("You can't call .bind multiple times in a signature.") - end - - decl.bind = type - - self - end - - def checked(level) - check_live! - - if !decl.checked.equal?(ARG_NOT_PROVIDED) - raise BuilderError.new("You can't call .checked multiple times in a signature.") - end - if (level == :never || level == :compiled) && !decl.on_failure.equal?(ARG_NOT_PROVIDED) - raise BuilderError.new("You can't use .checked(:#{level}) with .on_failure because .on_failure will have no effect.") - end - if !T::Private::RuntimeLevels::LEVELS.include?(level) - raise BuilderError.new("Invalid `checked` level '#{level}'. Use one of: #{T::Private::RuntimeLevels::LEVELS}.") - end - - decl.checked = level - - self - end - - def on_failure(*args) - check_live! - - if !decl.on_failure.equal?(ARG_NOT_PROVIDED) - raise BuilderError.new("You can't call .on_failure multiple times in a signature.") - end - if decl.checked == :never || decl.checked == :compiled - raise BuilderError.new("You can't use .on_failure with .checked(:#{decl.checked}) because .on_failure will have no effect.") - end - - decl.on_failure = args - - self - end - - def abstract - check_live! - - case decl.mode - when Modes.standard - decl.mode = Modes.abstract - when Modes.abstract - raise BuilderError.new(".abstract cannot be repeated in a single signature") - else - raise BuilderError.new("`.abstract` cannot be combined with `.override` or `.overridable`.") - end - - self - end - - def final - check_live! - raise BuilderError.new("The syntax for declaring a method final is `sig(:final) {...}`, not `sig {final. ...}`") - end - - def override(allow_incompatible: false) - check_live! - - case decl.mode - when Modes.standard - decl.mode = Modes.override - decl.override_allow_incompatible = allow_incompatible - when Modes.override, Modes.overridable_override - raise BuilderError.new(".override cannot be repeated in a single signature") - when Modes.overridable - decl.mode = Modes.overridable_override - else - raise BuilderError.new("`.override` cannot be combined with `.abstract`.") - end - - self - end - - def overridable - check_live! - - case decl.mode - when Modes.abstract - raise BuilderError.new("`.overridable` cannot be combined with `.#{decl.mode}`") - when Modes.override - decl.mode = Modes.overridable_override - when Modes.standard - decl.mode = Modes.overridable - when Modes.overridable, Modes.overridable_override - raise BuilderError.new(".overridable cannot be repeated in a single signature") - end - - self - end - - # Declares valid type paramaters which can be used with `T.type_parameter` in - # this `sig`. - # - # This is used for generic methods. Example usage: - # - # sig do - # type_parameters(:U) - # .params(blk: T.proc.params(arg0: Elem).returns(T.type_parameter(:U))) - # .returns(T::Array[T.type_parameter(:U)]) - # end - # def map(&blk); end - def type_parameters(*names) - check_live! - - names.each do |name| - raise BuilderError.new("not a symbol: #{name}") unless name.is_a?(Symbol) - end - - if !decl.type_parameters.equal?(ARG_NOT_PROVIDED) - raise BuilderError.new("You can't call .type_parameters multiple times in a signature.") - end - - decl.type_parameters = names - - self - end - - def finalize! - check_live! - - if decl.returns.equal?(ARG_NOT_PROVIDED) - raise BuilderError.new("You must provide a return type; use the `.returns` or `.void` builder methods.") - end - - if decl.bind.equal?(ARG_NOT_PROVIDED) - decl.bind = nil - end - if decl.checked.equal?(ARG_NOT_PROVIDED) - default_checked_level = T::Private::RuntimeLevels.default_checked_level - if (default_checked_level == :never || default_checked_level == :compiled) && !decl.on_failure.equal?(ARG_NOT_PROVIDED) - raise BuilderError.new("To use .on_failure you must additionally call .checked(:tests) or .checked(:always), otherwise, the .on_failure has no effect.") - end - decl.checked = default_checked_level - end - if decl.on_failure.equal?(ARG_NOT_PROVIDED) - decl.on_failure = nil - end - if decl.params.equal?(ARG_NOT_PROVIDED) - decl.params = {} - end - if decl.type_parameters.equal?(ARG_NOT_PROVIDED) - decl.type_parameters = {} - end - - decl.finalized = true - - self - end - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/modes.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/modes.rb deleted file mode 100644 index 53d9a93195..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/modes.rb +++ /dev/null @@ -1,28 +0,0 @@ -# frozen_string_literal: true -# typed: true - -module T::Private::Methods::Modes - def self.standard - 'standard' - end - def self.abstract - 'abstract' - end - def self.overridable - 'overridable' - end - def self.override - 'override' - end - def self.overridable_override - 'overridable_override' - end - def self.untyped - 'untyped' - end - MODES = [self.standard, self.abstract, self.overridable, self.override, self.overridable_override, self.untyped].freeze - - OVERRIDABLE_MODES = [self.override, self.overridable, self.overridable_override, self.untyped, self.abstract].freeze - OVERRIDE_MODES = [self.override, self.overridable_override].freeze - NON_OVERRIDE_MODES = MODES - OVERRIDE_MODES -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/signature.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/signature.rb deleted file mode 100644 index bd15977bd5..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/signature.rb +++ /dev/null @@ -1,225 +0,0 @@ -# frozen_string_literal: true -# typed: true - -class T::Private::Methods::Signature - attr_reader :method, :method_name, :arg_types, :kwarg_types, :block_type, :block_name, - :rest_type, :rest_name, :keyrest_type, :keyrest_name, :bind, - :return_type, :mode, :req_arg_count, :req_kwarg_names, :has_rest, :has_keyrest, - :check_level, :parameters, :on_failure, :override_allow_incompatible, - :defined_raw - - def self.new_untyped(method:, mode: T::Private::Methods::Modes.untyped, parameters: method.parameters) - # Using `Untyped` ensures we'll get an error if we ever try validation on these. - not_typed = T::Private::Types::NotTyped.new - raw_return_type = not_typed - # Map missing parameter names to "argN" positionally - parameters = parameters.each_with_index.map do |(param_kind, param_name), index| - [param_kind, param_name || "arg#{index}"] - end - raw_arg_types = parameters.map do |_param_kind, param_name| - [param_name, not_typed] - end.to_h - - self.new( - method: method, - method_name: method.name, - raw_arg_types: raw_arg_types, - raw_return_type: raw_return_type, - bind: nil, - mode: mode, - check_level: :never, - parameters: parameters, - on_failure: nil, - ) - end - - def initialize(method:, method_name:, raw_arg_types:, raw_return_type:, bind:, mode:, check_level:, on_failure:, parameters: method.parameters, override_allow_incompatible: false, defined_raw: false) - @method = method - @method_name = method_name - @arg_types = [] - @kwarg_types = {} - @block_type = nil - @block_name = nil - @rest_type = nil - @rest_name = nil - @keyrest_type = nil - @keyrest_name = nil - @return_type = T::Utils.coerce(raw_return_type) - @bind = bind ? T::Utils.coerce(bind) : bind - @mode = mode - @check_level = check_level - @req_arg_count = 0 - @req_kwarg_names = [] - @has_rest = false - @has_keyrest = false - @parameters = parameters - @on_failure = on_failure - @override_allow_incompatible = override_allow_incompatible - @defined_raw = defined_raw - - declared_param_names = raw_arg_types.keys - # If sig params are declared but there is a single parameter with a missing name - # **and** the method ends with a "=", assume it is a writer method generated - # by attr_writer or attr_accessor - writer_method = declared_param_names != [nil] && parameters == [[:req]] && method_name[-1] == "=" - # For writer methods, map the single parameter to the method name without the "=" at the end - parameters = [[:req, method_name[0...-1].to_sym]] if writer_method - param_names = parameters.map {|_, name| name} - missing_names = param_names - declared_param_names - extra_names = declared_param_names - param_names - if !missing_names.empty? - raise "The declaration for `#{method.name}` is missing parameter(s): #{missing_names.join(', ')}" - end - if !extra_names.empty? - raise "The declaration for `#{method.name}` has extra parameter(s): #{extra_names.join(', ')}" - end - - if parameters.size != raw_arg_types.size - raise "The declaration for `#{method.name}` has arguments with duplicate names" - end - - parameters.zip(raw_arg_types) do |(param_kind, param_name), (type_name, raw_type)| - if type_name != param_name - hint = "" - # Ruby reorders params so that required keyword arguments - # always precede optional keyword arguments. We can't tell - # whether the culprit is the Ruby reordering or user error, so - # we error but include a note - if param_kind == :keyreq && parameters.any? {|k, _| k == :key} - hint = "\n\nNote: Any required keyword arguments must precede any optional keyword " \ - "arguments. If your method declaration matches your `def`, try reordering any " \ - "optional keyword parameters to the end of the method list." - end - - raise "Parameter `#{type_name}` is declared out of order (declared as arg number " \ - "#{declared_param_names.index(type_name) + 1}, defined in the method as arg number " \ - "#{param_names.index(type_name) + 1}).#{hint}\nMethod: #{method_desc}" - end - - type = T::Utils.coerce(raw_type) - - case param_kind - when :req - if @arg_types.length > @req_arg_count - # Note that this is actually is supported by Ruby, but it would add complexity to - # support it here, and I'm happy to discourage its use anyway. - # - # If you are seeing this error and surprised by it, it's possible that you have - # overridden the method described in the error message. For example, Rails defines - # def self.update!(id = :all, attributes) - # on AR models. If you have also defined `self.update!` on an AR model you might - # see this error. The simplest resolution is to rename your method. - raise "Required params after optional params are not supported in method declarations. Method: #{method_desc}" - end - @arg_types << [param_name, type] - @req_arg_count += 1 - when :opt - @arg_types << [param_name, type] - when :key, :keyreq - @kwarg_types[param_name] = type - if param_kind == :keyreq - @req_kwarg_names << param_name - end - when :block - @block_name = param_name - @block_type = type - when :rest - @has_rest = true - @rest_name = param_name - @rest_type = type - when :keyrest - @has_keyrest = true - @keyrest_name = param_name - @keyrest_type = type - else - raise "Unexpected param_kind: `#{param_kind}`. Method: #{method_desc}" - end - end - end - - attr_writer :method_name - protected :method_name= - - def as_alias(alias_name) - new_sig = clone - new_sig.method_name = alias_name - new_sig - end - - def arg_count - @arg_types.length - end - - def kwarg_names - @kwarg_types.keys - end - - def owner - @method.owner - end - - def dsl_method - "#{@mode}_method" - end - - # @return [Hash] a mapping like `{arg_name: [val, type], ...}`, for only those args actually present. - def each_args_value_type(args) - # Manually split out args and kwargs based on ruby's behavior. Do not try to implement this by - # getting ruby to determine the kwargs for you (e.g., by defining this method to take *args and - # **kwargs). That won't work, because ruby's behavior for determining kwargs is dependent on the - # the other parameters in the method definition, and our method definition here doesn't (and - # can't) match the definition of the method we're validating. In addition, Ruby has a bug that - # causes forwarding **kwargs to do the wrong thing: see https://bugs.ruby-lang.org/issues/10708 - # and https://bugs.ruby-lang.org/issues/11860. - args_length = args.length - if (args_length > @req_arg_count) && (!@kwarg_types.empty? || @has_keyrest) && args[-1].is_a?(Hash) - kwargs = args[-1] - args_length -= 1 - else - kwargs = EMPTY_HASH - end - - arg_types = @arg_types - - if @has_rest - rest_count = args_length - @arg_types.length - rest_count = 0 if rest_count.negative? - - arg_types += [[@rest_name, @rest_type]] * rest_count - - elsif (args_length < @req_arg_count) || (args_length > @arg_types.length) - expected_str = @req_arg_count.to_s - if @arg_types.length != @req_arg_count - expected_str += "..#{@arg_types.length}" - end - raise ArgumentError.new("wrong number of arguments (given #{args_length}, expected #{expected_str})") - end - - begin - it = 0 - while it < args_length - yield arg_types[it][0], args[it], arg_types[it][1] - it += 1 - end - end - - kwargs.each do |name, val| - type = @kwarg_types[name] - if !type && @has_keyrest - type = @keyrest_type - end - yield name, val, type if type - end - end - - def method_desc - loc = if @method.source_location - @method.source_location.join(':') - else - "" - end - "#{@method} at #{loc}" - end - - EMPTY_HASH = {}.freeze -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/signature_validation.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/signature_validation.rb deleted file mode 100644 index 16188e0bf3..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/methods/signature_validation.rb +++ /dev/null @@ -1,225 +0,0 @@ -# frozen_string_literal: true -# typed: true - -module T::Private::Methods::SignatureValidation - Methods = T::Private::Methods - Modes = Methods::Modes - - def self.validate(signature) - if signature.method_name == :initialize && signature.method.owner.is_a?(Class) - # Constructors are special. They look like overrides in terms of a super_method existing, - # but in practice, you never call them polymorphically. Conceptually, they're standard - # methods (this is consistent with how they're treated in other languages, e.g. Java) - if signature.mode != Modes.standard - raise "`initialize` should not use `.abstract` or `.implementation` or any other inheritance modifiers." - end - return - end - - super_method = signature.method.super_method - - if super_method && super_method.owner != signature.method.owner - Methods.maybe_run_sig_block_for_method(super_method) - super_signature = Methods.signature_for_method(super_method) - - # If the super_method has any kwargs we can't build a - # Signature for it, so we'll just skip validation in that case. - if !super_signature && !super_method.parameters.select {|kind, _| kind == :rest || kind == :kwrest}.empty? - nil - else - # super_signature can be nil when we're overriding a method (perhaps a builtin) that didn't use - # one of the method signature helpers. Use an untyped signature so we can still validate - # everything but types. - # - # We treat these signatures as overridable, that way people can use `.override` with - # overrides of builtins. In the future we could try to distinguish when the method is a - # builtin and treat non-builtins as non-overridable (so you'd be forced to declare them with - # `.overridable`). - # - super_signature ||= Methods::Signature.new_untyped(method: super_method) - - validate_override_mode(signature, super_signature) - validate_override_shape(signature, super_signature) - validate_override_types(signature, super_signature) - end - else - validate_non_override_mode(signature) - end - end - - private_class_method def self.pretty_mode(signature) - if signature.mode == Modes.overridable_override - '.overridable.override' - else - ".#{signature.mode}" - end - end - - def self.validate_override_mode(signature, super_signature) - case signature.mode - when *Modes::OVERRIDE_MODES - # Peaceful - when *Modes::NON_OVERRIDE_MODES - if super_signature.mode == Modes.standard - # Peaceful - elsif super_signature.mode == Modes.abstract - raise "You must use `.override` when overriding the abstract method `#{signature.method_name}`.\n" \ - " Abstract definition: #{method_loc_str(super_signature.method)}\n" \ - " Implementation definition: #{method_loc_str(signature.method)}\n" - elsif super_signature.mode != Modes.untyped - raise "You must use `.override` when overriding the existing method `#{signature.method_name}`.\n" \ - " Parent definition: #{method_loc_str(super_signature.method)}\n" \ - " Child definition: #{method_loc_str(signature.method)}\n" - end - else - raise "Unexpected mode: #{signature.mode}. Please report this bug at https://github.com/sorbet/sorbet/issues" - end - end - - def self.validate_non_override_mode(signature) - case signature.mode - when Modes.override - if signature.method_name == :each && signature.method.owner < Enumerable - # Enumerable#each is the only method in Sorbet's RBI payload that defines an abstract method. - # Enumerable#each does not actually exist at runtime, but it is required to be implemented by - # any class which includes Enumerable. We want to declare Enumerable#each as abstract so that - # people can call it anything which implements the Enumerable interface, and so that it's a - # static error to forget to implement it. - # - # This is a one-off hack, and we should think carefully before adding more methods here. - nil - else - raise "You marked `#{signature.method_name}` as #{pretty_mode(signature)}, but that method doesn't already exist in this class/module to be overriden.\n" \ - " Either check for typos and for missing includes or super classes to make the parent method shows up\n" \ - " ... or remove #{pretty_mode(signature)} here: #{method_loc_str(signature.method)}\n" - end - when Modes.standard, *Modes::NON_OVERRIDE_MODES - # Peaceful - nil - else - raise "Unexpected mode: #{signature.mode}. Please report this bug at https://github.com/sorbet/sorbet/issues" - end - - # Given a singleton class, we can check if it belongs to a - # module by looking at its superclass; given `module M`, - # `M.singleton_class.superclass == Module`, which is not true - # for any class. - owner = signature.method.owner - if (signature.mode == Modes.abstract || Modes::OVERRIDABLE_MODES.include?(signature.mode)) && - owner.singleton_class? && owner.superclass == Module - raise "Defining an overridable class method (via #{pretty_mode(signature)}) " \ - "on a module is not allowed. Class methods on " \ - "modules do not get inherited and thus cannot be overridden." - end - end - - def self.validate_override_shape(signature, super_signature) - return if signature.override_allow_incompatible - return if super_signature.mode == Modes.untyped - - method_name = signature.method_name - mode_verb = super_signature.mode == Modes.abstract ? 'implements' : 'overrides' - - if !signature.has_rest && signature.arg_count < super_signature.arg_count - raise "Your definition of `#{method_name}` must accept at least #{super_signature.arg_count} " \ - "positional arguments to be compatible with the method it #{mode_verb}: " \ - "#{base_override_loc_str(signature, super_signature)}" - end - - if !signature.has_rest && super_signature.has_rest - raise "Your definition of `#{method_name}` must have `*#{super_signature.rest_name}` " \ - "to be compatible with the method it #{mode_verb}: " \ - "#{base_override_loc_str(signature, super_signature)}" - end - - if signature.req_arg_count > super_signature.req_arg_count - raise "Your definition of `#{method_name}` must have no more than #{super_signature.req_arg_count} " \ - "required argument(s) to be compatible with the method it #{mode_verb}: " \ - "#{base_override_loc_str(signature, super_signature)}" - end - - if !signature.has_keyrest - # O(nm), but n and m are tiny here - missing_kwargs = super_signature.kwarg_names - signature.kwarg_names - if !missing_kwargs.empty? - raise "Your definition of `#{method_name}` is missing these keyword arg(s): #{missing_kwargs} " \ - "which are defined in the method it #{mode_verb}: " \ - "#{base_override_loc_str(signature, super_signature)}" - end - end - - if !signature.has_keyrest && super_signature.has_keyrest - raise "Your definition of `#{method_name}` must have `**#{super_signature.keyrest_name}` " \ - "to be compatible with the method it #{mode_verb}: " \ - "#{base_override_loc_str(signature, super_signature)}" - end - - # O(nm), but n and m are tiny here - extra_req_kwargs = signature.req_kwarg_names - super_signature.req_kwarg_names - if !extra_req_kwargs.empty? - raise "Your definition of `#{method_name}` has extra required keyword arg(s) " \ - "#{extra_req_kwargs} relative to the method it #{mode_verb}, making it incompatible: " \ - "#{base_override_loc_str(signature, super_signature)}" - end - - if super_signature.block_name && !signature.block_name - raise "Your definition of `#{method_name}` must accept a block parameter to be compatible " \ - "with the method it #{mode_verb}: " \ - "#{base_override_loc_str(signature, super_signature)}" - end - end - - def self.validate_override_types(signature, super_signature) - return if signature.override_allow_incompatible - return if super_signature.mode == Modes.untyped - return unless [signature, super_signature].all? do |sig| - sig.check_level == :always || sig.check_level == :compiled || (sig.check_level == :tests && T::Private::RuntimeLevels.check_tests?) - end - mode_noun = super_signature.mode == Modes.abstract ? 'implementation' : 'override' - - # arg types must be contravariant - super_signature.arg_types.zip(signature.arg_types).each_with_index do |((_super_name, super_type), (name, type)), index| - if !super_type.subtype_of?(type) - raise "Incompatible type for arg ##{index + 1} (`#{name}`) in signature for #{mode_noun} of method " \ - "`#{signature.method_name}`:\n" \ - "* Base: `#{super_type}` (in #{method_loc_str(super_signature.method)})\n" \ - "* #{mode_noun.capitalize}: `#{type}` (in #{method_loc_str(signature.method)})\n" \ - "(The types must be contravariant.)" - end - end - - # kwarg types must be contravariant - super_signature.kwarg_types.each do |name, super_type| - type = signature.kwarg_types[name] - if !super_type.subtype_of?(type) - raise "Incompatible type for arg `#{name}` in signature for #{mode_noun} of method `#{signature.method_name}`:\n" \ - "* Base: `#{super_type}` (in #{method_loc_str(super_signature.method)})\n" \ - "* #{mode_noun.capitalize}: `#{type}` (in #{method_loc_str(signature.method)})\n" \ - "(The types must be contravariant.)" - end - end - - # return types must be covariant - if !signature.return_type.subtype_of?(super_signature.return_type) - raise "Incompatible return type in signature for #{mode_noun} of method `#{signature.method_name}`:\n" \ - "* Base: `#{super_signature.return_type}` (in #{method_loc_str(super_signature.method)})\n" \ - "* #{mode_noun.capitalize}: `#{signature.return_type}` (in #{method_loc_str(signature.method)})\n" \ - "(The types must be covariant.)" - end - end - - private_class_method def self.base_override_loc_str(signature, super_signature) - mode_noun = super_signature.mode == Modes.abstract ? 'Implementation' : 'Override' - "\n * Base definition: in #{method_loc_str(super_signature.method)}" \ - "\n * #{mode_noun}: in #{method_loc_str(signature.method)}" - end - - private_class_method def self.method_loc_str(method) - loc = if method.source_location - method.source_location.join(':') - else - "" - end - "#{method.owner} at #{loc}" - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/mixins/mixins.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/mixins/mixins.rb deleted file mode 100644 index 01eb42bd3a..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/mixins/mixins.rb +++ /dev/null @@ -1,27 +0,0 @@ -# frozen_string_literal: true -# typed: true - -module T::Private - module MixesInClassMethods - def included(other) - mods = Abstract::Data.get(self, :class_methods_mixins) - mods.each {|mod| other.extend(mod)} - super - end - end - - module Mixins - def self.declare_mixes_in_class_methods(mixin, class_methods) - if mixin.is_a?(Class) - raise "Classes cannot be used as mixins, and so mixes_in_class_methods cannot be used on a Class." - end - - if Abstract::Data.key?(mixin, :class_methods_mixins) - class_methods = Abstract::Data.get(mixin, :class_methods_mixins) + class_methods - end - - mixin.singleton_class.include(MixesInClassMethods) - Abstract::Data.set(mixin, :class_methods_mixins, class_methods) - end - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/retry.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/retry.rb deleted file mode 100644 index 7b2822d394..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/retry.rb +++ /dev/null @@ -1,10 +0,0 @@ -# frozen_string_literal: true -# typed: true - -module T::Private::Retry - - # A special singleton used for static analysis of exceptions. - module RETRY - freeze - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/runtime_levels.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/runtime_levels.rb deleted file mode 100644 index 2454b21988..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/runtime_levels.rb +++ /dev/null @@ -1,62 +0,0 @@ -# frozen_string_literal: true -# typed: true - -# Used in `sig.checked(level)` to determine when runtime type checking -# is enabled on a method. -module T::Private::RuntimeLevels - LEVELS = [ - # Validate every call in every environment - :always, - # Validate in tests, but not in production - :tests, - # Don't even validate in tests, b/c too expensive, - # or b/c we fully trust the static typing - :never, - # Validate the sig when the file is using the Sorbet Compiler. - # Behaves like :never when interpreted. - :compiled, - ].freeze - - @check_tests = false - @wrapped_tests_with_validation = false - - @has_read_default_checked_level = false - @default_checked_level = :always - - def self.check_tests? - # Assume that this code path means that some `sig.checked(:tests)` - # has been wrapped (or not wrapped) already, which is a trapdoor - # for toggling `@check_tests`. - @wrapped_tests_with_validation = true - - @check_tests - end - - def self.enable_checking_in_tests - if !@check_tests && @wrapped_tests_with_validation - all_checked_tests_sigs = T::Private::Methods.all_checked_tests_sigs - locations = all_checked_tests_sigs.map {|sig| sig.method.source_location.join(':')}.join("\n- ") - raise "Toggle `:tests`-level runtime type checking earlier. " \ - "There are already some methods wrapped with `sig.checked(:tests)`:\n" \ - "- #{locations}" - end - - _toggle_checking_tests(true) - end - - def self.default_checked_level - @has_read_default_checked_level = true - @default_checked_level - end - - def self.default_checked_level=(default_checked_level) - if @has_read_default_checked_level - raise "Set the default checked level earlier. There are already some methods whose sig blocks have evaluated which would not be affected by the new default." - end - @default_checked_level = default_checked_level - end - - def self._toggle_checking_tests(checked) - @check_tests = checked - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/sealed.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/sealed.rb deleted file mode 100644 index 62e19fb088..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/sealed.rb +++ /dev/null @@ -1,91 +0,0 @@ -# frozen_string_literal: true -# typed: false - -module T::Private::Sealed - module NoInherit - def inherited(child) - super - this_line = Kernel.caller.find {|line| !line.match(/in `inherited'$/)} - T::Private::Sealed.validate_inheritance(this_line, self, child, 'inherited') - @sorbet_sealed_module_all_subclasses << child - end - - def sealed_subclasses - @sorbet_sealed_module_all_subclasses_set ||= # rubocop:disable Naming/MemoizedInstanceVariableName - begin - require 'set' - Set.new(@sorbet_sealed_module_all_subclasses).freeze - end - end - end - - module NoIncludeExtend - def included(child) - super - this_line = Kernel.caller.find {|line| !line.match(/in `included'$/)} - T::Private::Sealed.validate_inheritance(this_line, self, child, 'included') - @sorbet_sealed_module_all_subclasses << child - end - - def extended(child) - super - this_line = Kernel.caller.find {|line| !line.match(/in `extended'$/)} - T::Private::Sealed.validate_inheritance(this_line, self, child, 'extended') - @sorbet_sealed_module_all_subclasses << child - end - - def sealed_subclasses - # this will freeze the set so that you can never get into a - # state where you use the subclasses list and then something - # else will add to it - @sorbet_sealed_module_all_subclasses_set ||= # rubocop:disable Naming/MemoizedInstanceVariableName - begin - require 'set' - Set.new(@sorbet_sealed_module_all_subclasses).freeze - end - end - end - - def self.declare(mod, decl_file) - if !mod.is_a?(Module) - raise "#{mod} is not a class or module and cannot be declared `sealed!`" - end - if sealed_module?(mod) - raise "#{mod} was already declared `sealed!` and cannot be re-declared `sealed!`" - end - if T::Private::Final.final_module?(mod) - raise "#{mod} was already declared `final!` and cannot be declared `sealed!`" - end - mod.extend(mod.is_a?(Class) ? NoInherit : NoIncludeExtend) - if !decl_file - raise "Couldn't determine declaration file for sealed class." - end - mod.instance_variable_set(:@sorbet_sealed_module_decl_file, decl_file) - mod.instance_variable_set(:@sorbet_sealed_module_all_subclasses, []) - end - - def self.sealed_module?(mod) - mod.instance_variable_defined?(:@sorbet_sealed_module_decl_file) - end - - def self.validate_inheritance(this_line, parent, child, verb) - this_file = this_line&.split(':')&.first - decl_file = parent.instance_variable_get(:@sorbet_sealed_module_decl_file) if sealed_module?(parent) - - if !this_file - raise "Could not use backtrace to determine file for #{verb} child #{child}" - end - if !decl_file - raise "#{parent} does not seem to be a sealed module (#{verb} by #{child})" - end - - if !this_file.start_with?(decl_file) - whitelist = T::Configuration.sealed_violation_whitelist - if !whitelist.nil? && whitelist.any? {|pattern| this_file =~ pattern} - return - end - - raise "#{parent} was declared sealed and can only be #{verb} in #{decl_file}, not #{this_file}" - end - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/types/not_typed.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/types/not_typed.rb deleted file mode 100644 index 57196553b6..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/types/not_typed.rb +++ /dev/null @@ -1,23 +0,0 @@ -# frozen_string_literal: true -# typed: true - -# A placeholder for when an untyped thing must provide a type. -# Raises an exception if it is ever used for validation. -class T::Private::Types::NotTyped < T::Types::Base - ERROR_MESSAGE = "Validation is being done on a `NotTyped`. Please report this bug at https://github.com/sorbet/sorbet/issues" - - # overrides Base - def name - "" - end - - # overrides Base - def valid?(obj) - raise ERROR_MESSAGE - end - - # overrides Base - private def subtype_of_single?(other) - raise ERROR_MESSAGE - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/types/string_holder.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/types/string_holder.rb deleted file mode 100644 index b2295f7730..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/types/string_holder.rb +++ /dev/null @@ -1,26 +0,0 @@ -# frozen_string_literal: true -# typed: true - -# Holds a string. Useful for showing type aliases in error messages -class T::Private::Types::StringHolder < T::Types::Base - attr_reader :string - - def initialize(string) - @string = string - end - - # overrides Base - def name - string - end - - # overrides Base - def valid?(obj) - false - end - - # overrides Base - private def subtype_of_single?(other) - false - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/types/type_alias.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/types/type_alias.rb deleted file mode 100644 index de805c9659..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/types/type_alias.rb +++ /dev/null @@ -1,31 +0,0 @@ -# frozen_string_literal: true -# typed: true - -module T::Private::Types - # Wraps a proc for a type alias to defer its evaluation. - class TypeAlias < T::Types::Base - - def initialize(callable) - @callable = callable - end - - def aliased_type - @aliased_type ||= T::Utils.coerce(@callable.call) - end - - # overrides Base - def name - aliased_type.name - end - - # overrides Base - def recursively_valid?(obj) - aliased_type.recursively_valid?(obj) - end - - # overrides Base - def valid?(obj) - aliased_type.valid?(obj) - end - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/types/void.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/types/void.rb deleted file mode 100644 index 310fc56abc..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/private/types/void.rb +++ /dev/null @@ -1,34 +0,0 @@ -# frozen_string_literal: true -# typed: true - -# A marking class for when methods return void. -# Should never appear in types directly. -class T::Private::Types::Void < T::Types::Base - ERROR_MESSAGE = "Validation is being done on an `Void`. Please report this bug at https://github.com/sorbet/sorbet/issues" - - # The actual return value of `.void` methods. - # - # Uses `module VOID` because this gives it a readable name when someone - # examines it in Pry or with `#inspect` like: - # - # T::Private::Types::Void::VOID - # - module VOID - freeze - end - - # overrides Base - def name - "" - end - - # overrides Base - def valid?(obj) - raise ERROR_MESSAGE - end - - # overrides Base - private def subtype_of_single?(other) - raise ERROR_MESSAGE - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/_props.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/_props.rb deleted file mode 100644 index fae252aa04..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/_props.rb +++ /dev/null @@ -1,169 +0,0 @@ -# frozen_string_literal: true -# typed: true - -# A mixin for defining typed properties (attributes). -# To get serialization methods (to/from JSON-style hashes), add T::Props::Serializable. -# To get a constructor based on these properties, inherit from T::Struct. -module T::Props - extend T::Helpers - - ##### - # CAUTION: This mixin is used in hundreds of classes; we want to keep its surface area as narrow - # as possible and avoid polluting (and possibly conflicting with) the classes that use it. - # - # It currently has *zero* instance methods; let's try to keep it that way. - # For ClassMethods (below), try to add things to T::Props::Decorator instead unless you are sure - # it needs to be exposed here. - ##### - - module ClassMethods - extend T::Sig - extend T::Helpers - - def props - decorator.props - end - def plugins - @plugins ||= [] - end - - def decorator_class - Decorator - end - - def decorator - @decorator ||= decorator_class.new(self) - end - def reload_decorator! - @decorator = decorator_class.new(self) - end - - # Define a new property. See {file:README.md} for some concrete - # examples. - # - # Defining a property defines a method with the same name as the - # property, that returns the current value, and a `prop=` method - # to set its value. Properties will be inherited by subclasses of - # a document class. - # - # @param name [Symbol] The name of this property - # @param cls [Class,T::Types::Base] The type of this - # property. If the type is itself a `Document` subclass, this - # property will be recursively serialized/deserialized. - # @param rules [Hash] Options to control this property's behavior. - # @option rules [T::Boolean,Symbol] :optional If `true`, this property - # is never required to be set before an instance is serialized. - # If `:on_load` (default), when this property is missing or nil, a - # new model cannot be saved, and an existing model can only be - # saved if the property was already missing when it was loaded. - # If `false`, when the property is missing/nil after deserialization, it - # will be set to the default value (as defined by the `default` or - # `factory` option) or will raise if they are not present. - # Deprecated: For `Model`s, if `:optional` is set to the special value - # `:existing`, the property can be saved as nil even if it was - # deserialized with a non-nil value. (Deprecated because there should - # never be a need for this behavior; the new behavior of non-optional - # properties should be sufficient.) - # @option rules [Array] :enum An array of legal values; The - # property is required to take on one of those values. - # @option rules [T::Boolean] :dont_store If true, this property will - # not be saved on the hash resulting from - # {T::Props::Serializable#serialize} - # @option rules [Object] :ifunset A value to be returned if this - # property is requested but has never been set (is set to - # `nil`). It is applied at property-access time, and never saved - # back onto the object or into the database. - # - # ``:ifunset`` is considered **DEPRECATED** and should not be used - # in new code, in favor of just setting a default value. - # @option rules [Model, Symbol, Proc] :foreign A model class that this - # property is a reference to. Passing `:foreign` will define a - # `:"#{name}_"` method, that will load and return the - # corresponding foreign model. - # - # A symbol can be passed to avoid load-order dependencies; It - # will be lazily resolved relative to the enclosing module of the - # defining class. - # - # A callable (proc or method) can be passed to dynamically specify the - # foreign model. This will be passed the object instance so that other - # properties of the object can be used to determine the relevant model - # class. It should return a string/symbol class name or the foreign model - # class directly. - # - # @option rules [Object] :default A default value that will be set - # by `#initialize` if none is provided in the initialization - # hash. This will not affect objects loaded by {.from_hash}. - # @option rules [Proc] :factory A `Proc` that will be called to - # generate an initial value for this prop on `#initialize`, if - # none is provided. - # @option rules [T::Boolean] :immutable If true, this prop cannot be - # modified after an instance is created or loaded from a hash. - # @option rules [T::Boolean] :override It is an error to redeclare a - # `prop` that has already been declared (including on a - # superclass), unless `:override` is set to `true`. - # @option rules [Symbol, Array] :redaction A redaction directive that may - # be passed to Chalk::Tools::RedactionUtils.redact_with_directive to - # sanitize this parameter for display. Will define a - # `:"#{name}_redacted"` method, which will return the value in sanitized - # form. - # - # @return [void] - sig {params(name: Symbol, cls: T.untyped, rules: T.untyped).void} - def prop(name, cls, rules={}) - cls = T::Utils.coerce(cls) if !cls.is_a?(Module) - decorator.prop_defined(name, cls, rules) - end - - # Validates the value of the specified prop. This method allows the caller to - # validate a value for a prop without having to set the data on the instance. - # Throws if invalid. - # - # @param prop [Symbol] - # @param val [Object] - # @return [void] - def validate_prop_value(prop, val) - decorator.validate_prop_value(prop, val) - end - - # Needs to be documented - def plugin(mod) - decorator.plugin(mod) - end - - # Shorthand helper to define a `prop` with `immutable => true` - sig {params(name: Symbol, cls_or_args: T.untyped, args: T::Hash[Symbol, T.untyped]).void} - def const(name, cls_or_args, args={}) - if (cls_or_args.is_a?(Hash) && cls_or_args.key?(:immutable)) || args.key?(:immutable) - Kernel.raise ArgumentError.new("Cannot pass 'immutable' argument when using 'const' keyword to define a prop") - end - - if cls_or_args.is_a?(Hash) - self.prop(name, cls_or_args.merge(immutable: true)) - else - self.prop(name, cls_or_args, args.merge(immutable: true)) - end - end - - def included(child) - decorator.model_inherited(child) - super - end - - def prepended(child) - decorator.model_inherited(child) - super - end - - def extended(child) - decorator.model_inherited(child.singleton_class) - super - end - - def inherited(child) - decorator.model_inherited(child) - super - end - end - mixes_in_class_methods(ClassMethods) -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/constructor.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/constructor.rb deleted file mode 100644 index 570c068ac4..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/constructor.rb +++ /dev/null @@ -1,40 +0,0 @@ -# frozen_string_literal: true -# typed: false - -module T::Props::Constructor - include T::Props::WeakConstructor -end - -module T::Props::Constructor::DecoratorMethods - extend T::Sig - - # Set values for all props that have no defaults. Override what `WeakConstructor` - # does in order to raise errors on nils instead of ignoring them. - # - # @return [Integer] A count of props that we successfully initialized (which - # we'll use to check for any unrecognized input.) - # - # checked(:never) - O(runtime object construction) - sig {params(instance: T::Props::Constructor, hash: T::Hash[Symbol, T.untyped]).returns(Integer).checked(:never)} - def construct_props_without_defaults(instance, hash) - # Use `each_pair` rather than `count` because, as of Ruby 2.6, the latter delegates to Enumerator - # and therefore allocates for each entry. - result = 0 - props_without_defaults&.each_pair do |p, setter_proc| - begin - val = hash[p] - instance.instance_exec(val, &setter_proc) - if val || hash.key?(p) - result += 1 - end - rescue TypeError, T::Props::InvalidValueError - if !hash.key?(p) - raise ArgumentError.new("Missing required prop `#{p}` for class `#{instance.class.name}`") - else - raise - end - end - end - result - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/custom_type.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/custom_type.rb deleted file mode 100644 index 0df6a0d863..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/custom_type.rb +++ /dev/null @@ -1,108 +0,0 @@ -# frozen_string_literal: true -# typed: strict - -module T::Props - module CustomType - extend T::Sig - extend T::Helpers - - abstract! - - include Kernel # for `is_a?` - - # Alias for backwards compatibility - sig(:final) do - params( - value: BasicObject, - ) - .returns(T::Boolean) - .checked(:never) - end - def instance?(value) - self.===(value) - end - - # Alias for backwards compatibility - sig(:final) do - params( - value: BasicObject, - ) - .returns(T::Boolean) - .checked(:never) - end - def valid?(value) - instance?(value) - end - - # Given an instance of this type, serialize that into a scalar type - # supported by T::Props. - # - # @param [Object] instance - # @return An instance of one of T::Configuration.scalar_types - sig {abstract.params(instance: T.untyped).returns(T.untyped).checked(:never)} - def serialize(instance); end - - # Given the serialized form of your type, this returns an instance - # of that custom type representing that value. - # - # @param scalar One of T::Configuration.scalar_types - # @return Object - sig {abstract.params(scalar: T.untyped).returns(T.untyped).checked(:never)} - def deserialize(scalar); end - - sig {override.params(_base: Module).void} - def self.included(_base) - super - - raise 'Please use "extend", not "include" to attach this module' - end - - sig(:final) {params(val: Object).returns(T::Boolean).checked(:never)} - def self.scalar_type?(val) - # We don't need to check for val's included modules in - # T::Configuration.scalar_types, because T::Configuration.scalar_types - # are all classes. - klass = T.let(val.class, T.nilable(Class)) - until klass.nil? - return true if T::Configuration.scalar_types.include?(klass.to_s) - klass = klass.superclass - end - false - end - - # We allow custom types to serialize to Arrays, so that we can - # implement set-like fields that store a unique-array, but forbid - # hashes; Custom hash types should be implemented via an emebdded - # T::Struct (or a subclass like Chalk::ODM::Document) or via T. - sig(:final) {params(val: Object).returns(T::Boolean).checked(:never)} - def self.valid_serialization?(val) - case val - when Array - val.each do |v| - return false unless scalar_type?(v) - end - - true - else - scalar_type?(val) - end - end - - sig(:final) do - params(instance: Object) - .returns(T.untyped) - .checked(:never) - end - def self.checked_serialize(instance) - val = T.cast(instance.class, T::Props::CustomType).serialize(instance) - unless valid_serialization?(val) - msg = "#{instance.class} did not serialize to a valid scalar type. It became a: #{val.class}" - if val.is_a?(Hash) - msg += "\nIf you want to store a structured Hash, consider using a T::Struct as your type." - end - raise TypeError.new(msg) - end - val - end - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/decorator.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/decorator.rb deleted file mode 100644 index 679a32584b..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/decorator.rb +++ /dev/null @@ -1,669 +0,0 @@ -# frozen_string_literal: true -# typed: strict - -# NB: This is not actually a decorator. It's just named that way for consistency -# with DocumentDecorator and ModelDecorator (which both seem to have been written -# with an incorrect understanding of the decorator pattern). These "decorators" -# should really just be static methods on private modules (we'd also want/need to -# replace decorator overrides in plugins with class methods that expose the necessary -# functionality). -class T::Props::Decorator - extend T::Sig - - Rules = T.type_alias {T::Hash[Symbol, T.untyped]} - DecoratedInstance = T.type_alias {Object} # Would be T::Props, but that produces circular reference errors in some circumstances - PropType = T.type_alias {T::Types::Base} - PropTypeOrClass = T.type_alias {T.any(PropType, Module)} - - class NoRulesError < StandardError; end - - EMPTY_PROPS = T.let({}.freeze, T::Hash[Symbol, Rules]) - private_constant :EMPTY_PROPS - - sig {params(klass: T.untyped).void.checked(:never)} - def initialize(klass) - @class = T.let(klass, T.all(Module, T::Props::ClassMethods)) - @class.plugins.each do |mod| - T::Props::Plugin::Private.apply_decorator_methods(mod, self) - end - @props = T.let(EMPTY_PROPS, T::Hash[Symbol, Rules]) - end - - # checked(:never) - O(prop accesses) - sig {returns(T::Hash[Symbol, Rules]).checked(:never)} - attr_reader :props - - sig {returns(T::Array[Symbol])} - def all_props - props.keys - end - - # checked(:never) - O(prop accesses) - sig {params(prop: T.any(Symbol, String)).returns(Rules).checked(:never)} - def prop_rules(prop) - props[prop.to_sym] || raise("No such prop: #{prop.inspect}") - end - - # checked(:never) - Rules hash is expensive to check - sig {params(prop: Symbol, rules: Rules).void.checked(:never)} - def add_prop_definition(prop, rules) - override = rules.delete(:override) - - if props.include?(prop) && !override - raise ArgumentError.new("Attempted to redefine prop #{prop.inspect} that's already defined without specifying :override => true: #{prop_rules(prop)}") - elsif !props.include?(prop) && override - raise ArgumentError.new("Attempted to override a prop #{prop.inspect} that doesn't already exist") - end - - @props = @props.merge(prop => rules.freeze).freeze - end - - # Heads up! - # - # There are already too many ad-hoc options on the prop DSL. - # - # We have already done a lot of work to remove unnecessary and confusing - # options. If you're considering adding a new rule key, please come chat with - # the Sorbet team first, as we'd really like to learn more about how to best - # solve the problem you're encountering. - VALID_RULE_KEYS = T.let(%i[ - enum - foreign - ifunset - immutable - override - redaction - sensitivity - without_accessors - clobber_existing_method! - extra - setter_validate - _tnilable - ].map {|k| [k, true]}.to_h.freeze, T::Hash[Symbol, T::Boolean]) - private_constant :VALID_RULE_KEYS - - sig {params(key: Symbol).returns(T::Boolean).checked(:never)} - def valid_rule_key?(key) - !!VALID_RULE_KEYS[key] - end - - # checked(:never) - O(prop accesses) - sig {returns(T.all(Module, T::Props::ClassMethods)).checked(:never)} - def decorated_class - @class - end - - # Accessors - - # Use this to validate that a value will validate for a given prop. Useful for knowing whether a value can be set on a model without setting it. - # - # checked(:never) - potentially O(prop accesses) depending on usage pattern - sig {params(prop: Symbol, val: T.untyped).void.checked(:never)} - def validate_prop_value(prop, val) - # We call `setter_proc` here without binding to an instance, so it'll run - # `instance_variable_set` if validation passes, but nothing will care. - # We only care about the validation. - prop_rules(prop).fetch(:setter_proc).call(val) - end - - # For performance, don't use named params here. - # Passing in rules here is purely a performance optimization. - # Unlike the other methods that take rules, this one calls prop_rules for - # the default, which raises if the prop doesn't exist (this maintains - # preexisting behavior). - # - # Note this path is NOT used by generated setters on instances, - # which are defined using `setter_proc` directly. - # - # checked(:never) - O(prop accesses) - sig do - params( - instance: DecoratedInstance, - prop: Symbol, - val: T.untyped, - rules: Rules - ) - .void - .checked(:never) - end - def prop_set(instance, prop, val, rules=prop_rules(prop)) - instance.instance_exec(val, &rules.fetch(:setter_proc)) - end - alias_method :set, :prop_set - - # Only Models have any custom get logic but we need to call this on - # non-Models since we don't know at code gen time what we have. - sig do - params( - instance: DecoratedInstance, - prop: Symbol, - value: T.untyped - ) - .returns(T.untyped) - .checked(:never) - end - def prop_get_logic(instance, prop, value) - value - end - - # For performance, don't use named params here. - # Passing in rules here is purely a performance optimization. - # - # Note this path is NOT used by generated getters on instances, - # unless `ifunset` is used on the prop, or `prop_get` is overridden. - # - # checked(:never) - O(prop accesses) - sig do - params( - instance: DecoratedInstance, - prop: T.any(String, Symbol), - rules: Rules - ) - .returns(T.untyped) - .checked(:never) - end - def prop_get(instance, prop, rules=prop_rules(prop)) - val = instance.instance_variable_get(rules[:accessor_key]) if instance.instance_variable_defined?(rules[:accessor_key]) - if !val.nil? - val - elsif (d = rules[:ifunset]) - T::Props::Utils.deep_clone_object(d) - else - nil - end - end - - sig do - params( - instance: DecoratedInstance, - prop: T.any(String, Symbol), - rules: Rules - ) - .returns(T.untyped) - .checked(:never) - end - def prop_get_if_set(instance, prop, rules=prop_rules(prop)) - instance.instance_variable_get(rules[:accessor_key]) if instance.instance_variable_defined?(rules[:accessor_key]) - end - alias_method :get, :prop_get_if_set # Alias for backwards compatibility - - # checked(:never) - O(prop accesses) - sig do - params( - instance: DecoratedInstance, - prop: Symbol, - foreign_class: Module, - rules: Rules, - opts: T::Hash[Symbol, T.untyped], - ) - .returns(T.untyped) - .checked(:never) - end - def foreign_prop_get(instance, prop, foreign_class, rules=prop_rules(prop), opts={}) - return if !(value = prop_get(instance, prop, rules)) - T.unsafe(foreign_class).load(value, {}, opts) - end - - # TODO: we should really be checking all the methods on `cls`, not just Object - BANNED_METHOD_NAMES = T.let(Object.instance_methods.each_with_object({}) {|x, acc| acc[x] = true}.freeze, T::Hash[Symbol, TrueClass]) - - # checked(:never) - Rules hash is expensive to check - sig do - params( - name: Symbol, - cls: Module, - rules: Rules, - type: PropTypeOrClass - ) - .void - .checked(:never) - end - def prop_validate_definition!(name, cls, rules, type) - validate_prop_name(name) - - if rules.key?(:pii) - raise ArgumentError.new("The 'pii:' option for props has been renamed " \ - "to 'sensitivity:' (in prop #{@class.name}.#{name})") - end - - if rules.keys.any? {|k| !valid_rule_key?(k)} - raise ArgumentError.new("At least one invalid prop arg supplied in #{self}: #{rules.keys.inspect}") - end - - if !rules[:clobber_existing_method!] && !rules[:without_accessors] && BANNED_METHOD_NAMES.include?(name.to_sym) - raise ArgumentError.new( - "#{name} can't be used as a prop in #{@class} because a method with " \ - "that name already exists (defined by #{@class.instance_method(name).owner} " \ - "at #{@class.instance_method(name).source_location || ''}). " \ - "(If using this name is unavoidable, try `without_accessors: true`.)" - ) - end - - extra = rules[:extra] - if !extra.nil? && !extra.is_a?(Hash) - raise ArgumentError.new("Extra metadata must be a Hash in prop #{@class.name}.#{name}") - end - - nil - end - - SAFE_NAME = T.let(/\A[A-Za-z_][A-Za-z0-9_-]*\z/.freeze, Regexp) - - # Used to validate both prop names and serialized forms - sig {params(name: T.any(Symbol, String)).void} - private def validate_prop_name(name) - if !name.match?(SAFE_NAME) - raise ArgumentError.new("Invalid prop name in #{@class.name}: #{name}") - end - end - - # This converts the type from a T::Type to a regular old ruby class. - sig {params(type: T::Types::Base).returns(Module)} - private def convert_type_to_class(type) - case type - when T::Types::TypedArray, T::Types::FixedArray - Array - when T::Types::TypedHash, T::Types::FixedHash - Hash - when T::Types::TypedSet - Set - when T::Types::Union - # The below unwraps our T.nilable types for T::Props if we can. - # This lets us do things like specify: const T.nilable(String), foreign: Opus::DB::Model::Merchant - non_nil_type = T::Utils.unwrap_nilable(type) - if non_nil_type - convert_type_to_class(non_nil_type) - else - Object - end - when T::Types::Simple - type.raw_type - else - # This isn't allowed unless whitelisted_for_underspecification is - # true, due to the check in prop_validate_definition - Object - end - end - - # Returns `true` when the type of the prop is nilable, or the field is typed - # as `T.untyped`, a `:default` is present in the rules hash, and its value is - # `nil`. The latter case is a workaround for explicitly not supporting the use - # of `T.nilable(T.untyped)`. - # - # checked(:never) - Rules hash is expensive to check - sig do - params( - cls: PropTypeOrClass, - rules: Rules, - ) - .void - .checked(:never) - end - private def prop_nilable?(cls, rules) - T::Utils::Nilable.is_union_with_nilclass(cls) || (cls == T.untyped && rules.key?(:default) && rules[:default].nil?) - end - - # checked(:never) - Rules hash is expensive to check - sig do - params( - name: T.any(Symbol, String), - cls: PropTypeOrClass, - rules: Rules, - ) - .void - .checked(:never) - end - def prop_defined(name, cls, rules={}) - cls = T::Utils.resolve_alias(cls) - - if prop_nilable?(cls, rules) - # :_tnilable is introduced internally for performance purpose so that clients do not need to call - # T::Utils::Nilable.is_tnilable(cls) again. - # It is strictly internal: clients should always use T::Props::Utils.required_prop?() or - # T::Props::Utils.optional_prop?() for checking whether a field is required or optional. - rules[:_tnilable] = true - end - - name = name.to_sym - type = cls - if !cls.is_a?(Module) - cls = convert_type_to_class(cls) - end - type_object = smart_coerce(type, enum: rules[:enum]) - - prop_validate_definition!(name, cls, rules, type_object) - - # Retrive the possible underlying object with T.nilable. - type = T::Utils::Nilable.get_underlying_type(type) - - sensitivity_and_pii = {sensitivity: rules[:sensitivity]} - normalize = T::Configuration.normalize_sensitivity_and_pii_handler - if normalize - sensitivity_and_pii = normalize.call(sensitivity_and_pii) - - # We check for Class so this is only applied on concrete - # documents/models; We allow mixins containing props to not - # specify their PII nature, as long as every class into which they - # are ultimately included does. - # - if sensitivity_and_pii[:pii] && @class.is_a?(Class) && !T.unsafe(@class).contains_pii? - raise ArgumentError.new( - 'Cannot include a pii prop in a class that declares `contains_no_pii`' - ) - end - end - - rules = rules.merge( - # TODO: The type of this element is confusing. We should refactor so that - # it can be always `type_object` (a PropType) or always `cls` (a Module) - type: type, - type_object: type_object, - accessor_key: "@#{name}".to_sym, - sensitivity: sensitivity_and_pii[:sensitivity], - pii: sensitivity_and_pii[:pii], - # extra arbitrary metadata attached by the code defining this property - extra: rules[:extra]&.freeze, - ) - - validate_not_missing_sensitivity(name, rules) - - # for backcompat (the `:array` key is deprecated but because the name is - # so generic it's really hard to be sure it's not being relied on anymore) - if type.is_a?(T::Types::TypedArray) - inner = T::Utils::Nilable.get_underlying_type(type.type) - if inner.is_a?(Module) - rules[:array] = inner - end - end - - rules[:setter_proc] = T::Props::Private::SetterFactory.build_setter_proc(@class, name, rules).freeze - - add_prop_definition(name, rules) - - # NB: using `without_accessors` doesn't make much sense unless you also define some other way to - # get at the property (e.g., Chalk::ODM::Document exposes `get` and `set`). - define_getter_and_setter(name, rules) unless rules[:without_accessors] - - handle_foreign_option(name, cls, rules, rules[:foreign]) if rules[:foreign] - handle_redaction_option(name, rules[:redaction]) if rules[:redaction] - end - - # checked(:never) - Rules hash is expensive to check - sig {params(name: Symbol, rules: Rules).void.checked(:never)} - private def define_getter_and_setter(name, rules) - T::Configuration.without_ruby_warnings do - if !rules[:immutable] - if method(:prop_set).owner != T::Props::Decorator - @class.send(:define_method, "#{name}=") do |val| - T.unsafe(self.class).decorator.prop_set(self, name, val, rules) - end - else - # Fast path (~4x faster as of Ruby 2.6) - @class.send(:define_method, "#{name}=", &rules.fetch(:setter_proc)) - end - end - - if method(:prop_get).owner != T::Props::Decorator || rules.key?(:ifunset) - @class.send(:define_method, name) do - T.unsafe(self.class).decorator.prop_get(self, name, rules) - end - else - # Fast path (~30x faster as of Ruby 2.6) - @class.send(:attr_reader, name) # send is used because `attr_reader` is private in 2.4 - end - end - end - - sig do - params(type: PropTypeOrClass, enum: T.untyped) - .returns(T::Types::Base) - end - private def smart_coerce(type, enum:) - # Backwards compatibility for pre-T::Types style - type = T::Utils.coerce(type) - if enum.nil? - type - else - nonnil_type = T::Utils.unwrap_nilable(type) - if nonnil_type - T.unsafe(T.nilable(T.all(nonnil_type, T.deprecated_enum(enum)))) - else - T.unsafe(T.all(T.unsafe(type), T.deprecated_enum(enum))) - end - end - end - - # checked(:never) - Rules hash is expensive to check - sig {params(prop_name: Symbol, rules: Rules).void.checked(:never)} - private def validate_not_missing_sensitivity(prop_name, rules) - if rules[:sensitivity].nil? - if rules[:redaction] - T::Configuration.hard_assert_handler( - "#{@class}##{prop_name} has a 'redaction:' annotation but no " \ - "'sensitivity:' annotation. This is probably wrong, because if a " \ - "prop needs redaction then it is probably sensitive. Add a " \ - "sensitivity annotation like 'sensitivity: Opus::Sensitivity::PII." \ - "whatever', or explicitly override this check with 'sensitivity: []'." - ) - end - # TODO(PRIVACYENG-982) Ideally we'd also check for 'password' and possibly - # other terms, but this interacts badly with ProtoDefinedDocument because - # the proto syntax currently can't declare "sensitivity: []" - if /\bsecret\b/.match?(prop_name) - T::Configuration.hard_assert_handler( - "#{@class}##{prop_name} has the word 'secret' in its name, but no " \ - "'sensitivity:' annotation. This is probably wrong, because if a " \ - "prop is named 'secret' then it is probably sensitive. Add a " \ - "sensitivity annotation like 'sensitivity: Opus::Sensitivity::NonPII." \ - "security_token', or explicitly override this check with " \ - "'sensitivity: []'." - ) - end - end - end - - # Create `#{prop_name}_redacted` method - sig do - params( - prop_name: Symbol, - redaction: T.untyped, - ) - .void - end - private def handle_redaction_option(prop_name, redaction) - redacted_method = "#{prop_name}_redacted" - - @class.send(:define_method, redacted_method) do - value = self.public_send(prop_name) - handler = T::Configuration.redaction_handler - if !handler - raise "Using `redaction:` on a prop requires specifying `T::Configuration.redaction_handler`" - end - handler.call(value, redaction) - end - end - - sig do - params( - option_sym: Symbol, - foreign: T.untyped, - valid_type_msg: String, - ) - .void - end - private def validate_foreign_option(option_sym, foreign, valid_type_msg:) - if foreign.is_a?(Symbol) || foreign.is_a?(String) - raise ArgumentError.new( - "Using a symbol/string for `#{option_sym}` is no longer supported. Instead, use a Proc " \ - "that returns the class, e.g., foreign: -> {Foo}" - ) - end - - if !foreign.is_a?(Proc) && !foreign.is_a?(Array) && !foreign.respond_to?(:load) - raise ArgumentError.new("The `#{option_sym}` option must be #{valid_type_msg}") - end - end - - # checked(:never) - Rules hash is expensive to check - sig do - params( - prop_name: T.any(String, Symbol), - rules: Rules, - foreign: T.untyped, - ) - .void - .checked(:never) - end - private def define_foreign_method(prop_name, rules, foreign) - fk_method = "#{prop_name}_" - - # n.b. there's no clear reason *not* to allow additional options - # here, but we're baking in `allow_direct_mutation` since we - # *haven't* allowed additional options in the past and want to - # default to keeping this interface narrow. - @class.send(:define_method, fk_method) do |allow_direct_mutation: nil| - foreign = T.let(foreign, T.untyped) - if foreign.is_a?(Proc) - resolved_foreign = foreign.call - if !resolved_foreign.respond_to?(:load) - raise ArgumentError.new( - "The `foreign` proc for `#{prop_name}` must return a model class. " \ - "Got `#{resolved_foreign.inspect}` instead." - ) - end - # `foreign` is part of the closure state, so this will persist to future invocations - # of the method, optimizing it so this only runs on the first invocation. - foreign = resolved_foreign - end - opts = if allow_direct_mutation.nil? - {} - else - {allow_direct_mutation: allow_direct_mutation} - end - - T.unsafe(self.class).decorator.foreign_prop_get(self, prop_name, foreign, rules, opts) - end - - force_fk_method = "#{fk_method}!" - @class.send(:define_method, force_fk_method) do |allow_direct_mutation: nil| - loaded_foreign = send(fk_method, allow_direct_mutation: allow_direct_mutation) - if !loaded_foreign - T::Configuration.hard_assert_handler( - 'Failed to load foreign model', - storytime: {method: force_fk_method, class: self.class} - ) - end - loaded_foreign - end - end - - # checked(:never) - Rules hash is expensive to check - sig do - params( - prop_name: Symbol, - prop_cls: Module, - rules: Rules, - foreign: T.untyped, - ) - .void - .checked(:never) - end - private def handle_foreign_option(prop_name, prop_cls, rules, foreign) - validate_foreign_option( - :foreign, foreign, valid_type_msg: "a model class or a Proc that returns one" - ) - - if prop_cls != String - raise ArgumentError.new("`foreign` can only be used with a prop type of String") - end - - if foreign.is_a?(Array) - # We don't support arrays with `foreign` because it's hard to both preserve ordering and - # keep them from being lurky performance hits by issuing a bunch of un-batched DB queries. - # We could potentially address that by porting over something like AmbiguousIDLoader. - raise ArgumentError.new( - "Using an array for `foreign` is no longer supported. Instead, please use a union type of " \ - "token types for the prop type, e.g., T.any(Opus::Autogen::Tokens::FooModelToken, Opus::Autogen::Tokens::BarModelToken)" - ) - end - - unless foreign.is_a?(Proc) - T::Configuration.soft_assert_handler(<<~MESSAGE, storytime: {prop: prop_name, value: foreign}, notify: 'jerry') - Please use a Proc that returns a model class instead of the model class itself as the argument to `foreign`. In other words: - - instead of `prop :foo, String, foreign: FooModel` - use `prop :foo, String, foreign: -> {FooModel}` - - MESSAGE - end - - define_foreign_method(prop_name, rules, foreign) - end - - # TODO: rename this to props_inherited - # - # This gets called when a module or class that extends T::Props gets included, extended, - # prepended, or inherited. - sig {params(child: Module).void.checked(:never)} - def model_inherited(child) - child.extend(T::Props::ClassMethods) - child = T.cast(child, T.all(Module, T::Props::ClassMethods)) - - child.plugins.concat(decorated_class.plugins) - decorated_class.plugins.each do |mod| - # NB: apply_class_methods must not be an instance method on the decorator itself, - # otherwise we'd have to call child.decorator here, which would create the decorator - # before any `decorator_class` override has a chance to take effect (see the comment below). - T::Props::Plugin::Private.apply_class_methods(mod, child) - end - - props.each do |name, rules| - copied_rules = rules.dup - # NB: Calling `child.decorator` here is a timb bomb that's going to give someone a really bad - # time. Any class that defines props and also overrides the `decorator_class` method is going - # to reach this line before its override take effect, turning it into a no-op. - child.decorator.add_prop_definition(name, copied_rules) - - # It's a bit tricky to support `prop_get` hooks added by plugins without - # sacrificing the `attr_reader` fast path or clobbering customized getters - # defined manually on a child. - # - # To make this work, we _do_ clobber getters defined on the child, but only if: - # (a) it's needed in order to support a `prop_get` hook, and - # (b) it's safe because the getter was defined by this file. - # - unless rules[:without_accessors] - if clobber_getter?(child, name) - child.send(:define_method, name) do - T.unsafe(self.class).decorator.prop_get(self, name, rules) - end - end - - if !rules[:immutable] && clobber_setter?(child, name) - child.send(:define_method, "#{name}=") do |val| - T.unsafe(self.class).decorator.prop_set(self, name, val, rules) - end - end - end - end - end - - sig {params(child: T.all(Module, T::Props::ClassMethods), prop: Symbol).returns(T::Boolean).checked(:never)} - private def clobber_getter?(child, prop) - !!(child.decorator.method(:prop_get).owner != method(:prop_get).owner && - child.instance_method(prop).source_location&.first == __FILE__) - end - - sig {params(child: T.all(Module, T::Props::ClassMethods), prop: Symbol).returns(T::Boolean).checked(:never)} - private def clobber_setter?(child, prop) - !!(child.decorator.method(:prop_set).owner != method(:prop_set).owner && - child.instance_method("#{prop}=").source_location&.first == __FILE__) - end - - sig {params(mod: Module).void.checked(:never)} - def plugin(mod) - decorated_class.plugins << mod - T::Props::Plugin::Private.apply_class_methods(mod, decorated_class) - T::Props::Plugin::Private.apply_decorator_methods(mod, self) - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/errors.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/errors.rb deleted file mode 100644 index 6977f20471..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/errors.rb +++ /dev/null @@ -1,8 +0,0 @@ -# frozen_string_literal: true -# typed: strict - -module T::Props - class Error < StandardError; end - class InvalidValueError < Error; end - class ImmutableProp < Error; end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/generated_code_validation.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/generated_code_validation.rb deleted file mode 100644 index 91f256799d..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/generated_code_validation.rb +++ /dev/null @@ -1,277 +0,0 @@ -# frozen_string_literal: true -# typed: true - -module T::Props - # Helper to validate generated code, to mitigate security concerns around - # `class_eval`. Not called by default; the expectation is this will be used - # in a test iterating over all T::Props::Serializable subclasses. - # - # We validate the exact expected structure of the generated methods as far - # as we can, and then where cloning produces an arbitrarily nested structure, - # we just validate a lack of side effects. - module GeneratedCodeValidation - extend Private::Parse - - class ValidationError < RuntimeError; end - - def self.validate_deserialize(source) - parsed = parse(source) - - # def %(hash) - # ... - # end - assert_equal(:def, parsed.type) - name, args, body = parsed.children - assert_equal(:__t_props_generated_deserialize, name) - assert_equal(s(:args, s(:arg, :hash)), args) - - assert_equal(:begin, body.type) - init, *prop_clauses, ret = body.children - - # found = % - # ... - # found - assert_equal(:lvasgn, init.type) - init_name, init_val = init.children - assert_equal(:found, init_name) - assert_equal(:int, init_val.type) - assert_equal(s(:lvar, :found), ret) - - prop_clauses.each_with_index do |clause, i| - if i.even? - validate_deserialize_hash_read(clause) - else - validate_deserialize_ivar_set(clause) - end - end - end - - def self.validate_serialize(source) - parsed = parse(source) - - # def %(strict) - # ... - # end - assert_equal(:def, parsed.type) - name, args, body = parsed.children - assert_equal(:__t_props_generated_serialize, name) - assert_equal(s(:args, s(:arg, :strict)), args) - - assert_equal(:begin, body.type) - init, *prop_clauses, ret = body.children - - # h = {} - # ... - # h - assert_equal(s(:lvasgn, :h, s(:hash)), init) - assert_equal(s(:lvar, :h), ret) - - prop_clauses.each do |clause| - validate_serialize_clause(clause) - end - end - - private_class_method def self.validate_serialize_clause(clause) - assert_equal(:if, clause.type) - condition, if_body, else_body = clause.children - - # if @%.nil? - assert_equal(:send, condition.type) - receiver, method = condition.children - assert_equal(:ivar, receiver.type) - assert_equal(:nil?, method) - - unless if_body.nil? - # required_prop_missing_from_serialize(%) if strict - assert_equal(:if, if_body.type) - if_strict_condition, if_strict_body, if_strict_else = if_body.children - assert_equal(s(:lvar, :strict), if_strict_condition) - assert_equal(:send, if_strict_body.type) - on_strict_receiver, on_strict_method, on_strict_arg = if_strict_body.children - assert_equal(nil, on_strict_receiver) - assert_equal(:required_prop_missing_from_serialize, on_strict_method) - assert_equal(:sym, on_strict_arg.type) - assert_equal(nil, if_strict_else) - end - - # h[%] = ... - assert_equal(:send, else_body.type) - receiver, method, h_key, h_val = else_body.children - assert_equal(s(:lvar, :h), receiver) - assert_equal(:[]=, method) - assert_equal(:str, h_key.type) - - validate_lack_of_side_effects(h_val, whitelisted_methods_for_serialize) - end - - private_class_method def self.validate_deserialize_hash_read(clause) - # val = hash[%s] - - assert_equal(:lvasgn, clause.type) - name, val = clause.children - assert_equal(:val, name) - assert_equal(:send, val.type) - receiver, method, arg = val.children - assert_equal(s(:lvar, :hash), receiver) - assert_equal(:[], method) - assert_equal(:str, arg.type) - end - - private_class_method def self.validate_deserialize_ivar_set(clause) - # %s = if val.nil? - # found -= 1 unless hash.key?(%s) - # %s - # else - # %s - # end - - assert_equal(:ivasgn, clause.type) - ivar_name, deser_val = clause.children - unless ivar_name.is_a?(Symbol) - raise ValidationError.new("Unexpected ivar: #{ivar_name}") - end - - assert_equal(:if, deser_val.type) - condition, if_body, else_body = deser_val.children - assert_equal(s(:send, s(:lvar, :val), :nil?), condition) - - assert_equal(:begin, if_body.type) - update_found, handle_nil = if_body.children - assert_equal(:if, update_found.type) - found_condition, found_if_body, found_else_body = update_found.children - assert_equal(:send, found_condition.type) - receiver, method, arg = found_condition.children - assert_equal(s(:lvar, :hash), receiver) - assert_equal(:key?, method) - assert_equal(:str, arg.type) - assert_equal(nil, found_if_body) - assert_equal(s(:op_asgn, s(:lvasgn, :found), :-, s(:int, 1)), found_else_body) - - validate_deserialize_handle_nil(handle_nil) - - if else_body.type == :kwbegin - rescue_expression, = else_body.children - assert_equal(:rescue, rescue_expression.type) - - try, rescue_body = rescue_expression.children - validate_lack_of_side_effects(try, whitelisted_methods_for_deserialize) - - assert_equal(:resbody, rescue_body.type) - exceptions, assignment, handler = rescue_body.children - assert_equal(:array, exceptions.type) - exceptions.children.each {|c| assert_equal(:const, c.type)} - assert_equal(:lvasgn, assignment.type) - assert_equal([:e], assignment.children) - - deserialization_error, val_return = handler.children - - assert_equal(:send, deserialization_error.type) - receiver, method, *args = deserialization_error.children - assert_equal(nil, receiver) - assert_equal(:raise_deserialization_error, method) - args.each {|a| validate_lack_of_side_effects(a, whitelisted_methods_for_deserialize)} - - validate_lack_of_side_effects(val_return, whitelisted_methods_for_deserialize) - else - validate_lack_of_side_effects(else_body, whitelisted_methods_for_deserialize) - end - end - - private_class_method def self.validate_deserialize_handle_nil(node) - case node.type - when :hash, :array, :str, :sym, :int, :float, :true, :false, :nil, :const # rubocop:disable Lint/BooleanSymbol - # Primitives and constants are safe - when :send - receiver, method, arg = node.children - if receiver.nil? - # required_prop_missing_from_deserialize(%) - assert_equal(:required_prop_missing_from_deserialize, method) - assert_equal(:sym, arg.type) - elsif receiver == self_class_decorator - # self.class.decorator.raise_nil_deserialize_error(%) - assert_equal(:raise_nil_deserialize_error, method) - assert_equal(:str, arg.type) - elsif method == :default - # self.class.decorator.props_with_defaults.fetch(%).default - assert_equal(:send, receiver.type) - inner_receiver, inner_method, inner_arg = receiver.children - assert_equal( - s(:send, self_class_decorator, :props_with_defaults), - inner_receiver, - ) - assert_equal(:fetch, inner_method) - assert_equal(:sym, inner_arg.type) - else - raise ValidationError.new("Unexpected receiver in nil handler: #{node.inspect}") - end - else - raise ValidationError.new("Unexpected nil handler: #{node.inspect}") - end - end - - private_class_method def self.self_class_decorator - @self_class_decorator ||= s(:send, s(:send, s(:self), :class), :decorator).freeze - end - - private_class_method def self.validate_lack_of_side_effects(node, whitelisted_methods_by_receiver_type) - case node.type - when :const - # This is ok, because we'll have validated what method has been called - # if applicable - when :hash, :array, :str, :sym, :int, :float, :true, :false, :nil, :self # rubocop:disable Lint/BooleanSymbol - # Primitives & self are ok - when :lvar, :arg, :ivar - # Reading local & instance variables & arguments is ok - unless node.children.all? {|c| c.is_a?(Symbol)} - raise ValidationError.new("Unexpected child for #{node.type}: #{node.inspect}") - end - when :args, :mlhs, :block, :begin, :if - # Blocks etc are read-only if their contents are read-only - node.children.each {|c| validate_lack_of_side_effects(c, whitelisted_methods_by_receiver_type) if c} - when :send - # Sends are riskier so check a whitelist - receiver, method, *args = node.children - if receiver - if receiver.type == :send - key = receiver - else - key = receiver.type - validate_lack_of_side_effects(receiver, whitelisted_methods_by_receiver_type) - end - - if !whitelisted_methods_by_receiver_type[key]&.include?(method) - raise ValidationError.new("Unexpected method #{method} called on #{receiver.inspect}") - end - end - args.each do |arg| - validate_lack_of_side_effects(arg, whitelisted_methods_by_receiver_type) - end - else - raise ValidationError.new("Unexpected node type #{node.type}: #{node.inspect}") - end - end - - private_class_method def self.assert_equal(expected, actual) - if expected != actual - raise ValidationError.new("Expected #{expected}, got #{actual}") - end - end - - # Method calls generated by SerdeTransform - private_class_method def self.whitelisted_methods_for_serialize - @whitelisted_methods_for_serialize ||= { - lvar: %i{dup map transform_values transform_keys each_with_object nil? []= serialize}, - ivar: %i[dup map transform_values transform_keys each_with_object serialize], - const: %i[checked_serialize deep_clone_object], - } - end - - # Method calls generated by SerdeTransform - private_class_method def self.whitelisted_methods_for_deserialize - @whitelisted_methods_for_deserialize ||= { - lvar: %i{dup map transform_values transform_keys each_with_object nil? []= to_f}, - const: %i[deserialize from_hash deep_clone_object], - } - end - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/has_lazily_specialized_methods.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/has_lazily_specialized_methods.rb deleted file mode 100644 index 5c1acecb69..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/has_lazily_specialized_methods.rb +++ /dev/null @@ -1,140 +0,0 @@ -# frozen_string_literal: true -# typed: false - -module T::Props - - # Helper for generating methods that replace themselves with a specialized - # version on first use. The main use case is when we want to generate a - # method using the full set of props on a class; we can't do that during - # prop definition because we have no way of knowing whether we are defining - # the last prop. - # - # See go/M8yrvzX2 (Stripe-internal) for discussion of security considerations. - # In outline, while `class_eval` is a bit scary, we believe that as long as - # all inputs are defined in version control (and this is enforced by calling - # `disable_lazy_evaluation!` appropriately), risk isn't significantly higher - # than with build-time codegen. - module HasLazilySpecializedMethods - extend T::Sig - - class SourceEvaluationDisabled < RuntimeError - def initialize - super("Evaluation of lazily-defined methods is disabled") - end - end - - # Disable any future evaluation of lazily-defined methods. - # - # This is intended to be called after startup but before interacting with - # the outside world, to limit attack surface for our `class_eval` use. - # - # Note it does _not_ prevent explicit calls to `eagerly_define_lazy_methods!` - # from working. - sig {void} - def self.disable_lazy_evaluation! - @lazy_evaluation_disabled ||= true - end - - sig {returns(T::Boolean)} - def self.lazy_evaluation_enabled? - !defined?(@lazy_evaluation_disabled) || !@lazy_evaluation_disabled - end - - module DecoratorMethods - extend T::Sig - - sig {returns(T::Hash[Symbol, T.proc.returns(String)]).checked(:never)} - private def lazily_defined_methods - @lazily_defined_methods ||= {} - end - - sig {returns(T::Hash[Symbol, T.untyped]).checked(:never)} - private def lazily_defined_vm_methods - @lazily_defined_vm_methods ||= {} - end - - sig {params(name: Symbol).void} - private def eval_lazily_defined_method!(name) - if !HasLazilySpecializedMethods.lazy_evaluation_enabled? - raise SourceEvaluationDisabled.new - end - - source = lazily_defined_methods.fetch(name).call - - cls = decorated_class - cls.class_eval(source.to_s) - cls.send(:private, name) - end - - sig {params(name: Symbol).void} - private def eval_lazily_defined_vm_method!(name) - if !HasLazilySpecializedMethods.lazy_evaluation_enabled? - raise SourceEvaluationDisabled.new - end - - lazily_defined_vm_methods.fetch(name).call - - cls = decorated_class - cls.send(:private, name) - end - - sig {params(name: Symbol, blk: T.proc.returns(String)).void} - private def enqueue_lazy_method_definition!(name, &blk) - lazily_defined_methods[name] = blk - - cls = decorated_class - if cls.method_defined?(name) - # Ruby does not emit "method redefined" warnings for aliased methods - # (more robust than undef_method that would create a small window in which the method doesn't exist) - cls.send(:alias_method, name, name) - end - cls.send(:define_method, name) do |*args| - self.class.decorator.send(:eval_lazily_defined_method!, name) - send(name, *args) - end - if cls.respond_to?(:ruby2_keywords, true) - cls.send(:ruby2_keywords, name) - end - cls.send(:private, name) - end - - sig {params(name: Symbol, blk: T.untyped).void} - private def enqueue_lazy_vm_method_definition!(name, &blk) - lazily_defined_vm_methods[name] = blk - - cls = decorated_class - cls.send(:define_method, name) do |*args| - self.class.decorator.send(:eval_lazily_defined_vm_method!, name) - send(name, *args) - end - if cls.respond_to?(:ruby2_keywords, true) - cls.send(:ruby2_keywords, name) - end - cls.send(:private, name) - end - - sig {void} - def eagerly_define_lazy_methods! - return if lazily_defined_methods.empty? - - source = lazily_defined_methods.values.map(&:call).map(&:to_s).join("\n\n") - - cls = decorated_class - cls.class_eval(source) - lazily_defined_methods.each_key {|name| cls.send(:private, name)} - lazily_defined_methods.clear - end - - sig {void} - def eagerly_define_lazy_vm_methods! - return if lazily_defined_vm_methods.empty? - - lazily_defined_vm_methods.values.map(&:call) - - cls = decorated_class - lazily_defined_vm_methods.each_key {|name| cls.send(:private, name)} - lazily_defined_vm_methods.clear - end - end - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/optional.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/optional.rb deleted file mode 100644 index 4f482beac3..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/optional.rb +++ /dev/null @@ -1,89 +0,0 @@ -# frozen_string_literal: true -# typed: false - -module T::Props::Optional - include T::Props::Plugin -end - -############################################## - -# NB: This must stay in the same file where T::Props::Optional is defined due to -# T::Props::Decorator#apply_plugin; see https://git.corp.stripe.com/stripe-internal/pay-server/blob/fc7f15593b49875f2d0499ffecfd19798bac05b3/chalk/odm/lib/chalk-odm/document_decorator.rb#L716-L717 -module T::Props::Optional::DecoratorMethods - extend T::Sig - - # Heads up! - # - # There are already too many ad-hoc options on the prop DSL. - # - # We have already done a lot of work to remove unnecessary and confusing - # options. If you're considering adding a new rule key, please come chat with - # the Sorbet team first, as we'd really like to learn more about how to best - # solve the problem you're encountering. - VALID_RULE_KEYS = { - default: true, - factory: true, - }.freeze - private_constant :VALID_RULE_KEYS - - DEFAULT_SETTER_RULE_KEY = :_t_props_private_apply_default - private_constant :DEFAULT_SETTER_RULE_KEY - - def valid_rule_key?(key) - super || VALID_RULE_KEYS[key] - end - - def prop_optional?(prop) - prop_rules(prop)[:fully_optional] - end - - def compute_derived_rules(rules) - rules[:fully_optional] = !T::Props::Utils.need_nil_write_check?(rules) - rules[:need_nil_read_check] = T::Props::Utils.need_nil_read_check?(rules) - end - - # checked(:never) - O(runtime object construction) - sig {returns(T::Hash[Symbol, T::Props::Private::ApplyDefault]).checked(:never)} - attr_reader :props_with_defaults - - # checked(:never) - O(runtime object construction) - sig {returns(T::Hash[Symbol, T::Props::Private::SetterFactory::SetterProc]).checked(:never)} - attr_reader :props_without_defaults - - def add_prop_definition(prop, rules) - compute_derived_rules(rules) - - default_setter = T::Props::Private::ApplyDefault.for(decorated_class, rules) - if default_setter - @props_with_defaults ||= {} - @props_with_defaults[prop] = default_setter - props_without_defaults&.delete(prop) # Handle potential override - - rules[DEFAULT_SETTER_RULE_KEY] = default_setter - else - @props_without_defaults ||= {} - @props_without_defaults[prop] = rules.fetch(:setter_proc) - props_with_defaults&.delete(prop) # Handle potential override - end - - super - end - - def prop_validate_definition!(name, cls, rules, type) - result = super - - if rules.key?(:default) && rules.key?(:factory) - raise ArgumentError.new("Setting both :default and :factory is invalid. See: go/chalk-docs") - end - - result - end - - def has_default?(rules) - rules.include?(DEFAULT_SETTER_RULE_KEY) - end - - def get_default(rules, instance_class) - rules[DEFAULT_SETTER_RULE_KEY]&.default - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/plugin.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/plugin.rb deleted file mode 100644 index 1423c172ed..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/plugin.rb +++ /dev/null @@ -1,37 +0,0 @@ -# frozen_string_literal: true -# typed: false - -module T::Props::Plugin - include T::Props - extend T::Helpers - - module ClassMethods - def included(child) - super - child.plugin(self) - end - end - mixes_in_class_methods(ClassMethods) - - module Private - # These need to be non-instance methods so we can use them without prematurely creating the - # child decorator in `model_inherited` (see comments there for details). - # - # The dynamic constant access below forces this file to be `typed: false` - def self.apply_class_methods(plugin, target) - if plugin.const_defined?('ClassMethods') - # FIXME: This will break preloading, selective test execution, etc if `mod::ClassMethods` - # is ever defined in a separate file from `mod`. - target.extend(plugin::ClassMethods) - end - end - - def self.apply_decorator_methods(plugin, target) - if plugin.const_defined?('DecoratorMethods') - # FIXME: This will break preloading, selective test execution, etc if `mod::DecoratorMethods` - # is ever defined in a separate file from `mod`. - target.extend(plugin::DecoratorMethods) - end - end - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/pretty_printable.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/pretty_printable.rb deleted file mode 100644 index e821cd3435..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/pretty_printable.rb +++ /dev/null @@ -1,107 +0,0 @@ -# frozen_string_literal: true -# typed: true - -module T::Props::PrettyPrintable - include T::Props::Plugin - - # Return a string representation of this object and all of its props - def inspect - T.unsafe(T.cast(self, Object).class).decorator.inspect_instance(self) - end - - # Override the PP gem with something that's similar, but gives us a hook - # to do redaction - def pretty_inspect - T.unsafe(T.cast(self, Object).class).decorator.inspect_instance(self, multiline: true) - end - - module DecoratorMethods - extend T::Sig - - sig {params(key: Symbol).returns(T::Boolean).checked(:never)} - def valid_rule_key?(key) - super || key == :inspect - end - - sig do - params(instance: T::Props::PrettyPrintable, multiline: T::Boolean, indent: String) - .returns(String) - end - def inspect_instance(instance, multiline: false, indent: ' ') - components = - inspect_instance_components( - instance, - multiline: multiline, - indent: indent - ) - .reject(&:empty?) - - # Not using #<> here as that makes pry highlight these objects - # as if they were all comments, whereas this makes them look - # like the structured thing they are. - if multiline - "#{components[0]}:\n" + T.must(components[1..-1]).join("\n") - else - "<#{components.join(' ')}>" - end - end - - sig do - params(instance: T::Props::PrettyPrintable, multiline: T::Boolean, indent: String) - .returns(T::Array[String]) - end - private def inspect_instance_components(instance, multiline:, indent:) - pretty_props = T.unsafe(self).all_props.map do |prop| - [prop, inspect_prop_value(instance, prop, multiline: multiline, indent: indent)] - end - - joined_props = join_props_with_pretty_values( - pretty_props, - multiline: multiline, - indent: indent - ) - - [ - T.unsafe(self).decorated_class.to_s, - joined_props, - ] - end - - sig do - params(instance: T::Props::PrettyPrintable, prop: Symbol, multiline: T::Boolean, indent: String) - .returns(String) - .checked(:never) - end - private def inspect_prop_value(instance, prop, multiline:, indent:) - val = T.unsafe(self).get(instance, prop) - rules = T.unsafe(self).prop_rules(prop) - if (custom_inspect = rules[:inspect]) - if T::Utils.arity(custom_inspect) == 1 - custom_inspect.call(val) - else - custom_inspect.call(val, {multiline: multiline, indent: indent}) - end - elsif rules[:sensitivity] && !rules[:sensitivity].empty? && !val.nil? - "" - else - val.inspect - end - end - - sig do - params(pretty_kvs: T::Array[[Symbol, String]], multiline: T::Boolean, indent: String) - .returns(String) - end - private def join_props_with_pretty_values(pretty_kvs, multiline:, indent: ' ') - pairs = pretty_kvs - .sort_by {|k, _v| k.to_s} - .map {|k, v| "#{k}=#{v}"} - - if multiline - indent + pairs.join("\n#{indent}") - else - pairs.join(', ') - end - end - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/private/apply_default.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/private/apply_default.rb deleted file mode 100644 index b86f506f9a..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/private/apply_default.rb +++ /dev/null @@ -1,170 +0,0 @@ -# frozen_string_literal: true -# typed: strict - -module T::Props - module Private - class ApplyDefault - extend T::Sig - extend T::Helpers - abstract! - - # checked(:never) - O(object construction x prop count) - sig {returns(SetterFactory::SetterProc).checked(:never)} - attr_reader :setter_proc - - # checked(:never) - We do this with `T.let` instead - sig {params(accessor_key: Symbol, setter_proc: SetterFactory::SetterProc).void.checked(:never)} - def initialize(accessor_key, setter_proc) - @accessor_key = T.let(accessor_key, Symbol) - @setter_proc = T.let(setter_proc, SetterFactory::SetterProc) - end - - # checked(:never) - O(object construction x prop count) - sig {abstract.returns(T.untyped).checked(:never)} - def default; end - - # checked(:never) - O(object construction x prop count) - sig {abstract.params(instance: T.all(T::Props::Optional, Object)).void.checked(:never)} - def set_default(instance); end - - NO_CLONE_TYPES = T.let([TrueClass, FalseClass, NilClass, Symbol, Numeric, T::Enum].freeze, T::Array[Module]) - - # checked(:never) - Rules hash is expensive to check - sig {params(cls: Module, rules: T::Hash[Symbol, T.untyped]).returns(T.nilable(ApplyDefault)).checked(:never)} - def self.for(cls, rules) - accessor_key = rules.fetch(:accessor_key) - setter = rules.fetch(:setter_proc) - - if rules.key?(:factory) - ApplyDefaultFactory.new(cls, rules.fetch(:factory), accessor_key, setter) - elsif rules.key?(:default) - default = rules.fetch(:default) - case default - when *NO_CLONE_TYPES - return ApplyPrimitiveDefault.new(default, accessor_key, setter) - when String - if default.frozen? - return ApplyPrimitiveDefault.new(default, accessor_key, setter) - end - when Array - if default.empty? && default.class == Array - return ApplyEmptyArrayDefault.new(accessor_key, setter) - end - when Hash - if default.empty? && default.default.nil? && T.unsafe(default).default_proc.nil? && default.class == Hash - return ApplyEmptyHashDefault.new(accessor_key, setter) - end - end - - ApplyComplexDefault.new(default, accessor_key, setter) - else - nil - end - end - end - - class ApplyFixedDefault < ApplyDefault - abstract! - - # checked(:never) - We do this with `T.let` instead - sig {params(default: BasicObject, accessor_key: Symbol, setter_proc: SetterFactory::SetterProc).void.checked(:never)} - def initialize(default, accessor_key, setter_proc) - # FIXME: Ideally we'd check here that the default is actually a valid - # value for this field, but existing code relies on the fact that we don't. - # - # :( - # - # setter_proc.call(default) - @default = T.let(default, BasicObject) - super(accessor_key, setter_proc) - end - - # checked(:never) - O(object construction x prop count) - sig {override.params(instance: T.all(T::Props::Optional, Object)).void.checked(:never)} - def set_default(instance) - instance.instance_variable_set(@accessor_key, default) - end - end - - class ApplyPrimitiveDefault < ApplyFixedDefault - # checked(:never) - O(object construction x prop count) - sig {override.returns(T.untyped).checked(:never)} - attr_reader :default - end - - class ApplyComplexDefault < ApplyFixedDefault - # checked(:never) - O(object construction x prop count) - sig {override.returns(T.untyped).checked(:never)} - def default - T::Props::Utils.deep_clone_object(@default) - end - end - - # Special case since it's so common, and a literal `[]` is meaningfully - # faster than falling back to ApplyComplexDefault or even calling - # `some_empty_array.dup` - class ApplyEmptyArrayDefault < ApplyDefault - # checked(:never) - O(object construction x prop count) - sig {override.params(instance: T.all(T::Props::Optional, Object)).void.checked(:never)} - def set_default(instance) - instance.instance_variable_set(@accessor_key, []) - end - - # checked(:never) - O(object construction x prop count) - sig {override.returns(T::Array[T.untyped]).checked(:never)} - def default - [] - end - end - - # Special case since it's so common, and a literal `{}` is meaningfully - # faster than falling back to ApplyComplexDefault or even calling - # `some_empty_hash.dup` - class ApplyEmptyHashDefault < ApplyDefault - # checked(:never) - O(object construction x prop count) - sig {override.params(instance: T.all(T::Props::Optional, Object)).void.checked(:never)} - def set_default(instance) - instance.instance_variable_set(@accessor_key, {}) - end - - # checked(:never) - O(object construction x prop count) - sig {override.returns(T::Hash[T.untyped, T.untyped]).checked(:never)} - def default - {} - end - end - - class ApplyDefaultFactory < ApplyDefault - # checked(:never) - We do this with `T.let` instead - sig do - params( - cls: Module, - factory: T.any(Proc, Method), - accessor_key: Symbol, - setter_proc: SetterFactory::SetterProc, - ) - .void - .checked(:never) - end - def initialize(cls, factory, accessor_key, setter_proc) - @class = T.let(cls, Module) - @factory = T.let(factory, T.any(Proc, Method)) - super(accessor_key, setter_proc) - end - - # checked(:never) - O(object construction x prop count) - sig {override.params(instance: T.all(T::Props::Optional, Object)).void.checked(:never)} - def set_default(instance) - # Use the actual setter to validate the factory returns a legitimate - # value every time - instance.instance_exec(default, &@setter_proc) - end - - # checked(:never) - O(object construction x prop count) - sig {override.returns(T.untyped).checked(:never)} - def default - @class.class_exec(&@factory) - end - end - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/private/deserializer_generator.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/private/deserializer_generator.rb deleted file mode 100644 index 2393e1a284..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/private/deserializer_generator.rb +++ /dev/null @@ -1,160 +0,0 @@ -# frozen_string_literal: true -# typed: strict - -module T::Props - module Private - - # Generates a specialized `deserialize` implementation for a subclass of - # T::Props::Serializable. - # - # The basic idea is that we analyze the props and for each prop, generate - # the simplest possible logic as a block of Ruby source, so that we don't - # pay the cost of supporting types like T:::Hash[CustomType, SubstructType] - # when deserializing a simple Integer. Then we join those together, - # with a little shared logic to be able to detect when we get input keys - # that don't match any prop. - module DeserializerGenerator - extend T::Sig - - # Generate a method that takes a T::Hash[String, T.untyped] representing - # serialized props, sets instance variables for each prop found in the - # input, and returns the count of we props set (which we can use to check - # for unexpected input keys with minimal effect on the fast path). - sig do - params( - props: T::Hash[Symbol, T::Hash[Symbol, T.untyped]], - defaults: T::Hash[Symbol, T::Props::Private::ApplyDefault], - ) - .returns(String) - .checked(:never) - end - def self.generate(props, defaults) - stored_props = props.reject {|_, rules| rules[:dont_store]} - parts = stored_props.map do |prop, rules| - # All of these strings should already be validated (directly or - # indirectly) in `validate_prop_name`, so we don't bother with a nice - # error message, but we double check here to prevent a refactoring - # from introducing a security vulnerability. - raise unless T::Props::Decorator::SAFE_NAME.match?(prop.to_s) - - hash_key = rules.fetch(:serialized_form) - raise unless T::Props::Decorator::SAFE_NAME.match?(hash_key) - - ivar_name = rules.fetch(:accessor_key).to_s - raise unless ivar_name.start_with?('@') && T::Props::Decorator::SAFE_NAME.match?(ivar_name[1..-1]) - - transformation = SerdeTransform.generate( - T::Utils::Nilable.get_underlying_type_object(rules.fetch(:type_object)), - SerdeTransform::Mode::DESERIALIZE, - 'val' - ) - transformed_val = if transformation - # Rescuing exactly NoMethodError is intended as a temporary hack - # to preserve the semantics from before codegen. More generally - # we are inconsistent about typechecking on deser and need to decide - # our strategy here. - <<~RUBY - begin - #{transformation} - rescue NoMethodError => e - raise_deserialization_error( - #{prop.inspect}, - val, - e, - ) - val - end - RUBY - else - 'val' - end - - nil_handler = generate_nil_handler( - prop: prop, - serialized_form: hash_key, - default: defaults[prop], - nilable_type: T::Props::Utils.optional_prop?(rules), - raise_on_nil_write: !!rules[:raise_on_nil_write], - ) - - <<~RUBY - val = hash[#{hash_key.inspect}] - #{ivar_name} = if val.nil? - found -= 1 unless hash.key?(#{hash_key.inspect}) - #{nil_handler} - else - #{transformed_val} - end - RUBY - end - - <<~RUBY - def __t_props_generated_deserialize(hash) - found = #{stored_props.size} - #{parts.join("\n\n")} - found - end - RUBY - end - - # This is very similar to what we do in ApplyDefault, but has a few - # key differences that mean we don't just re-use the code: - # - # 1. Where the logic in construction is that we generate a default - # if & only if the prop key isn't present in the input, here we'll - # generate a default even to override an explicit nil, but only - # if the prop is actually required. - # 2. Since we're generating raw Ruby source, we can remove a layer - # of indirection for marginally better performance; this seems worth - # it for the common cases of literals and empty arrays/hashes. - # 3. We need to care about the distinction between `raise_on_nil_write` - # and actually non-nilable, where new-instance construction doesn't. - # - # So we fall back to ApplyDefault only when one of the cases just - # mentioned doesn't apply. - sig do - params( - prop: Symbol, - serialized_form: String, - default: T.nilable(ApplyDefault), - nilable_type: T::Boolean, - raise_on_nil_write: T::Boolean, - ) - .returns(String) - .checked(:never) - end - private_class_method def self.generate_nil_handler( - prop:, - serialized_form:, - default:, - nilable_type:, - raise_on_nil_write: - ) - if !nilable_type - case default - when NilClass - "self.class.decorator.raise_nil_deserialize_error(#{serialized_form.inspect})" - when ApplyPrimitiveDefault - literal = default.default - case literal - when String, Integer, Symbol, Float, TrueClass, FalseClass, NilClass - literal.inspect - else - "self.class.decorator.props_with_defaults.fetch(#{prop.inspect}).default" - end - when ApplyEmptyArrayDefault - '[]' - when ApplyEmptyHashDefault - '{}' - else - "self.class.decorator.props_with_defaults.fetch(#{prop.inspect}).default" - end - elsif raise_on_nil_write - "required_prop_missing_from_deserialize(#{prop.inspect})" - else - 'nil' - end - end - end - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/private/parser.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/private/parser.rb deleted file mode 100644 index 2ccd574118..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/private/parser.rb +++ /dev/null @@ -1,32 +0,0 @@ -# frozen_string_literal: true -# typed: false - -module T::Props - module Private - module Parse - def parse(source) - @current_ruby ||= require_parser(:CurrentRuby) - @current_ruby.parse(source) - end - - def s(type, *children) - @node ||= require_parser(:AST, :Node) - @node.new(type, children) - end - - private def require_parser(*constants) - # This is an optional dependency for sorbet-runtime in general, - # but is required here - require 'parser/current' - - # Hack to work around the static checker thinking the constant is - # undefined - cls = Kernel.const_get(:Parser, true) - while (const = constants.shift) - cls = cls.const_get(const, false) - end - cls - end - end - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/private/serde_transform.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/private/serde_transform.rb deleted file mode 100644 index e0b37a376d..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/private/serde_transform.rb +++ /dev/null @@ -1,186 +0,0 @@ -# frozen_string_literal: true -# typed: strict - -module T::Props - module Private - module SerdeTransform - extend T::Sig - - class Serialize; end - private_constant :Serialize - class Deserialize; end - private_constant :Deserialize - ModeType = T.type_alias {T.any(Serialize, Deserialize)} - private_constant :ModeType - - module Mode - SERIALIZE = T.let(Serialize.new.freeze, Serialize) - DESERIALIZE = T.let(Deserialize.new.freeze, Deserialize) - end - - NO_TRANSFORM_TYPES = T.let( - [TrueClass, FalseClass, NilClass, Symbol, String].freeze, - T::Array[Module], - ) - private_constant :NO_TRANSFORM_TYPES - - sig do - params( - type: T::Types::Base, - mode: ModeType, - varname: String, - ) - .returns(T.nilable(String)) - .checked(:never) - end - def self.generate(type, mode, varname) - case type - when T::Types::TypedArray - inner = generate(type.type, mode, 'v') - if inner.nil? - "#{varname}.dup" - else - "#{varname}.map {|v| #{inner}}" - end - when T::Types::TypedSet - inner = generate(type.type, mode, 'v') - if inner.nil? - "#{varname}.dup" - else - "Set.new(#{varname}) {|v| #{inner}}" - end - when T::Types::TypedHash - keys = generate(type.keys, mode, 'k') - values = generate(type.values, mode, 'v') - if keys && values - "#{varname}.each_with_object({}) {|(k,v),h| h[#{keys}] = #{values}}" - elsif keys - "#{varname}.transform_keys {|k| #{keys}}" - elsif values - "#{varname}.transform_values {|v| #{values}}" - else - "#{varname}.dup" - end - when T::Types::Simple - raw = type.raw_type - if NO_TRANSFORM_TYPES.any? {|cls| raw <= cls} - nil - elsif raw <= Float - case mode - when Deserialize then "#{varname}.to_f" - when Serialize then nil - else T.absurd(mode) - end - elsif raw <= Numeric - nil - elsif raw < T::Props::Serializable - handle_serializable_subtype(varname, raw, mode) - elsif raw.singleton_class < T::Props::CustomType - handle_custom_type(varname, T.unsafe(raw), mode) - elsif T::Configuration.scalar_types.include?(raw.name) - # It's a bit of a hack that this is separate from NO_TRANSFORM_TYPES - # and doesn't check inheritance (like `T::Props::CustomType.scalar_type?` - # does), but it covers the main use case (pay-server's custom `Boolean` - # module) without either requiring `T::Configuration.scalar_types` to - # accept modules instead of strings (which produces load-order issues - # and subtle behavior changes) or eating the performance cost of doing - # an inheritance check by manually crawling a class hierarchy and doing - # string comparisons. - nil - else - "T::Props::Utils.deep_clone_object(#{varname})" - end - when T::Types::Union - non_nil_type = T::Utils.unwrap_nilable(type) - if non_nil_type - inner = generate(non_nil_type, mode, varname) - if inner.nil? - nil - else - "#{varname}.nil? ? nil : #{inner}" - end - elsif type.types.all? {|t| generate(t, mode, varname).nil?} - # Handle, e.g., T::Boolean - nil - else - # We currently deep_clone_object if the type was T.any(Integer, Float). - # When we get better support for union types (maybe this specific - # union type, because it would be a replacement for - # Chalk::ODM::DeprecatedNumemric), we could opt to special case - # this union to have no specific serde transform (the only reason - # why Float has a special case is because round tripping through - # JSON might normalize Floats to Integers) - "T::Props::Utils.deep_clone_object(#{varname})" - end - when T::Types::Intersection - dynamic_fallback = "T::Props::Utils.deep_clone_object(#{varname})" - - # Transformations for any members of the intersection type where we - # know what we need to do and did not have to fall back to the - # dynamic deep clone method. - # - # NB: This deliberately does include `nil`, which means we know we - # don't need to do any transforming. - inner_known = type.types - .map {|t| generate(t, mode, varname)} - .reject {|t| t == dynamic_fallback} - .uniq - - if inner_known.size != 1 - # If there were no cases where we could tell what we need to do, - # e.g. if this is `T.all(SomethingWeird, WhoKnows)`, just use the - # dynamic fallback. - # - # If there were multiple cases and they weren't consistent, e.g. - # if this is `T.all(String, T::Array[Integer])`, the type is probably - # bogus/uninhabited, but use the dynamic fallback because we still - # don't have a better option, and this isn't the place to raise that - # error. - dynamic_fallback - else - # This is probably something like `T.all(String, SomeMarker)` or - # `T.all(SomeEnum, T.deprecated_enum(SomeEnum::FOO))` and we should - # treat it like String or SomeEnum even if we don't know what to do - # with the rest of the type. - inner_known.first - end - when T::Types::Enum - generate(T::Utils.lift_enum(type), mode, varname) - else - "T::Props::Utils.deep_clone_object(#{varname})" - end - end - - sig {params(varname: String, type: Module, mode: ModeType).returns(String).checked(:never)} - private_class_method def self.handle_serializable_subtype(varname, type, mode) - case mode - when Serialize - "#{varname}.serialize(strict)" - when Deserialize - type_name = T.must(module_name(type)) - "#{type_name}.from_hash(#{varname})" - else - T.absurd(mode) - end - end - - sig {params(varname: String, type: Module, mode: ModeType).returns(String).checked(:never)} - private_class_method def self.handle_custom_type(varname, type, mode) - case mode - when Serialize - "T::Props::CustomType.checked_serialize(#{varname})" - when Deserialize - type_name = T.must(module_name(type)) - "#{type_name}.deserialize(#{varname})" - else - T.absurd(mode) - end - end - - sig {params(type: Module).returns(T.nilable(String)).checked(:never)} - private_class_method def self.module_name(type) - T::Configuration.module_name_mangler.call(type) - end - end - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/private/serializer_generator.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/private/serializer_generator.rb deleted file mode 100644 index 0d49a46e0f..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/private/serializer_generator.rb +++ /dev/null @@ -1,76 +0,0 @@ -# frozen_string_literal: true -# typed: strict - -module T::Props - module Private - - # Generates a specialized `serialize` implementation for a subclass of - # T::Props::Serializable. - # - # The basic idea is that we analyze the props and for each prop, generate - # the simplest possible logic as a block of Ruby source, so that we don't - # pay the cost of supporting types like T:::Hash[CustomType, SubstructType] - # when serializing a simple Integer. Then we join those together, - # with a little shared logic to be able to detect when we get input keys - # that don't match any prop. - module SerializerGenerator - extend T::Sig - - sig do - params( - props: T::Hash[Symbol, T::Hash[Symbol, T.untyped]], - ) - .returns(String) - .checked(:never) - end - def self.generate(props) - stored_props = props.reject {|_, rules| rules[:dont_store]} - parts = stored_props.map do |prop, rules| - # All of these strings should already be validated (directly or - # indirectly) in `validate_prop_name`, so we don't bother with a nice - # error message, but we double check here to prevent a refactoring - # from introducing a security vulnerability. - raise unless T::Props::Decorator::SAFE_NAME.match?(prop.to_s) - - hash_key = rules.fetch(:serialized_form) - raise unless T::Props::Decorator::SAFE_NAME.match?(hash_key) - - ivar_name = rules.fetch(:accessor_key).to_s - raise unless ivar_name.start_with?('@') && T::Props::Decorator::SAFE_NAME.match?(ivar_name[1..-1]) - - transformed_val = SerdeTransform.generate( - T::Utils::Nilable.get_underlying_type_object(rules.fetch(:type_object)), - SerdeTransform::Mode::SERIALIZE, - ivar_name - ) || ivar_name - - nil_asserter = - if rules[:fully_optional] - '' - else - "required_prop_missing_from_serialize(#{prop.inspect}) if strict" - end - - # Don't serialize values that are nil to save space (both the - # nil value itself and the field name in the serialized BSON - # document) - <<~RUBY - if #{ivar_name}.nil? - #{nil_asserter} - else - h[#{hash_key.inspect}] = #{transformed_val} - end - RUBY - end - - <<~RUBY - def __t_props_generated_serialize(strict) - h = {} - #{parts.join("\n\n")} - h - end - RUBY - end - end - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/private/setter_factory.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/private/setter_factory.rb deleted file mode 100644 index 00c76ed1e7..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/private/setter_factory.rb +++ /dev/null @@ -1,197 +0,0 @@ -# frozen_string_literal: true -# typed: strict - -module T::Props - module Private - module SetterFactory - extend T::Sig - - SetterProc = T.type_alias {T.proc.params(val: T.untyped).void} - ValidateProc = T.type_alias {T.proc.params(prop: Symbol, value: T.untyped).void} - - sig do - params( - klass: T.all(Module, T::Props::ClassMethods), - prop: Symbol, - rules: T::Hash[Symbol, T.untyped] - ) - .returns(SetterProc) - .checked(:never) - end - def self.build_setter_proc(klass, prop, rules) - # Our nil check works differently than a simple T.nilable for various - # reasons (including the `raise_on_nil_write` setting and the existence - # of defaults & factories), so unwrap any T.nilable and do a check - # manually. - non_nil_type = T::Utils::Nilable.get_underlying_type_object(rules.fetch(:type_object)) - accessor_key = rules.fetch(:accessor_key) - validate = rules[:setter_validate] - - # It seems like a bug that this affects the behavior of setters, but - # some existing code relies on this behavior - has_explicit_nil_default = rules.key?(:default) && rules.fetch(:default).nil? - - # Use separate methods in order to ensure that we only close over necessary - # variables - if !T::Props::Utils.need_nil_write_check?(rules) || has_explicit_nil_default - if validate.nil? && non_nil_type.is_a?(T::Types::Simple) - simple_nilable_proc(prop, accessor_key, non_nil_type.raw_type, klass) - else - nilable_proc(prop, accessor_key, non_nil_type, klass, validate) - end - else - if validate.nil? && non_nil_type.is_a?(T::Types::Simple) - simple_non_nil_proc(prop, accessor_key, non_nil_type.raw_type, klass) - else - non_nil_proc(prop, accessor_key, non_nil_type, klass, validate) - end - end - end - - sig do - params( - prop: Symbol, - accessor_key: Symbol, - non_nil_type: Module, - klass: T.all(Module, T::Props::ClassMethods), - ) - .returns(SetterProc) - end - private_class_method def self.simple_non_nil_proc(prop, accessor_key, non_nil_type, klass) - proc do |val| - unless val.is_a?(non_nil_type) - T::Props::Private::SetterFactory.raise_pretty_error( - klass, - prop, - T::Utils.coerce(non_nil_type), - val, - ) - end - instance_variable_set(accessor_key, val) - end - end - - sig do - params( - prop: Symbol, - accessor_key: Symbol, - non_nil_type: T::Types::Base, - klass: T.all(Module, T::Props::ClassMethods), - validate: T.nilable(ValidateProc) - ) - .returns(SetterProc) - end - private_class_method def self.non_nil_proc(prop, accessor_key, non_nil_type, klass, validate) - proc do |val| - # this use of recursively_valid? is intentional: unlike for - # methods, we want to make sure data at the 'edge' - # (e.g. models that go into databases or structs serialized - # from disk) are correct, so we use more thorough runtime - # checks there - if non_nil_type.recursively_valid?(val) - validate&.call(prop, val) - else - T::Props::Private::SetterFactory.raise_pretty_error( - klass, - prop, - non_nil_type, - val, - ) - end - instance_variable_set(accessor_key, val) - end - end - - sig do - params( - prop: Symbol, - accessor_key: Symbol, - non_nil_type: Module, - klass: T.all(Module, T::Props::ClassMethods), - ) - .returns(SetterProc) - end - private_class_method def self.simple_nilable_proc(prop, accessor_key, non_nil_type, klass) - proc do |val| - if val.nil? - instance_variable_set(accessor_key, nil) - elsif val.is_a?(non_nil_type) - instance_variable_set(accessor_key, val) - else - T::Props::Private::SetterFactory.raise_pretty_error( - klass, - prop, - T::Utils.coerce(non_nil_type), - val, - ) - instance_variable_set(accessor_key, val) - end - end - end - - sig do - params( - prop: Symbol, - accessor_key: Symbol, - non_nil_type: T::Types::Base, - klass: T.all(Module, T::Props::ClassMethods), - validate: T.nilable(ValidateProc), - ) - .returns(SetterProc) - end - private_class_method def self.nilable_proc(prop, accessor_key, non_nil_type, klass, validate) - proc do |val| - if val.nil? - instance_variable_set(accessor_key, nil) - # this use of recursively_valid? is intentional: unlike for - # methods, we want to make sure data at the 'edge' - # (e.g. models that go into databases or structs serialized - # from disk) are correct, so we use more thorough runtime - # checks there - elsif non_nil_type.recursively_valid?(val) - validate&.call(prop, val) - instance_variable_set(accessor_key, val) - else - T::Props::Private::SetterFactory.raise_pretty_error( - klass, - prop, - non_nil_type, - val, - ) - instance_variable_set(accessor_key, val) - end - end - end - - sig do - params( - klass: T.all(Module, T::Props::ClassMethods), - prop: Symbol, - type: T.any(T::Types::Base, Module), - val: T.untyped, - ) - .void - end - def self.raise_pretty_error(klass, prop, type, val) - base_message = "Can't set #{klass.name}.#{prop} to #{val.inspect} (instance of #{val.class}) - need a #{type}" - - pretty_message = "Parameter '#{prop}': #{base_message}\n" - caller_loc = caller_locations&.find {|l| !l.to_s.include?('sorbet-runtime/lib/types/props')} - if caller_loc - pretty_message += "Caller: #{caller_loc.path}:#{caller_loc.lineno}\n" - end - - T::Configuration.call_validation_error_handler( - nil, - message: base_message, - pretty_message: pretty_message, - kind: 'Parameter', - name: prop, - type: type, - value: val, - location: caller_loc, - ) - end - end - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/serializable.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/serializable.rb deleted file mode 100644 index 2e2ea1b749..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/serializable.rb +++ /dev/null @@ -1,374 +0,0 @@ -# frozen_string_literal: true -# typed: false - -module T::Props::Serializable - include T::Props::Plugin - # Required because we have special handling for `optional: false` - include T::Props::Optional - # Required because we have special handling for extra_props - include T::Props::PrettyPrintable - - # Serializes this object to a hash, suitable for conversion to - # JSON/BSON. - # - # @param strict [T::Boolean] (true) If false, do not raise an - # exception if this object has mandatory props with missing - # values. - # @return [Hash] A serialization of this object. - def serialize(strict=true) - begin - h = __t_props_generated_serialize(strict) - rescue => e - msg = self.class.decorator.message_with_generated_source_context( - e, - :__t_props_generated_serialize, - :generate_serialize_source - ) - if msg - begin - raise e.class.new(msg) - rescue ArgumentError - raise TypeError.new(msg) - end - else - raise - end - end - - h.merge!(@_extra_props) if defined?(@_extra_props) - h - end - - private def __t_props_generated_serialize(strict) - # No-op; will be overridden if there are any props. - # - # To see the definition for class `Foo`, run `Foo.decorator.send(:generate_serialize_source)` - {} - end - - # Populates the property values on this object with the values - # from a hash. In general, prefer to use {.from_hash} to construct - # a new instance, instead of loading into an existing instance. - # - # @param hash [Hash] The hash to take property - # values from. - # @param strict [T::Boolean] (false) If true, raise an exception if - # the hash contains keys that do not correspond to any known - # props on this instance. - # @return [void] - def deserialize(hash, strict=false) - begin - hash_keys_matching_props = __t_props_generated_deserialize(hash) - rescue => e - msg = self.class.decorator.message_with_generated_source_context( - e, - :__t_props_generated_deserialize, - :generate_deserialize_source - ) - if msg - begin - raise e.class.new(msg) - rescue ArgumentError - raise TypeError.new(msg) - end - else - raise - end - end - - if hash.size > hash_keys_matching_props - serialized_forms = self.class.decorator.prop_by_serialized_forms - extra = hash.reject {|k, _| serialized_forms.key?(k)} - - # `extra` could still be empty here if the input matches a `dont_store` prop; - # historically, we just ignore those - if !extra.empty? - if strict - raise "Unknown properties for #{self.class.name}: #{extra.keys.inspect}" - else - @_extra_props = extra - end - end - end - end - - private def __t_props_generated_deserialize(hash) - # No-op; will be overridden if there are any props. - # - # To see the definition for class `Foo`, run `Foo.decorator.send(:generate_deserialize_source)` - 0 - end - - # with() will clone the old object to the new object and merge the specified props to the new object. - def with(changed_props) - with_existing_hash(changed_props, existing_hash: self.serialize) - end - - private def recursive_stringify_keys(obj) - if obj.is_a?(Hash) - new_obj = obj.class.new - obj.each do |k, v| - new_obj[k.to_s] = recursive_stringify_keys(v) - end - elsif obj.is_a?(Array) - new_obj = obj.map {|v| recursive_stringify_keys(v)} - else - new_obj = obj - end - new_obj - end - - private def with_existing_hash(changed_props, existing_hash:) - serialized = existing_hash - new_val = self.class.from_hash(serialized.merge(recursive_stringify_keys(changed_props))) - old_extra = self.instance_variable_get(:@_extra_props) if self.instance_variable_defined?(:@_extra_props) - new_extra = new_val.instance_variable_get(:@_extra_props) if new_val.instance_variable_defined?(:@_extra_props) - if old_extra != new_extra - difference = - if old_extra - new_extra.reject {|k, v| old_extra[k] == v} - else - new_extra - end - raise ArgumentError.new("Unexpected arguments: input(#{changed_props}), unexpected(#{difference})") - end - new_val - end - - # Asserts if this property is missing during strict serialize - private def required_prop_missing_from_serialize(prop) - if defined?(@_required_props_missing_from_deserialize) && - @_required_props_missing_from_deserialize&.include?(prop) - # If the prop was already missing during deserialization, that means the application - # code already had to deal with a nil value, which means we wouldn't be accomplishing - # much by raising here (other than causing an unnecessary breakage). - T::Configuration.log_info_handler( - "chalk-odm: missing required property in serialize", - prop: prop, class: self.class.name, id: self.class.decorator.get_id(self) - ) - else - raise TypeError.new("#{self.class.name}.#{prop} not set for non-optional prop") - end - end - - # Marks this property as missing during deserialize - private def required_prop_missing_from_deserialize(prop) - @_required_props_missing_from_deserialize ||= Set[] - @_required_props_missing_from_deserialize << prop - nil - end - - private def raise_deserialization_error(prop_name, value, orig_error) - T::Configuration.soft_assert_handler( - 'Deserialization error (probably unexpected stored type)', - storytime: { - klass: self.class, - prop: prop_name, - value: value, - error: orig_error.message, - notify: 'djudd' - } - ) - end -end - -############################################## - -# NB: This must stay in the same file where T::Props::Serializable is defined due to -# T::Props::Decorator#apply_plugin; see https://git.corp.stripe.com/stripe-internal/pay-server/blob/fc7f15593b49875f2d0499ffecfd19798bac05b3/chalk/odm/lib/chalk-odm/document_decorator.rb#L716-L717 -module T::Props::Serializable::DecoratorMethods - include T::Props::HasLazilySpecializedMethods::DecoratorMethods - - # Heads up! - # - # There are already too many ad-hoc options on the prop DSL. - # - # We have already done a lot of work to remove unnecessary and confusing - # options. If you're considering adding a new rule key, please come chat with - # the Sorbet team first, as we'd really like to learn more about how to best - # solve the problem you're encountering. - VALID_RULE_KEYS = {dont_store: true, name: true, raise_on_nil_write: true}.freeze - private_constant :VALID_RULE_KEYS - - def valid_rule_key?(key) - super || VALID_RULE_KEYS[key] - end - - def required_props - @class.props.select {|_, v| T::Props::Utils.required_prop?(v)}.keys - end - - def prop_dont_store?(prop) - prop_rules(prop)[:dont_store] - end - def prop_by_serialized_forms - @class.prop_by_serialized_forms - end - - def from_hash(hash, strict=false) - raise ArgumentError.new("#{hash.inspect} provided to from_hash") if !(hash && hash.is_a?(Hash)) - - i = @class.allocate - i.deserialize(hash, strict) - - i - end - - def prop_serialized_form(prop) - prop_rules(prop)[:serialized_form] - end - - def serialized_form_prop(serialized_form) - prop_by_serialized_forms[serialized_form.to_s] || raise("No such serialized form: #{serialized_form.inspect}") - end - - def add_prop_definition(prop, rules) - rules[:serialized_form] = rules.fetch(:name, prop.to_s) - res = super - prop_by_serialized_forms[rules[:serialized_form]] = prop - if T::Configuration.use_vm_prop_serde? - enqueue_lazy_vm_method_definition!(:__t_props_generated_serialize) {generate_serialize2} - enqueue_lazy_vm_method_definition!(:__t_props_generated_deserialize) {generate_deserialize2} - else - enqueue_lazy_method_definition!(:__t_props_generated_serialize) {generate_serialize_source} - enqueue_lazy_method_definition!(:__t_props_generated_deserialize) {generate_deserialize_source} - end - res - end - - private def generate_serialize_source - T::Props::Private::SerializerGenerator.generate(props) - end - - private def generate_deserialize_source - T::Props::Private::DeserializerGenerator.generate( - props, - props_with_defaults || {}, - ) - end - - private def generate_serialize2 - T::Props::Private::SerializerGenerator.generate2(decorated_class, props) - end - - private def generate_deserialize2 - T::Props::Private::DeserializerGenerator.generate2( - decorated_class, - props, - props_with_defaults || {}, - ) - end - - def message_with_generated_source_context(error, generated_method, generate_source_method) - line_label = error.backtrace.find {|l| l.end_with?("in `#{generated_method}'")} - return unless line_label - - line_num = line_label.split(':')[1]&.to_i - return unless line_num - - source_lines = self.send(generate_source_method).split("\n") - previous_blank = source_lines[0...line_num].rindex(&:empty?) || 0 - next_blank = line_num + (source_lines[line_num..-1]&.find_index(&:empty?) || 0) - context = " #{source_lines[(previous_blank + 1)...next_blank].join("\n ")}" - <<~MSG - Error in #{decorated_class.name}##{generated_method}: #{error.message} - at line #{line_num - previous_blank - 1} in: - #{context} - MSG - end - - def raise_nil_deserialize_error(hkey) - msg = "Tried to deserialize a required prop from a nil value. It's "\ - "possible that a nil value exists in the database, so you should "\ - "provide a `default: or factory:` for this prop (see go/optional "\ - "for more details). If this is already the case, you probably "\ - "omitted a required prop from the `fields:` option when doing a "\ - "partial load." - storytime = {prop: hkey, klass: decorated_class.name} - - # Notify the model owner if it exists, and always notify the API owner. - begin - if T::Configuration.class_owner_finder && (owner = T::Configuration.class_owner_finder.call(decorated_class)) - T::Configuration.hard_assert_handler( - msg, - storytime: storytime, - project: owner - ) - end - ensure - T::Configuration.hard_assert_handler(msg, storytime: storytime) - end - end - - def prop_validate_definition!(name, cls, rules, type) - result = super - - if (rules_name = rules[:name]) - unless rules_name.is_a?(String) - raise ArgumentError.new("Invalid name in prop #{@class.name}.#{name}: #{rules_name.inspect}") - end - - validate_prop_name(rules_name) - end - - if !rules[:raise_on_nil_write].nil? && rules[:raise_on_nil_write] != true - raise ArgumentError.new("The value of `raise_on_nil_write` if specified must be `true` (given: #{rules[:raise_on_nil_write]}).") - end - - result - end - - def get_id(instance) - prop = prop_by_serialized_forms['_id'] - if prop - get(instance, prop) - else - nil - end - end - - EMPTY_EXTRA_PROPS = {}.freeze - private_constant :EMPTY_EXTRA_PROPS - - def extra_props(instance) - if instance.instance_variable_defined?(:@_extra_props) - instance.instance_variable_get(:@_extra_props) || EMPTY_EXTRA_PROPS - else - EMPTY_EXTRA_PROPS - end - end - - # overrides T::Props::PrettyPrintable - private def inspect_instance_components(instance, multiline:, indent:) - if (extra_props = extra_props(instance)) && !extra_props.empty? - pretty_kvs = extra_props.map {|k, v| [k.to_sym, v.inspect]} - extra = join_props_with_pretty_values(pretty_kvs, multiline: false) - super + ["@_extra_props=<#{extra}>"] - else - super - end - end -end - -############################################## - -# NB: This must stay in the same file where T::Props::Serializable is defined due to -# T::Props::Decorator#apply_plugin; see https://git.corp.stripe.com/stripe-internal/pay-server/blob/fc7f15593b49875f2d0499ffecfd19798bac05b3/chalk/odm/lib/chalk-odm/document_decorator.rb#L716-L717 -module T::Props::Serializable::ClassMethods - def prop_by_serialized_forms - @prop_by_serialized_forms ||= {} - end - - # Allocate a new instance and call {#deserialize} to load a new - # object from a hash. - # @return [Serializable] - def from_hash(hash, strict=false) - self.decorator.from_hash(hash, strict) - end - - # Equivalent to {.from_hash} with `strict` set to true. - # @return [Serializable] - def from_hash!(hash) - self.decorator.from_hash(hash, true) - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/type_validation.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/type_validation.rb deleted file mode 100644 index ae3557783d..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/type_validation.rb +++ /dev/null @@ -1,111 +0,0 @@ -# frozen_string_literal: true -# typed: false - -module T::Props::TypeValidation - include T::Props::Plugin - - BANNED_TYPES = [Object, BasicObject, Kernel].freeze - - class UnderspecifiedType < ArgumentError; end - - module DecoratorMethods - extend T::Sig - - sig {params(key: Symbol).returns(T::Boolean).checked(:never)} - def valid_rule_key?(key) - super || key == :DEPRECATED_underspecified_type - end - - sig do - params( - name: T.any(Symbol, String), - _cls: Module, - rules: T::Hash[Symbol, T.untyped], - type: T.any(T::Types::Base, Module) - ) - .void - end - def prop_validate_definition!(name, _cls, rules, type) - super - - if !rules[:DEPRECATED_underspecified_type] - validate_type(type, field_name: name) - elsif rules[:DEPRECATED_underspecified_type] && find_invalid_subtype(type).nil? - raise ArgumentError.new("DEPRECATED_underspecified_type set unnecessarily for #{@class.name}.#{name} - #{type} is a valid type") - end - end - - sig do - params( - type: T::Types::Base, - field_name: T.any(Symbol, String), - ) - .void - end - private def validate_type(type, field_name:) - if (invalid_subtype = find_invalid_subtype(type)) - raise UnderspecifiedType.new(type_error_message(invalid_subtype, field_name, type)) - end - end - - # Returns an invalid type, if any, found in the given top-level type. - # This might be the type itself, if it is e.g. "Object", or might be - # a subtype like the type of the values of a typed hash. - # - # If the type is fully valid, returns nil. - # - # checked(:never) - called potentially many times recursively - sig {params(type: T::Types::Base).returns(T.nilable(T::Types::Base)).checked(:never)} - private def find_invalid_subtype(type) - case type - when T::Types::TypedEnumerable - find_invalid_subtype(type.type) - when T::Types::FixedHash - type.types.values.map {|subtype| find_invalid_subtype(subtype)}.compact.first - when T::Types::Union, T::Types::FixedArray - # `T.any` is valid if all of the members are valid - type.types.map {|subtype| find_invalid_subtype(subtype)}.compact.first - when T::Types::Intersection - # `T.all` is valid if at least one of the members is valid - invalid = type.types.map {|subtype| find_invalid_subtype(subtype)}.compact - if invalid.length == type.types.length - invalid.first - else - nil - end - when T::Types::Enum, T::Types::ClassOf - nil - when T::Private::Types::TypeAlias - find_invalid_subtype(type.aliased_type) - when T::Types::Simple - # TODO Could we manage to define a whitelist, consisting of something - # like primitives, subdocs, DataInterfaces, and collections/enums/unions - # thereof? - if BANNED_TYPES.include?(type.raw_type) - type - else - nil - end - else - type - end - end - - sig do - params( - type: T::Types::Base, - field_name: T.any(Symbol, String), - orig_type: T::Types::Base, - ) - .returns(String) - end - private def type_error_message(type, field_name, orig_type) - msg_prefix = "#{@class.name}.#{field_name}: #{orig_type} is invalid in prop definition" - if type == orig_type - "#{msg_prefix}. Please choose a more specific type (T.untyped and ~equivalents like Object are banned)." - else - "#{msg_prefix}. Please choose a subtype more specific than #{type} (T.untyped and ~equivalents like Object are banned)." - end - end - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/utils.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/utils.rb deleted file mode 100644 index 33d1abadce..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/utils.rb +++ /dev/null @@ -1,59 +0,0 @@ -# frozen_string_literal: true -# typed: true - -module T::Props::Utils - # Deep copy an object. The object must consist of Ruby primitive - # types and Hashes and Arrays. - def self.deep_clone_object(what, freeze: false) - result = case what - when true - true - when false - false - when Symbol, NilClass, Numeric - what - when Array - what.map {|v| deep_clone_object(v, freeze: freeze)} - when Hash - h = what.class.new - what.each do |k, v| - k.freeze if freeze - h[k] = deep_clone_object(v, freeze: freeze) - end - h - when Regexp - what.dup - when T::Enum - what - else - what.clone - end - freeze ? result.freeze : result - end - - # The prop_rules indicate whether we should check for reading a nil value for the prop/field. - # This is mostly for the compatibility check that we allow existing documents carry some nil prop/field. - def self.need_nil_read_check?(prop_rules) - # . :on_load allows nil read, but we need to check for the read for future writes - prop_rules[:optional] == :on_load || prop_rules[:raise_on_nil_write] - end - - # The prop_rules indicate whether we should check for writing a nil value for the prop/field. - def self.need_nil_write_check?(prop_rules) - need_nil_read_check?(prop_rules) || T::Props::Utils.required_prop?(prop_rules) - end - - def self.required_prop?(prop_rules) - # Clients should never reference :_tnilable as the implementation can change. - !prop_rules[:_tnilable] - end - - def self.optional_prop?(prop_rules) - # Clients should never reference :_tnilable as the implementation can change. - !!prop_rules[:_tnilable] - end - - def self.merge_serialized_optional_rule(prop_rules) - {'_tnilable' => true}.merge(prop_rules.merge('_tnilable' => true)) - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/weak_constructor.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/weak_constructor.rb deleted file mode 100644 index 3ffe1be695..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/props/weak_constructor.rb +++ /dev/null @@ -1,67 +0,0 @@ -# frozen_string_literal: true -# typed: false - -module T::Props::WeakConstructor - include T::Props::Optional - extend T::Sig - - # checked(:never) - O(runtime object construction) - sig {params(hash: T::Hash[Symbol, T.untyped]).void.checked(:never)} - def initialize(hash={}) - decorator = self.class.decorator - - hash_keys_matching_props = decorator.construct_props_with_defaults(self, hash) + - decorator.construct_props_without_defaults(self, hash) - - if hash_keys_matching_props < hash.size - raise ArgumentError.new("#{self.class}: Unrecognized properties: #{(hash.keys - decorator.props.keys).join(', ')}") - end - end -end - -module T::Props::WeakConstructor::DecoratorMethods - extend T::Sig - - # Set values for all props that have no defaults. Ignore any not present. - # - # @return [Integer] A count of props that we successfully initialized (which - # we'll use to check for any unrecognized input.) - # - # checked(:never) - O(runtime object construction) - sig {params(instance: T::Props::WeakConstructor, hash: T::Hash[Symbol, T.untyped]).returns(Integer).checked(:never)} - def construct_props_without_defaults(instance, hash) - # Use `each_pair` rather than `count` because, as of Ruby 2.6, the latter delegates to Enumerator - # and therefore allocates for each entry. - result = 0 - props_without_defaults&.each_pair do |p, setter_proc| - if hash.key?(p) - instance.instance_exec(hash[p], &setter_proc) - result += 1 - end - end - result - end - - # Set values for all props that have defaults. Use the default if and only if - # the prop key isn't in the input. - # - # @return [Integer] A count of props that we successfully initialized (which - # we'll use to check for any unrecognized input.) - # - # checked(:never) - O(runtime object construction) - sig {params(instance: T::Props::WeakConstructor, hash: T::Hash[Symbol, T.untyped]).returns(Integer).checked(:never)} - def construct_props_with_defaults(instance, hash) - # Use `each_pair` rather than `count` because, as of Ruby 2.6, the latter delegates to Enumerator - # and therefore allocates for each entry. - result = 0 - props_with_defaults&.each_pair do |p, default_struct| - if hash.key?(p) - instance.instance_exec(hash[p], &default_struct.setter_proc) - result += 1 - else - default_struct.set_default(instance) - end - end - result - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/sig.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/sig.rb deleted file mode 100644 index 3112adf861..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/sig.rb +++ /dev/null @@ -1,30 +0,0 @@ -# frozen_string_literal: true -# typed: strict - -# Used as a mixin to any class so that you can call `sig`. -# Docs at https://sorbet.org/docs/sigs -module T::Sig - module WithoutRuntime - # At runtime, does nothing, but statically it is treated exactly the same - # as T::Sig#sig. Only use it in cases where you can't use T::Sig#sig. - def self.sig(arg0=nil, &blk); end - - original_verbose = $VERBOSE - $VERBOSE = false - - # At runtime, does nothing, but statically it is treated exactly the same - # as T::Sig#sig. Only use it in cases where you can't use T::Sig#sig. - T::Sig::WithoutRuntime.sig {params(arg0: T.nilable(Symbol), blk: T.proc.bind(T::Private::Methods::DeclBuilder).void).void} - def self.sig(arg0=nil, &blk); end # rubocop:disable Lint/DuplicateMethods - - $VERBOSE = original_verbose - end - - # Declares a method with type signatures and/or - # abstract/override/... helpers. See the documentation URL on - # {T::Helpers} - T::Sig::WithoutRuntime.sig {params(arg0: T.nilable(Symbol), blk: T.proc.bind(T::Private::Methods::DeclBuilder).void).void} - def sig(arg0=nil, &blk) - T::Private::Methods.declare_sig(self, Kernel.caller_locations(1, 1)&.first, arg0, &blk) - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/struct.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/struct.rb deleted file mode 100644 index 5f35d1f81f..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/struct.rb +++ /dev/null @@ -1,18 +0,0 @@ -# frozen_string_literal: true -# typed: true - -class T::InexactStruct - include T::Props - include T::Props::Serializable - include T::Props::Constructor -end - -class T::Struct < T::InexactStruct - def self.inherited(subclass) - super(subclass) - T::Private::ClassUtils.replace_method(subclass.singleton_class, :inherited) do |s| - super(s) - raise "#{self.name} is a subclass of T::Struct and cannot be subclassed" - end - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/attached_class.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/attached_class.rb deleted file mode 100644 index 059956a68d..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/attached_class.rb +++ /dev/null @@ -1,37 +0,0 @@ -# frozen_string_literal: true -# typed: true - -module T::Types - # Modeling AttachedClass properly at runtime would require additional - # tracking, so at runtime we permit all values and rely on the static checker. - # As AttachedClass is modeled statically as a type member on every singleton - # class, this is consistent with the runtime behavior for all type members. - class AttachedClassType < Base - - def initialize(); end - - # overrides Base - def name - "T.attached_class" - end - - # overrides Base - def valid?(obj) - true - end - - # overrides Base - private def subtype_of_single?(other) - case other - when AttachedClassType - true - else - false - end - end - - module Private - INSTANCE = AttachedClassType.new.freeze - end - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/base.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/base.rb deleted file mode 100644 index cce89b178a..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/base.rb +++ /dev/null @@ -1,172 +0,0 @@ -# frozen_string_literal: true -# typed: true - -module T::Types - class Base - def self.method_added(method_name) - super(method_name) - # What is now `subtype_of_single?` used to be named `subtype_of?`. Make sure people don't - # override the wrong thing. - # - # NB: Outside of T::Types, we would enforce this by using `sig` and not declaring the method - # as overridable, but doing so here would result in a dependency cycle. - if method_name == :subtype_of? && self != T::Types::Base - raise "`subtype_of?` should not be overridden. You probably want to override " \ - "`subtype_of_single?` instead." - end - end - - # this will be redefined in certain subclasses - def recursively_valid?(obj) - valid?(obj) - end - - def valid?(obj) - raise NotImplementedError - end - - # @return [T::Boolean] This method must be implemented to return whether the subclass is a subtype - # of `type`. This should only be called by `subtype_of?`, which guarantees that `type` will be - # a "single" type, by which we mean it won't be a Union or an Intersection (c.f. - # `isSubTypeSingle` in sorbet). - private def subtype_of_single?(type) - raise NotImplementedError - end - - # Equality is based on name, so be sure the name reflects all relevant state when implementing. - def name - raise NotImplementedError - end - - # Mirrors ruby_typer::core::Types::isSubType - # See https://git.corp.stripe.com/stripe-internal/ruby-typer/blob/9fc8ed998c04ac0b96592ae6bb3493b8a925c5c1/core/types/subtyping.cc#L912-L950 - # - # This method cannot be overridden (see `method_added` above). - # Subclasses only need to implement `subtype_of_single?`). - def subtype_of?(t2) - t1 = self - - if t2.is_a?(T::Private::Types::TypeAlias) - t2 = t2.aliased_type - end - - if t1.is_a?(T::Private::Types::TypeAlias) - return t1.aliased_type.subtype_of?(t2) - end - - # pairs to cover: 1 (_, _) - # 2 (_, And) - # 3 (_, Or) - # 4 (And, _) - # 5 (And, And) - # 6 (And, Or) - # 7 (Or, _) - # 8 (Or, And) - # 9 (Or, Or) - - # Note: order of cases here matters! - if t1.is_a?(T::Types::Union) # 7, 8, 9 - # this will be incorrect if/when we have Type members - return t1.types.all? {|t1_member| t1_member.subtype_of?(t2)} - end - - if t2.is_a?(T::Types::Intersection) # 2, 5 - # this will be incorrect if/when we have Type members - return t2.types.all? {|t2_member| t1.subtype_of?(t2_member)} - end - - if t2.is_a?(T::Types::Union) - if t1.is_a?(T::Types::Intersection) # 6 - # dropping either of parts eagerly make subtype test be too strict. - # we have to try both cases, when we normally try only one - return t2.types.any? {|t2_member| t1.subtype_of?(t2_member)} || - t1.types.any? {|t1_member| t1_member.subtype_of?(t2)} - end - return t2.types.any? {|t2_member| t1.subtype_of?(t2_member)} # 3 - end - - if t1.is_a?(T::Types::Intersection) # 4 - # this will be incorrect if/when we have Type members - return t1.types.any? {|t1_member| t1_member.subtype_of?(t2)} - end - - # 1; Start with some special cases - if t1.is_a?(T::Private::Types::Void) - return t2.is_a?(T::Private::Types::Void) - end - - if t1.is_a?(T::Types::Untyped) || t2.is_a?(T::Types::Untyped) - return true - end - - # Rest of (1) - subtype_of_single?(t2) - end - - def to_s - name - end - - def describe_obj(obj) - # Would be redundant to print class and value in these common cases. - case obj - when nil, true, false - return "type #{obj.class}" - end - - # In rare cases, obj.inspect may fail, or be undefined, so rescue. - begin - # Default inspect behavior of, eg; `#` is ugly; just print the hash instead, which is more concise/readable. - if obj.method(:inspect).owner == Kernel - "type #{obj.class} with hash #{obj.hash}" - elsif T::Configuration.include_value_in_type_errors? - "type #{obj.class} with value #{T::Utils.string_truncate_middle(obj.inspect, 30, 30)}" - else - "type #{obj.class}" - end - rescue StandardError, SystemStackError - "type #{obj.class} with unprintable value" - end - end - - def error_message_for_obj(obj) - if valid?(obj) - nil - else - error_message(obj) - end - end - - def error_message_for_obj_recursive(obj) - if recursively_valid?(obj) - nil - else - error_message(obj) - end - end - - private def error_message(obj) - "Expected type #{self.name}, got #{describe_obj(obj)}" - end - - def validate!(obj) - err = error_message_for_obj(obj) - raise TypeError.new(err) if err - end - - ### Equality methods (necessary for deduping types with `uniq`) - - def hash - name.hash - end - - # Type equivalence, defined by serializing the type to a string (with - # `#name`) and comparing the resulting strings for equality. - def ==(other) - (T::Utils.resolve_alias(other).class == T::Utils.resolve_alias(self).class) && - other.name == self.name - end - - alias_method :eql?, :== - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/class_of.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/class_of.rb deleted file mode 100644 index d56f21d4c7..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/class_of.rb +++ /dev/null @@ -1,40 +0,0 @@ -# frozen_string_literal: true -# typed: true - -module T::Types - # Validates that an object belongs to the specified class. - class ClassOf < Base - attr_reader :type - - def initialize(type) - @type = type - end - - # overrides Base - def name - "T.class_of(#{@type})" - end - - # overrides Base - def valid?(obj) - obj.is_a?(Module) && obj <= @type - end - - # overrides Base - def subtype_of_single?(other) - case other - when ClassOf - @type <= other.type - when Simple - @type.is_a?(other.raw_type) - else - false - end - end - - # overrides Base - def describe_obj(obj) - obj.inspect - end - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/enum.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/enum.rb deleted file mode 100644 index 97ecfe0c0c..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/enum.rb +++ /dev/null @@ -1,40 +0,0 @@ -# frozen_string_literal: true -# typed: true - -module T::Types - # validates that the provided value is within a given set/enum - class Enum < Base - extend T::Sig - - attr_reader :values - - def initialize(values) - @values = values - end - - # overrides Base - def valid?(obj) - @values.member?(obj) - end - - # overrides Base - private def subtype_of_single?(other) - case other - when Enum - (other.values - @values).empty? - else - false - end - end - - # overrides Base - def name - "T.deprecated_enum([#{@values.map(&:inspect).join(', ')}])" - end - - # overrides Base - def describe_obj(obj) - obj.inspect - end - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/fixed_array.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/fixed_array.rb deleted file mode 100644 index 3bed082bcc..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/fixed_array.rb +++ /dev/null @@ -1,86 +0,0 @@ -# frozen_string_literal: true -# https://jira.corp.stripe.com/browse/RUBYPLAT-1107 -# typed: false - -module T::Types - # Takes a list of types. Validates each item in an array using the type in the same position - # in the list. - class FixedArray < Base - attr_reader :types - - def initialize(types) - @types = types.map {|type| T::Utils.coerce(type)} - end - - # overrides Base - def name - "[#{@types.join(', ')}]" - end - - # overrides Base - def recursively_valid?(obj) - if obj.is_a?(Array) && obj.length == @types.length - i = 0 - while i < @types.length - if !@types[i].recursively_valid?(obj[i]) - return false - end - i += 1 - end - true - else - false - end - end - - # overrides Base - def valid?(obj) - if obj.is_a?(Array) && obj.length == @types.length - i = 0 - while i < @types.length - if !@types[i].valid?(obj[i]) - return false - end - i += 1 - end - true - else - false - end - end - - # overrides Base - private def subtype_of_single?(other) - case other - when FixedArray - # Properly speaking, covariance here is unsound since arrays - # can be mutated, but sorbet implements covariant tuples for - # ease of adoption. - @types.size == other.types.size && @types.zip(other.types).all? do |t1, t2| - t1.subtype_of?(t2) - end - else - false - end - end - - # This gives us better errors, e.g.: - # "Expected [String, Symbol], got [String, String]" - # instead of - # "Expected [String, Symbol], got Array". - # - # overrides Base - def describe_obj(obj) - if obj.is_a?(Array) - if obj.length == @types.length - item_classes = obj.map(&:class).join(', ') - "type [#{item_classes}]" - else - "array of size #{obj.length}" - end - else - super - end - end - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/fixed_hash.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/fixed_hash.rb deleted file mode 100644 index d8fddb3703..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/fixed_hash.rb +++ /dev/null @@ -1,74 +0,0 @@ -# frozen_string_literal: true -# typed: true - -module T::Types - # Takes a hash of types. Validates each item in a hash using the type in the same position - # in the list. - class FixedHash < Base - attr_reader :types - - def initialize(types) - @types = types.transform_values {|v| T::Utils.coerce(v)} - end - - # overrides Base - def name - serialize_hash(@types) - end - - # overrides Base - def recursively_valid?(obj) - return false unless obj.is_a?(Hash) - return false if @types.any? {|key, type| !type.recursively_valid?(obj[key])} - return false if obj.any? {|key, _| !@types[key]} - true - end - - # overrides Base - def valid?(obj) - return false unless obj.is_a?(Hash) - return false if @types.any? {|key, type| !type.valid?(obj[key])} - return false if obj.any? {|key, _| !@types[key]} - true - end - - # overrides Base - private def subtype_of_single?(other) - case other - when FixedHash - # Using `subtype_of?` here instead of == would be unsound - @types == other.types - else - false - end - end - - # This gives us better errors, e.g.: - # `Expected {a: String}, got {a: TrueClass}` - # instead of - # `Expected {a: String}, got Hash`. - # - # overrides Base - def describe_obj(obj) - if obj.is_a?(Hash) - "type #{serialize_hash(obj.transform_values(&:class))}" - else - super - end - end - - private - - def serialize_hash(hash) - entries = hash.map do |(k, v)| - if Symbol === k && ":#{k}" == k.inspect - "#{k}: #{v}" - else - "#{k.inspect} => #{v}" - end - end - - "{#{entries.join(', ')}}" - end - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/intersection.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/intersection.rb deleted file mode 100644 index 8e4b42f187..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/intersection.rb +++ /dev/null @@ -1,42 +0,0 @@ -# frozen_string_literal: true -# typed: true - -module T::Types - # Takes a list of types. Validates that an object matches all of the types. - class Intersection < Base - attr_reader :types - - def initialize(types) - @types = types.flat_map do |type| - type = T::Utils.resolve_alias(type) - if type.is_a?(Intersection) - # Simplify nested intersections (mostly so `name` returns a nicer value) - type.types - else - T::Utils.coerce(type) - end - end.uniq - end - - # overrides Base - def name - "T.all(#{@types.map(&:name).sort.join(', ')})" - end - - # overrides Base - def recursively_valid?(obj) - @types.all? {|type| type.recursively_valid?(obj)} - end - - # overrides Base - def valid?(obj) - @types.all? {|type| type.valid?(obj)} - end - - # overrides Base - private def subtype_of_single?(other) - raise "This should never be reached if you're going through `subtype_of?` (and you should be)" - end - - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/noreturn.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/noreturn.rb deleted file mode 100644 index c285797480..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/noreturn.rb +++ /dev/null @@ -1,29 +0,0 @@ -# frozen_string_literal: true -# typed: true - -module T::Types - # The bottom type - class NoReturn < Base - - def initialize; end - - # overrides Base - def name - "T.noreturn" - end - - # overrides Base - def valid?(obj) - false - end - - # overrides Base - private def subtype_of_single?(other) - true - end - - module Private - INSTANCE = NoReturn.new.freeze - end - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/proc.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/proc.rb deleted file mode 100644 index aece6a3a2f..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/proc.rb +++ /dev/null @@ -1,51 +0,0 @@ -# frozen_string_literal: true -# typed: true - -module T::Types - # Defines the type of a proc (a ruby callable). At runtime, only - # validates that the value is a `::Proc`. - # - # At present, we only support fixed-arity procs with no optional or - # keyword arguments. - class Proc < Base - attr_reader :arg_types - attr_reader :returns - - def initialize(arg_types, returns) - @arg_types = {} - arg_types.each do |key, raw_type| - @arg_types[key] = T::Utils.coerce(raw_type) - end - @returns = T::Utils.coerce(returns) - end - - # overrides Base - def name - args = [] - @arg_types.each do |k, v| - args << "#{k}: #{v.name}" - end - "T.proc.params(#{args.join(', ')}).returns(#{returns})" - end - - # overrides Base - def valid?(obj) - obj.is_a?(::Proc) - end - - # overrides Base - private def subtype_of_single?(other) - case other - when self.class - if arg_types.size != other.arg_types.size - return false - end - arg_types.values.zip(other.arg_types.values).all? do |a, b| - b.subtype_of?(a) - end && returns.subtype_of?(other.returns) - else - false - end - end - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/self_type.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/self_type.rb deleted file mode 100644 index e431a3e0f9..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/self_type.rb +++ /dev/null @@ -1,35 +0,0 @@ -# frozen_string_literal: true -# typed: true - -module T::Types - # Modeling self-types properly at runtime would require additional tracking, - # so at runtime we permit all values and rely on the static checker. - class SelfType < Base - - def initialize(); end - - # overrides Base - def name - "T.self_type" - end - - # overrides Base - def valid?(obj) - true - end - - # overrides Base - private def subtype_of_single?(other) - case other - when SelfType - true - else - false - end - end - - module Private - INSTANCE = SelfType.new.freeze - end - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/simple.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/simple.rb deleted file mode 100644 index 2789adbb67..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/simple.rb +++ /dev/null @@ -1,94 +0,0 @@ -# frozen_string_literal: true -# typed: true - -module T::Types - # Validates that an object belongs to the specified class. - class Simple < Base - attr_reader :raw_type - - def initialize(raw_type) - @raw_type = raw_type - end - - # overrides Base - def name - # Memoize to mitigate pathological performance with anonymous modules (https://bugs.ruby-lang.org/issues/11119) - # - # `name` isn't normally a hot path for types, but it is used in initializing a T::Types::Union, - # and so in `T.nilable`, and so in runtime constructions like `x = T.let(nil, T.nilable(Integer))`. - @name ||= @raw_type.name.freeze - end - - # overrides Base - def valid?(obj) - obj.is_a?(@raw_type) - end - - # overrides Base - private def subtype_of_single?(other) - case other - when Simple - @raw_type <= other.raw_type - else - false - end - end - - # overrides Base - private def error_message(obj) - error_message = super(obj) - actual_name = obj.class.name - - return error_message unless name == actual_name - - <<~MSG.strip - #{error_message} - - The expected type and received object type have the same name but refer to different constants. - Expected type is #{name} with object id #{@raw_type.__id__}, but received type is #{actual_name} with object id #{obj.class.__id__}. - - There might be a constant reloading problem in your application. - MSG - end - - def to_nilable - @nilable ||= T::Types::Union.new([self, T::Utils::Nilable::NIL_TYPE]) - end - - module Private - module Pool - @cache = ObjectSpace::WeakMap.new - - def self.type_for_module(mod) - cached = @cache[mod] - return cached if cached - - type = if mod == ::Array - T::Array[T.untyped] - elsif mod == ::Hash - T::Hash[T.untyped, T.untyped] - elsif mod == ::Enumerable - T::Enumerable[T.untyped] - elsif mod == ::Enumerator - T::Enumerator[T.untyped] - elsif mod == ::Range - T::Range[T.untyped] - elsif !Object.autoload?(:Set) && Object.const_defined?(:Set) && mod == ::Set - T::Set[T.untyped] - else - Simple.new(mod) - end - - # Unfortunately, we still need to check if the module is frozen, - # since WeakMap adds a finalizer to the key that is added - # to the map, so that it can clear the map entry when the key is - # garbage collected. - # For a frozen object, though, adding a finalizer is not a valid - # operation, so this still raises if `mod` is frozen. - @cache[mod] = type unless mod.frozen? - type - end - end - end - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/t_enum.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/t_enum.rb deleted file mode 100644 index 121368c7b6..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/t_enum.rb +++ /dev/null @@ -1,38 +0,0 @@ -# frozen_string_literal: true -# typed: true - -module T::Types - # Validates that an object is equal to another T::Enum singleton value. - class TEnum < Base - attr_reader :val - - def initialize(val) - @val = val - end - - # overrides Base - def name - # Strips the #<...> off, just leaving the ... - # Reasoning: the user will have written something like - # T.any(MyEnum::A, MyEnum::B) - # in the type, so we should print what they wrote in errors, not: - # T.any(#, #) - @val.inspect[2..-2] - end - - # overrides Base - def valid?(obj) - @val == obj - end - - # overrides Base - private def subtype_of_single?(other) - case other - when TEnum - @val == other.val - else - false - end - end - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/type_member.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/type_member.rb deleted file mode 100644 index fadd2a7eea..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/type_member.rb +++ /dev/null @@ -1,7 +0,0 @@ -# frozen_string_literal: true -# typed: strict - -module T::Types - class TypeMember < TypeVariable - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/type_parameter.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/type_parameter.rb deleted file mode 100644 index ea82a07cc3..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/type_parameter.rb +++ /dev/null @@ -1,23 +0,0 @@ -# frozen_string_literal: true -# typed: true - -module T::Types - class TypeParameter < Base - def initialize(name) - raise ArgumentError.new("not a symbol: #{name}") unless name.is_a?(Symbol) - @name = name - end - - def valid?(obj) - true - end - - def subtype_of_single?(type) - true - end - - def name - "T.type_parameter(:#{@name})" - end - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/type_template.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/type_template.rb deleted file mode 100644 index 8c83de8949..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/type_template.rb +++ /dev/null @@ -1,7 +0,0 @@ -# frozen_string_literal: true -# typed: strict - -module T::Types - class TypeTemplate < TypeVariable - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/type_variable.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/type_variable.rb deleted file mode 100644 index 187119167d..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/type_variable.rb +++ /dev/null @@ -1,34 +0,0 @@ -# frozen_string_literal: true -# typed: true - -module T::Types - # Since we do type erasure at runtime, this just validates the variance and - # provides some syntax for the static type checker - class TypeVariable < Base - attr_reader :variance - - VALID_VARIANCES = %i[in out invariant].freeze - - def initialize(variance) - case variance - when Hash then raise ArgumentError.new("Pass bounds using a block. Got: #{variance}") - when *VALID_VARIANCES then nil - else - raise TypeError.new("invalid variance #{variance}") - end - @variance = variance - end - - def valid?(obj) - true - end - - def subtype_of_single?(type) - true - end - - def name - Untyped.new.name - end - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/typed_array.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/typed_array.rb deleted file mode 100644 index 0b5f3541a9..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/typed_array.rb +++ /dev/null @@ -1,39 +0,0 @@ -# frozen_string_literal: true -# typed: true - -module T::Types - class TypedArray < TypedEnumerable - # overrides Base - def name - "T::Array[#{@type.name}]" - end - - def underlying_class - Array - end - - # overrides Base - def recursively_valid?(obj) - obj.is_a?(Array) && super - end - - # overrides Base - def valid?(obj) - obj.is_a?(Array) - end - - def new(*args) - Array.new(*T.unsafe(args)) - end - - class Untyped < TypedArray - def initialize - super(T.untyped) - end - - def valid?(obj) - obj.is_a?(Array) - end - end - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/typed_enumerable.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/typed_enumerable.rb deleted file mode 100644 index 65c2631f0a..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/typed_enumerable.rb +++ /dev/null @@ -1,176 +0,0 @@ -# frozen_string_literal: true -# typed: true - -module T::Types - # Note: All subclasses of Enumerable should add themselves to the - # `case` statement below in `describe_obj` in order to get better - # error messages. - class TypedEnumerable < Base - attr_reader :type - - def initialize(type) - @type = T::Utils.coerce(type) - end - - def underlying_class - Enumerable - end - - # overrides Base - def name - "T::Enumerable[#{@type.name}]" - end - - # overrides Base - def valid?(obj) - obj.is_a?(Enumerable) - end - - # overrides Base - def recursively_valid?(obj) - return false unless obj.is_a?(Enumerable) - case obj - when Array - begin - it = 0 - while it < obj.count - return false unless @type.recursively_valid?(obj[it]) - it += 1 - end - true - end - when Hash - return false unless @type.is_a?(FixedArray) - types = @type.types - return false if types.count != 2 - key_type = types[0] - value_type = types[1] - obj.each_pair do |key, val| - # Some objects (I'm looking at you Rack::Utils::HeaderHash) don't - # iterate over a [key, value] array, so we can't juse use the @type.recursively_valid?(v) - return false if !key_type.recursively_valid?(key) || !value_type.recursively_valid?(val) - end - true - when Enumerator::Lazy - # Enumerators can be unbounded: see `[:foo, :bar].cycle` - true - when Enumerator - # Enumerators can be unbounded: see `[:foo, :bar].cycle` - true - when Range - # A nil beginning or a nil end does not provide any type information. That is, nil in a range represents - # boundlessness, it does not express a type. For example `(nil...nil)` is not a T::Range[NilClass], its a range - # of unknown types (T::Range[T.untyped]). - # Similarly, `(nil...1)` is not a `T::Range[T.nilable(Integer)]`, it's a boundless range of Integer. - (obj.begin.nil? || @type.recursively_valid?(obj.begin)) && (obj.end.nil? || @type.recursively_valid?(obj.end)) - when Set - obj.each do |item| - return false unless @type.recursively_valid?(item) - end - - true - else - # We don't check the enumerable since it isn't guaranteed to be - # rewindable (e.g. STDIN) and it may be expensive to enumerate - # (e.g. an enumerator that makes an HTTP request)" - true - end - end - - # overrides Base - private def subtype_of_single?(other) - if other.class <= TypedEnumerable && - underlying_class <= other.underlying_class - # Enumerables are covariant because they are read only - # - # Properly speaking, many Enumerable subtypes (e.g. Set) - # should be invariant because they are mutable and support - # both reading and writing. However, Sorbet treats *all* - # Enumerable subclasses as covariant for ease of adoption. - @type.subtype_of?(other.type) - else - false - end - end - - # overrides Base - def describe_obj(obj) - return super unless obj.is_a?(Enumerable) - type_from_instance(obj).name - end - - private def type_from_instances(objs) - return objs.class unless objs.is_a?(Enumerable) - obtained_types = [] - begin - objs.each do |x| - obtained_types << type_from_instance(x) - end - rescue - return T.untyped # all we can do is go with the types we have so far - end - if obtained_types.count > 1 - # Multiple kinds of bad types showed up, we'll suggest a union - # type you might want. - Union.new(obtained_types) - elsif obtained_types.empty? - T.noreturn - else - # Everything was the same bad type, lets just show that - obtained_types.first - end - end - - private def type_from_instance(obj) - if [true, false].include?(obj) - return T::Boolean - elsif !obj.is_a?(Enumerable) - return obj.class - end - - case obj - when Array - T::Array[type_from_instances(obj)] - when Hash - inferred_key = type_from_instances(obj.keys) - inferred_val = type_from_instances(obj.values) - T::Hash[inferred_key, inferred_val] - when Range - # We can't get any information from `NilClass` in ranges (since nil is used to represent boundlessness). - typeable_objects = [obj.begin, obj.end].compact - if typeable_objects.empty? - T::Range[T.untyped] - else - T::Range[type_from_instances(typeable_objects)] - end - when Enumerator::Lazy - T::Enumerator::Lazy[type_from_instances(obj)] - when Enumerator - T::Enumerator[type_from_instances(obj)] - when Set - T::Set[type_from_instances(obj)] - when IO - # Short circuit for anything IO-like (File, etc.). In these cases, - # enumerating the object is a destructive operation and might hang. - obj.class - else - # This is a specialized enumerable type, just return the class. - if T::Configuration::AT_LEAST_RUBY_2_7 - Object.instance_method(:class).bind_call(obj) - else - Object.instance_method(:class).bind(obj).call - end - end - end - - class Untyped < TypedEnumerable - def initialize - super(T.untyped) - end - - def valid?(obj) - obj.is_a?(Enumerable) - end - end - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/typed_enumerator.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/typed_enumerator.rb deleted file mode 100644 index e79341eb94..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/typed_enumerator.rb +++ /dev/null @@ -1,41 +0,0 @@ -# frozen_string_literal: true -# typed: true - -module T::Types - class TypedEnumerator < TypedEnumerable - attr_reader :type - - def underlying_class - Enumerator - end - - # overrides Base - def name - "T::Enumerator[#{@type.name}]" - end - - # overrides Base - def recursively_valid?(obj) - obj.is_a?(Enumerator) && super - end - - # overrides Base - def valid?(obj) - obj.is_a?(Enumerator) - end - - def new(*args, &blk) - T.unsafe(Enumerator).new(*args, &blk) - end - - class Untyped < TypedEnumerator - def initialize - super(T.untyped) - end - - def valid?(obj) - obj.is_a?(Enumerator) - end - end - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/typed_enumerator_lazy.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/typed_enumerator_lazy.rb deleted file mode 100644 index 3569be398a..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/typed_enumerator_lazy.rb +++ /dev/null @@ -1,41 +0,0 @@ -# frozen_string_literal: true -# typed: true - -module T::Types - class TypedEnumeratorLazy < TypedEnumerable - attr_reader :type - - def underlying_class - Enumerator::Lazy - end - - # overrides Base - def name - "T::Enumerator::Lazy[#{@type.name}]" - end - - # overrides Base - def recursively_valid?(obj) - obj.is_a?(Enumerator::Lazy) && super - end - - # overrides Base - def valid?(obj) - obj.is_a?(Enumerator::Lazy) - end - - def new(*args, &blk) - T.unsafe(Enumerator::Lazy).new(*args, &blk) - end - - class Untyped < TypedEnumeratorLazy - def initialize - super(T.untyped) - end - - def valid?(obj) - obj.is_a?(Enumerator::Lazy) - end - end - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/typed_hash.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/typed_hash.rb deleted file mode 100644 index f48e0c1595..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/typed_hash.rb +++ /dev/null @@ -1,48 +0,0 @@ -# frozen_string_literal: true -# typed: true - -module T::Types - class TypedHash < TypedEnumerable - # Technically we don't need these, but they are a nice api - attr_reader :keys, :values - - def underlying_class - Hash - end - - def initialize(keys:, values:) - @keys = T::Utils.coerce(keys) - @values = T::Utils.coerce(values) - @type = T::Utils.coerce([keys, values]) - end - - # overrides Base - def name - "T::Hash[#{@keys.name}, #{@values.name}]" - end - - # overrides Base - def recursively_valid?(obj) - obj.is_a?(Hash) && super - end - - # overrides Base - def valid?(obj) - obj.is_a?(Hash) - end - - def new(*args, &blk) - Hash.new(*T.unsafe(args), &blk) - end - - class Untyped < TypedHash - def initialize - super(keys: T.untyped, values: T.untyped) - end - - def valid?(obj) - obj.is_a?(Hash) - end - end - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/typed_range.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/typed_range.rb deleted file mode 100644 index 50e2ef9d53..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/typed_range.rb +++ /dev/null @@ -1,31 +0,0 @@ -# frozen_string_literal: true -# typed: true - -module T::Types - class TypedRange < TypedEnumerable - attr_reader :type - - def underlying_class - Hash - end - - # overrides Base - def name - "T::Range[#{@type.name}]" - end - - # overrides Base - def recursively_valid?(obj) - obj.is_a?(Range) && super - end - - # overrides Base - def valid?(obj) - obj.is_a?(Range) - end - - def new(*args) - T.unsafe(Range).new(*args) - end - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/typed_set.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/typed_set.rb deleted file mode 100644 index 8c1b2caee3..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/typed_set.rb +++ /dev/null @@ -1,53 +0,0 @@ -# frozen_string_literal: true -# typed: true - -module T::Types - class TypedSet < TypedEnumerable - attr_reader :type - - def underlying_class - Hash - end - - # overrides Base - def name - "T::Set[#{@type.name}]" - end - - # overrides Base - def recursively_valid?(obj) - # Re-implements non_forcing_is_a? - return false if Object.autoload?(:Set) # Set is meant to be autoloaded but not yet loaded, this value can't be a Set - return false unless Object.const_defined?(:Set) # Set is not loaded yet - obj.is_a?(Set) && super - end - - # overrides Base - def valid?(obj) - # Re-implements non_forcing_is_a? - return false if Object.autoload?(:Set) # Set is meant to be autoloaded but not yet loaded, this value can't be a Set - return false unless Object.const_defined?(:Set) # Set is not loaded yet - obj.is_a?(Set) - end - - def new(*args) - # Fine for this to blow up, because hopefully if they're trying to make a - # Set, they don't mind putting (or already have put) a `require 'set'` in - # their program directly. - Set.new(*T.unsafe(args)) - end - - class Untyped < TypedSet - def initialize - super(T.untyped) - end - - def valid?(obj) - # Re-implements non_forcing_is_a? - return false if Object.autoload?(:Set) # Set is meant to be autoloaded but not yet loaded, this value can't be a Set - return false unless Object.const_defined?(:Set) # Set is not loaded yet - obj.is_a?(Set) - end - end - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/union.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/union.rb deleted file mode 100644 index 3729dc48de..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/union.rb +++ /dev/null @@ -1,91 +0,0 @@ -# frozen_string_literal: true -# typed: true - -module T::Types - # Takes a list of types. Validates that an object matches at least one of the types. - class Union < Base - attr_reader :types - - def initialize(types) - @types = types.flat_map do |type| - type = T::Utils.coerce(type) - if type.is_a?(Union) - # Simplify nested unions (mostly so `name` returns a nicer value) - type.types - else - type - end - end.uniq - end - - # overrides Base - def name - type_shortcuts(@types) - end - - private def type_shortcuts(types) - if types.size == 1 - return types[0].name - end - nilable = T::Utils.coerce(NilClass) - trueclass = T::Utils.coerce(TrueClass) - falseclass = T::Utils.coerce(FalseClass) - if types.any? {|t| t == nilable} - remaining_types = types.reject {|t| t == nilable} - "T.nilable(#{type_shortcuts(remaining_types)})" - elsif types.any? {|t| t == trueclass} && types.any? {|t| t == falseclass} - remaining_types = types.reject {|t| t == trueclass || t == falseclass} - type_shortcuts([T::Private::Types::StringHolder.new("T::Boolean")] + remaining_types) - else - names = types.map(&:name).compact.sort - "T.any(#{names.join(', ')})" - end - end - - # overrides Base - def recursively_valid?(obj) - @types.any? {|type| type.recursively_valid?(obj)} - end - - # overrides Base - def valid?(obj) - @types.any? {|type| type.valid?(obj)} - end - - # overrides Base - private def subtype_of_single?(other) - raise "This should never be reached if you're going through `subtype_of?` (and you should be)" - end - - module Private - module Pool - EMPTY_ARRAY = [].freeze - private_constant :EMPTY_ARRAY - - # @param type_a [T::Types::Base] - # @param type_b [T::Types::Base] - # @param types [Array] optional array of additional T::Types::Base instances - def self.union_of_types(type_a, type_b, types=EMPTY_ARRAY) - if types.empty? - # We aren't guaranteed to detect a simple `T.nilable()` type here - # in cases where there are duplicate types, nested unions, etc. - # - # That's ok, because this is an optimization which isn't necessary for - # correctness. - if type_b == T::Utils::Nilable::NIL_TYPE && type_a.is_a?(T::Types::Simple) - type_a.to_nilable - elsif type_a == T::Utils::Nilable::NIL_TYPE && type_b.is_a?(T::Types::Simple) - type_b.to_nilable - else - Union.new([type_a, type_b]) - end - else - # This can't be a `T.nilable()` case unless there are duplicates, - # which is possible but unexpected. - Union.new([type_a, type_b] + types) - end - end - end - end - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/untyped.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/untyped.rb deleted file mode 100644 index a06a633d42..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/types/untyped.rb +++ /dev/null @@ -1,29 +0,0 @@ -# frozen_string_literal: true -# typed: true - -module T::Types - # A dynamic type, which permits whatever - class Untyped < Base - - def initialize; end - - # overrides Base - def name - "T.untyped" - end - - # overrides Base - def valid?(obj) - true - end - - # overrides Base - private def subtype_of_single?(other) - true - end - - module Private - INSTANCE = Untyped.new.freeze - end - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/utils.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/utils.rb deleted file mode 100644 index 7897eaa38f..0000000000 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10132/lib/types/utils.rb +++ /dev/null @@ -1,209 +0,0 @@ -# frozen_string_literal: true -# typed: true - -module T::Utils - # Used to convert from a type specification to a `T::Types::Base`. - def self.coerce(val) - if val.is_a?(T::Private::Types::TypeAlias) - val.aliased_type - elsif val.is_a?(T::Types::Base) - val - elsif val.is_a?(Module) - T::Types::Simple::Private::Pool.type_for_module(val) - elsif val.is_a?(::Array) - T::Types::FixedArray.new(val) - elsif val.is_a?(::Hash) - T::Types::FixedHash.new(val) - elsif val.is_a?(T::Private::Methods::DeclBuilder) - T::Private::Methods.finalize_proc(val.decl) - elsif val.is_a?(::T::Enum) - T::Types::TEnum.new(val) - elsif val.is_a?(::String) - raise "Invalid String literal for type constraint. Must be an #{T::Types::Base}, a " \ - "class/module, or an array. Got a String with value `#{val}`." - else - raise "Invalid value for type constraint. Must be an #{T::Types::Base}, a " \ - "class/module, or an array. Got a `#{val.class}`." - end - end - - # Dynamically confirm that `value` is recursively a valid value of - # type `type`, including recursively through collections. Note that - # in some cases this runtime check can be very expensive, especially - # with large collections of objects. - def self.check_type_recursive!(value, type) - T::Private::Casts.cast_recursive(value, type, cast_method: "T.check_type_recursive!") - end - - # Returns the set of all methods (public, protected, private) defined on a module or its - # ancestors, excluding Object and its ancestors. Overrides of methods from Object (and its - # ancestors) are included. - def self.methods_excluding_object(mod) - # We can't just do mod.instance_methods - Object.instance_methods, because that would leave out - # any methods from Object that are overridden in mod. - mod.ancestors.flat_map do |ancestor| - # equivalent to checking Object.ancestors.include?(ancestor) - next [] if Object <= ancestor - ancestor.instance_methods(false) + ancestor.private_instance_methods(false) - end.uniq - end - - # Returns the signature for the `UnboundMethod`, or nil if it's not sig'd - # - # @example T::Utils.signature_for_method(x.method(:foo)) - def self.signature_for_method(method) - T::Private::Methods.signature_for_method(method) - end - - # Returns the signature for the instance method on the supplied module, or nil if it's not found or not typed. - # - # @example T::Utils.signature_for_instance_method(MyClass, :my_method) - def self.signature_for_instance_method(mod, method_name) - T::Private::Methods.signature_for_method(mod.instance_method(method_name)) - end - - def self.wrap_method_with_call_validation_if_needed(mod, method_sig, original_method) - T::Private::Methods::CallValidation.wrap_method_if_needed(mod, method_sig, original_method) - end - - # Unwraps all the sigs. - def self.run_all_sig_blocks - T::Private::Methods.run_all_sig_blocks - end - - # Return the underlying type for a type alias. Otherwise returns type. - def self.resolve_alias(type) - case type - when T::Private::Types::TypeAlias - type.aliased_type - else - type - end - end - - # Give a type which is a subclass of T::Types::Base, determines if the type is a simple nilable type (union of NilClass and something else). - # If so, returns the T::Types::Base of the something else. Otherwise, returns nil. - def self.unwrap_nilable(type) - case type - when T::Types::Union - non_nil_types = type.types.reject {|t| t == Nilable::NIL_TYPE} - return nil if type.types.length == non_nil_types.length - case non_nil_types.length - when 0 then nil - when 1 then non_nil_types.first - else - T::Types::Union::Private::Pool.union_of_types(non_nil_types[0], non_nil_types[1], non_nil_types[2..-1]) - end - else - nil - end - end - - # Returns the arity of a method, unwrapping the sig if needed - def self.arity(method) - arity = method.arity - return arity if arity != -1 || method.is_a?(Proc) - sig = T::Private::Methods.signature_for_method(method) - sig ? sig.method.arity : arity - end - - # Elide the middle of a string as needed and replace it with an ellipsis. - # Keep the given number of characters at the start and end of the string. - # - # This method operates on string length, not byte length. - # - # If the string is shorter than the requested truncation length, return it - # without adding an ellipsis. This method may return a longer string than - # the original if the characters removed are shorter than the ellipsis. - # - # @param [String] str - # - # @param [Fixnum] start_len The length of string before the ellipsis - # @param [Fixnum] end_len The length of string after the ellipsis - # - # @param [String] ellipsis The string to add in place of the elided text - # - # @return [String] - # - def self.string_truncate_middle(str, start_len, end_len, ellipsis='...') - return unless str - - raise ArgumentError.new('must provide start_len') unless start_len - raise ArgumentError.new('must provide end_len') unless end_len - - raise ArgumentError.new('start_len must be >= 0') if start_len < 0 - raise ArgumentError.new('end_len must be >= 0') if end_len < 0 - - str = str.to_s - return str if str.length <= start_len + end_len - - start_part = str[0...start_len - ellipsis.length] - end_part = end_len == 0 ? '' : str[-end_len..-1] - - "#{start_part}#{ellipsis}#{end_part}" - end - - def self.lift_enum(enum) - unless enum.is_a?(T::Types::Enum) - raise ArgumentError.new("#{enum.inspect} is not a T.deprecated_enum") - end - - classes = enum.values.map(&:class).uniq - if classes.empty? - T.untyped - elsif classes.length > 1 - T::Types::Union.new(classes) - else - T::Types::Simple::Private::Pool.type_for_module(classes.first) - end - end - - module Nilable - # :is_union_type, T::Boolean: whether the type is an T::Types::Union type - # :non_nilable_type, Class: if it is an T.nilable type, the corresponding underlying type; otherwise, nil. - TypeInfo = Struct.new(:is_union_type, :non_nilable_type) - - NIL_TYPE = T::Utils.coerce(NilClass) - - def self.get_type_info(prop_type) - if prop_type.is_a?(T::Types::Union) - non_nilable_type = T::Utils.unwrap_nilable(prop_type) - if non_nilable_type&.is_a?(T::Types::Simple) - non_nilable_type = non_nilable_type.raw_type - end - TypeInfo.new(true, non_nilable_type) - else - TypeInfo.new(false, nil) - end - end - - # Get the underlying type inside prop_type: - # - if the type is A, the function returns A - # - if the type is T.nilable(A), the function returns A - def self.get_underlying_type(prop_type) - type_info = get_type_info(prop_type) - if type_info.is_union_type - type_info.non_nilable_type || prop_type - elsif prop_type.is_a?(T::Types::Simple) - prop_type.raw_type - else - prop_type - end - end - - # The difference between this function and the above function is that the Sorbet type, like T::Types::Simple - # is preserved. - def self.get_underlying_type_object(prop_type) - T::Utils.unwrap_nilable(prop_type) || prop_type - end - - def self.is_union_with_nilclass(prop_type) - case prop_type - when T::Types::Union - prop_type.types.include?(NIL_TYPE) - else - false - end - end - end -end From 4a9942d7fc1fa78e5f68eba544a16ec191320552 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Wed, 27 Jul 2022 20:41:22 +0200 Subject: [PATCH 034/138] Removed cached submodule --- Library/Taps/homebrew/homebrew-core | 1 - 1 file changed, 1 deletion(-) delete mode 160000 Library/Taps/homebrew/homebrew-core diff --git a/Library/Taps/homebrew/homebrew-core b/Library/Taps/homebrew/homebrew-core deleted file mode 160000 index 65b3469d30..0000000000 --- a/Library/Taps/homebrew/homebrew-core +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 65b3469d300943210a42d69f75eae33faafd204c From 0b5a68ca9b85a39c0534dcb1459a2368afb41afd Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Wed, 27 Jul 2022 20:43:07 +0200 Subject: [PATCH 035/138] After `brew style --fix` for livecheck command --- Library/Homebrew/livecheck/livecheck.rb | 150 ++++++++++-------- .../Homebrew/livecheck/livecheck_version.rb | 4 +- 2 files changed, 85 insertions(+), 69 deletions(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index 131c03d332..dd9b8f846d 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -159,15 +159,15 @@ module Homebrew # `formulae_and_casks_to_check` array and prints the results. sig { params( - formulae_and_casks_to_check: T::Array[T.any(Formula, Cask::Cask)], - full_name: T::Boolean, - handle_name_conflict: T::Boolean, - check_resources: T::Boolean, - json: T::Boolean, - newer_only: T::Boolean, - debug: T::Boolean, - quiet: T::Boolean, - verbose: T::Boolean, + formulae_and_casks_to_check: T::Array[T.any(Formula, Cask::Cask)], + full_name: T::Boolean, + handle_name_conflict: T::Boolean, + check_resources: T::Boolean, + json: T::Boolean, + newer_only: T::Boolean, + debug: T::Boolean, + quiet: T::Boolean, + verbose: T::Boolean, ).void } def run_checks( @@ -291,23 +291,25 @@ module Homebrew # Only check current and latest versions if we have resources to check against if has_resources - current_resources = formula_or_cask.resources.map { |resource| { name: resource.name, version: resource.version, livecheckable: resource.livecheckable? } } + current_resources = formula_or_cask.resources.map do |resource| + { name: resource.name, version: resource.version, livecheckable: resource.livecheckable? } + end resource_version_info = resource_version( formula_or_cask, - json: json, + json: json, full_name: use_full_name, - verbose: verbose, - debug: debug + verbose: verbose, + debug: debug, ) - latest_resources = resource_version_info.map { |resource| { name: resource[:resource], version: resource[:version][:latest] } } - - else - # In case we don't have any resources for that Formula/Cask - if debug || verbose - onoe "No resources to check for '#{formula_or_cask_name(formula_or_cask, full_name: full_name)}'" + latest_resources = resource_version_info.map do |resource| + { name: resource[:resource], version: resource[:version][:latest] } end + + elsif debug || verbose + # In case we don't have any resources for that Formula/Cask + onoe "No resources to check for '#{formula_or_cask_name(formula_or_cask, full_name: full_name)}'" end end @@ -368,7 +370,7 @@ module Homebrew if check_resources && has_resources && debug puts <<~EOS - ---------- + ---------- EOS end @@ -377,11 +379,11 @@ module Homebrew if check_resources && has_resources resources_info = [] latest_resources_names = latest_resources.map { |r| r[:name] } - current_resources.each_with_index do |resource, i| + current_resources.each_with_index do |resource, _i| current = resource[:version] current_str = current.to_s latest = if latest_resources_names.include?(resource[:name].to_s) - res = latest_resources.detect { |r| r[:name].to_s == resource[:name].to_s } + res = latest_resources.find { |r| r[:name].to_s == resource[:name].to_s } res[:version] else current @@ -398,11 +400,12 @@ module Homebrew current: current_str, latest: latest_str, newer_than_upstream: is_newer_than_upstream, - outdated: is_outdated, + outdated: is_outdated, } resources_info << info end - print_latest_resource_version(resources_info, verbose: verbose, ambiguous_cask: ambiguous_casks.include?(formula_or_cask)) + print_latest_resource_version(resources_info, verbose: verbose, + ambiguous_cask: ambiguous_casks.include?(formula_or_cask)) end nil @@ -476,10 +479,10 @@ module Homebrew sig { params( package_or_resource: T.any(Formula, Cask::Cask, Resource), - status_str: String, - messages: T.nilable(T::Array[String]), - full_name: T::Boolean, - verbose: T::Boolean, + status_str: String, + messages: T.nilable(T::Array[String]), + full_name: T::Boolean, + verbose: T::Boolean, ).returns(Hash) } def status_hash(package_or_resource, status_str, messages = nil, full_name: false, verbose: false) @@ -509,7 +512,7 @@ module Homebrew # Formats and prints the livecheck result for a resource (for a given Formula or Cask). sig { params(resources_info: Array(Hash), verbose: T::Boolean, ambiguous_cask: T::Boolean).void } def print_latest_resource_version(resources_info, verbose:, ambiguous_cask: false) - resources_info.each_with_index do |info, i| + resources_info.each_with_index do |info, _i| resource_s = "#{Tty.blue}#{info[:resource]}#{Tty.reset}" resource_s += " (livecheckable)" if info[:livecheckable] && verbose @@ -553,7 +556,7 @@ module Homebrew sig { params( - livecheck_url: T.any(String, Symbol), + livecheck_url: T.any(String, Symbol), package_or_resource: T.any(Formula, Cask::Cask, Resource), ).returns(T.nilable(String)) } @@ -673,14 +676,15 @@ module Homebrew end # Identifies the latest version of the resources in a given Formulae/Casks and returns an Array of Hash containing - # the version information for all the resources. Returns an Array with nil value if a latest version couldn't be found for a given resource. + # the version information for all the resources. Returns an Array with nil value if a latest version + # couldn't be found for a given resource. sig { params( - formula_or_cask: T.any(Formula, Cask::Cask), - json: T::Boolean, - full_name: T::Boolean, - verbose: T::Boolean, - debug: T::Boolean, + formula_or_cask: T.any(Formula, Cask::Cask), + json: T::Boolean, + full_name: T::Boolean, + verbose: T::Boolean, + debug: T::Boolean, ).returns(Array(T.nilable(Hash))) } def resource_version( @@ -691,13 +695,13 @@ module Homebrew debug: false ) resources_version = [] - formula_or_cask.resources.each_with_index do |resource, i| + formula_or_cask.resources.each do |resource| has_livecheckable = resource.livecheckable? if debug puts <<~EOS - ---------- + ---------- EOS odebug "Resource: #{resource_name(resource, full_name: full_name)}" @@ -706,7 +710,7 @@ module Homebrew resource_version_info = { resource: resource_name(resource, full_name: full_name), - version: { + version: { current: resource.version, }, } @@ -774,21 +778,17 @@ module Homebrew next end end - next if strategy.blank? + homebrew_curl = case strategy_name when "PageMatch", "HeaderMatch" use_homebrew_curl?(resource, url) end puts "Homebrew curl?: Yes" if debug && homebrew_curl.present? - strategy_data = strategy.find_versions( - url: url, - regex: livecheck_regex, - homebrew_curl: homebrew_curl, - &livecheck_strategy_block + url: url, regex: livecheck_regex, + homebrew_curl: homebrew_curl, &livecheck_strategy_block ) - match_version_map = strategy_data[:matches] regex = strategy_data[:regex] messages = strategy_data[:messages] @@ -836,32 +836,46 @@ module Homebrew end end - resource_version_info[:version][:latest] = Version.new(match_version_map.values.max_by { |v| LivecheckVersion.create(resource, v) }) + resource_version_info[:version][:latest] = Version.new(match_version_map.values.max_by do |v| + LivecheckVersion.create(resource, v) + end) - if json && verbose - resource_version_info[:meta] = {} - resource_version_info[:meta][:livecheckable] = has_livecheckable ? "Yes" : "No" - if has_livecheckable - resource_version_info[:meta][:livecheck] = {} - resource_version_info[:meta][:livecheck][:url] = {} - resource_version_info[:meta][:livecheck][:url][:symbol] = livecheck_url if livecheck_url.is_a?(Symbol) && livecheck_url_string - if strategy_data[:url].present? && strategy_data[:url] != url - resource_version_info[:meta][:livecheck][:url][:strategy] = strategy_data[:url] - end - resource_version_info[:meta][:livecheck][:url][:final] = strategy_data[:final_url] if strategy_data[:final_url] - resource_version_info[:meta][:livecheck][:url][:homebrew_curl] = homebrew_curl if homebrew_curl.present? - resource_version_info[:meta][:livecheck][:strategy] = strategy.present? ? strategy_name : nil - resource_version_info[:meta][:livecheck][:strategies] = strategies.map { |s| livecheck_strategy_names[s] } if strategies.present? - resource_version_info[:meta][:livecheck][:regex] = regex.inspect if regex.present? - resource_version_info[:meta][:livecheck][:cached] = true if strategy_data[:cached] == true + next unless json && verbose + resource_version_info[:meta] = {} + resource_version_info[:meta][:livecheckable] = has_livecheckable ? "Yes" : "No" + if has_livecheckable + resource_version_info[:meta][:livecheck] = {} + resource_version_info[:meta][:livecheck][:url] = {} + if livecheck_url.is_a?(Symbol) && livecheck_url_string + resource_version_info[:meta][:livecheck][:url][:symbol] = + livecheck_url end - resource_version_info[:meta][:url] = {} - resource_version_info[:meta][:url][:original] = original_url - resource_version_info[:meta][:url][:processed] = url if url != original_url + if strategy_data[:url].present? && strategy_data[:url] != url + resource_version_info[:meta][:livecheck][:url][:strategy] = strategy_data[:url] + end + if strategy_data[:final_url] + resource_version_info[:meta][:livecheck][:url][:final] = + strategy_data[:final_url] + end + if homebrew_curl.present? + resource_version_info[:meta][:livecheck][:url][:homebrew_curl] = + homebrew_curl + end + resource_version_info[:meta][:livecheck][:strategy] = strategy.present? ? strategy_name : nil + if strategies.present? + resource_version_info[:meta][:livecheck][:strategies] = strategies.map do |s| + livecheck_strategy_names[s] + end + end + resource_version_info[:meta][:livecheck][:regex] = regex.inspect if regex.present? + resource_version_info[:meta][:livecheck][:cached] = true if strategy_data[:cached] == true + end + resource_version_info[:meta][:url] = {} + resource_version_info[:meta][:url][:original] = original_url + resource_version_info[:meta][:url][:processed] = url if url != original_url end - resources_version << resource_version_info else # If there's no livecheck block in resource resource_version_info[:version][:latest] = resource.version @@ -869,8 +883,8 @@ module Homebrew resource_version_info[:meta] = {} resource_version_info[:meta][:url] = resource.url.to_s end - resources_version << resource_version_info end + resources_version << resource_version_info end resources_version end diff --git a/Library/Homebrew/livecheck/livecheck_version.rb b/Library/Homebrew/livecheck/livecheck_version.rb index f1b722ed49..c0753cc4b2 100644 --- a/Library/Homebrew/livecheck/livecheck_version.rb +++ b/Library/Homebrew/livecheck/livecheck_version.rb @@ -11,7 +11,9 @@ module Homebrew include Comparable - sig { params(package_or_resource: T.any(Formula, Cask::Cask, Resource), version: Version).returns(LivecheckVersion) } + sig { + params(package_or_resource: T.any(Formula, Cask::Cask, Resource), version: Version).returns(LivecheckVersion) + } def self.create(package_or_resource, version) versions = case package_or_resource when Resource From 825707a219faed0098353ecc3405ee99956f9bad Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Wed, 27 Jul 2022 20:54:28 +0200 Subject: [PATCH 036/138] Refactored a bit --- Library/Homebrew/dev-cmd/livecheck.rb | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Library/Homebrew/dev-cmd/livecheck.rb b/Library/Homebrew/dev-cmd/livecheck.rb index 966cd75a4f..dc080605a7 100644 --- a/Library/Homebrew/dev-cmd/livecheck.rb +++ b/Library/Homebrew/dev-cmd/livecheck.rb @@ -60,7 +60,7 @@ module Homebrew puts Homebrew::EnvConfig.livecheck_watchlist if Homebrew::EnvConfig.livecheck_watchlist.present? end - package_and_resource_to_check = if args.tap + formulae_and_casks_to_check = if args.tap tap = Tap.fetch(args.tap) formulae = args.cask? ? [] : tap.formula_files.map { |path| Formulary.factory(path) } casks = args.formula? ? [] : tap.cask_files.map { |path| Cask::CaskLoader.load(path) } @@ -96,11 +96,11 @@ module Homebrew raise UsageError, "A watchlist file is required when no arguments are given." end - package_and_resource_to_check = package_and_resource_to_check.sort_by do |package_or_resource| - package_or_resource.respond_to?(:token) ? package_or_resource.token : package_or_resource.name + formulae_and_casks_to_check = formulae_and_casks_to_check.sort_by do |formula_or_cask| + formula_or_cask.respond_to?(:token) ? formula_or_cask.token : formula_or_cask.name end - raise UsageError, "No formulae or casks to check." if package_and_resource_to_check.blank? + raise UsageError, "No formulae or casks to check." if formulae_and_casks_to_check.blank? options = { json: args.json?, @@ -113,6 +113,6 @@ module Homebrew verbose: args.verbose?, }.compact - Livecheck.run_checks(package_and_resource_to_check, **options) + Livecheck.run_checks(formulae_and_casks_to_check, **options) end end From 806f0be69af9d03c97e897c8918e86b45b572abb Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Wed, 27 Jul 2022 21:28:28 +0200 Subject: [PATCH 037/138] Refactoring in progress --- Library/Homebrew/livecheck/livecheck.rb | 383 ++++++++++++------------ 1 file changed, 190 insertions(+), 193 deletions(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index dd9b8f846d..46053f062b 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -367,13 +367,13 @@ module Homebrew next info end - if check_resources && has_resources && debug - puts <<~EOS + # if check_resources && has_resources && debug + # puts <<~EOS - ---------- + # ---------- - EOS - end + # EOS + # end print_latest_version(info, verbose: verbose, ambiguous_cask: ambiguous_casks.include?(formula_or_cask)) if check_resources && has_resources @@ -404,8 +404,11 @@ module Homebrew } resources_info << info end - print_latest_resource_version(resources_info, verbose: verbose, - ambiguous_cask: ambiguous_casks.include?(formula_or_cask)) + print_latest_resource_version( + resources_info, + verbose: verbose, + ambiguous_cask: ambiguous_casks.include?(formula_or_cask) + ) end nil @@ -675,218 +678,212 @@ module Homebrew homebrew_curl_root_domains.include?(url_root_domain) end - # Identifies the latest version of the resources in a given Formulae/Casks and returns an Array of Hash containing - # the version information for all the resources. Returns an Array with nil value if a latest version + # Identifies the latest version of the resource in a given Formulae/Casks and returns a Hash containing + # the version information for a resource. Returns a nil value if a latest version # couldn't be found for a given resource. sig { params( - formula_or_cask: T.any(Formula, Cask::Cask), - json: T::Boolean, - full_name: T::Boolean, - verbose: T::Boolean, - debug: T::Boolean, - ).returns(Array(T.nilable(Hash))) + resource: T.any(Resource), + json: T::Boolean, + full_name: T::Boolean, + verbose: T::Boolean, + debug: T::Boolean, + ).returns(T.nilable(Hash)) } def resource_version( - formula_or_cask, + resource, json: false, full_name: false, verbose: false, debug: false ) - resources_version = [] - formula_or_cask.resources.each do |resource| - has_livecheckable = resource.livecheckable? + has_livecheckable = resource.livecheckable? - if debug - puts <<~EOS + if debug + puts <<~EOS - ---------- + EOS + odebug "Resource: #{resource_name(resource, full_name: full_name)}" + odebug "Livecheckable?: #{has_livecheckable ? "Yes" : "No"}" + end - EOS - odebug "Resource: #{resource_name(resource, full_name: full_name)}" - odebug "Livecheckable?: #{has_livecheckable ? "Yes" : "No"}" - end + resource_version_info = { + resource: resource_name(resource, full_name: full_name), + version: { + current: resource.version, + }, + } - resource_version_info = { - resource: resource_name(resource, full_name: full_name), - version: { - current: resource.version, - }, - } + # Check resources with livecheck block (will be updated in the future) + if has_livecheckable + livecheck = resource.livecheck + livecheck_url = livecheck.url + livecheck_regex = livecheck.regex + livecheck_strategy = livecheck.strategy + livecheck_strategy_block = livecheck.strategy_block - # Check resources with livecheck block (will be updated in the future) - if has_livecheckable - livecheck = resource.livecheck - livecheck_url = livecheck.url - livecheck_regex = livecheck.regex - livecheck_strategy = livecheck.strategy - livecheck_strategy_block = livecheck.strategy_block + livecheck_url_string = livecheck_url_to_string( + livecheck_url, + resource, + ) - livecheck_url_string = livecheck_url_to_string( - livecheck_url, - resource, + urls = [livecheck_url_string] if livecheck_url_string + urls ||= checkable_urls(resource) + + checked_urls = [] + + urls.each_with_index do |original_url, i| + # Only preprocess the URL when it's appropriate + url = if STRATEGY_SYMBOLS_TO_SKIP_PREPROCESS_URL.include?(livecheck_strategy) + original_url + else + preprocess_url(original_url) + end + next if checked_urls.include?(url) + + strategies = Strategy.from_url( + url, + livecheck_strategy: livecheck_strategy, + url_provided: livecheck_url.present?, + regex_provided: livecheck_regex.present?, + block_provided: livecheck_strategy_block.present?, ) - urls = [livecheck_url_string] if livecheck_url_string - urls ||= checkable_urls(resource) + strategy = Strategy.from_symbol(livecheck_strategy) || strategies.first + strategy_name = livecheck_strategy_names[strategy] - checked_urls = [] - - urls.each_with_index do |original_url, i| - # Only preprocess the URL when it's appropriate - url = if STRATEGY_SYMBOLS_TO_SKIP_PREPROCESS_URL.include?(livecheck_strategy) - original_url + if debug + puts + if livecheck_url.is_a?(Symbol) + # This assumes the URL symbol will fit within the available space + puts "URL (#{livecheck_url}):".ljust(18, " ") + original_url else - preprocess_url(original_url) + puts "URL: #{original_url}" end - next if checked_urls.include?(url) - - strategies = Strategy.from_url( - url, - livecheck_strategy: livecheck_strategy, - url_provided: livecheck_url.present?, - regex_provided: livecheck_regex.present?, - block_provided: livecheck_strategy_block.present?, - ) - - strategy = Strategy.from_symbol(livecheck_strategy) || strategies.first - strategy_name = livecheck_strategy_names[strategy] - - if debug - puts - if livecheck_url.is_a?(Symbol) - # This assumes the URL symbol will fit within the available space - puts "URL (#{livecheck_url}):".ljust(18, " ") + original_url - else - puts "URL: #{original_url}" - end - puts "URL (processed): #{url}" if url != original_url - if strategies.present? && verbose - puts "Strategies: #{strategies.map { |s| livecheck_strategy_names[s] }.join(", ")}" - end - puts "Strategy: #{strategy.blank? ? "None" : strategy_name}" - puts "Regex: #{livecheck_regex.inspect}" if livecheck_regex.present? + puts "URL (processed): #{url}" if url != original_url + if strategies.present? && verbose + puts "Strategies: #{strategies.map { |s| livecheck_strategy_names[s] }.join(", ")}" end - - if livecheck_strategy.present? - if livecheck_url.blank? && strategy.method(:find_versions).parameters.include?([:keyreq, :url]) - odebug "#{strategy_name} strategy requires a URL" - next - elsif livecheck_strategy != :page_match && strategies.exclude?(strategy) - odebug "#{strategy_name} strategy does not apply to this URL" - next - end - end - next if strategy.blank? - - homebrew_curl = case strategy_name - when "PageMatch", "HeaderMatch" - use_homebrew_curl?(resource, url) - end - puts "Homebrew curl?: Yes" if debug && homebrew_curl.present? - strategy_data = strategy.find_versions( - url: url, regex: livecheck_regex, - homebrew_curl: homebrew_curl, &livecheck_strategy_block - ) - match_version_map = strategy_data[:matches] - regex = strategy_data[:regex] - messages = strategy_data[:messages] - checked_urls << url - - if messages.is_a?(Array) && match_version_map.blank? - puts messages unless json - next if i + 1 < urls.length - - return status_hash(resource, "error", messages, full_name: full_name, verbose: verbose) - end - - if debug - if strategy_data[:url].present? && strategy_data[:url] != url - puts "URL (strategy): #{strategy_data[:url]}" - end - puts "URL (final): #{strategy_data[:final_url]}" if strategy_data[:final_url].present? - if strategy_data[:regex].present? && strategy_data[:regex] != livecheck_regex - puts "Regex (strategy): #{strategy_data[:regex].inspect}" - end - puts "Cached?: Yes" if strategy_data[:cached] == true - end - - match_version_map.delete_if do |_match, version| - next true if version.blank? - next false if has_livecheckable - - UNSTABLE_VERSION_KEYWORDS.any? do |rejection| - version.to_s.include?(rejection) - end - end - - next if match_version_map.blank? - - if debug - puts - puts "Matched Versions:" - - if verbose - match_version_map.each do |match, version| - puts "#{match} => #{version.inspect}" - end - else - puts match_version_map.values.join(", ") - end - end - - resource_version_info[:version][:latest] = Version.new(match_version_map.values.max_by do |v| - LivecheckVersion.create(resource, v) - end) - - next unless json && verbose - - resource_version_info[:meta] = {} - resource_version_info[:meta][:livecheckable] = has_livecheckable ? "Yes" : "No" - if has_livecheckable - resource_version_info[:meta][:livecheck] = {} - resource_version_info[:meta][:livecheck][:url] = {} - if livecheck_url.is_a?(Symbol) && livecheck_url_string - resource_version_info[:meta][:livecheck][:url][:symbol] = - livecheck_url - end - if strategy_data[:url].present? && strategy_data[:url] != url - resource_version_info[:meta][:livecheck][:url][:strategy] = strategy_data[:url] - end - if strategy_data[:final_url] - resource_version_info[:meta][:livecheck][:url][:final] = - strategy_data[:final_url] - end - if homebrew_curl.present? - resource_version_info[:meta][:livecheck][:url][:homebrew_curl] = - homebrew_curl - end - resource_version_info[:meta][:livecheck][:strategy] = strategy.present? ? strategy_name : nil - if strategies.present? - resource_version_info[:meta][:livecheck][:strategies] = strategies.map do |s| - livecheck_strategy_names[s] - end - end - resource_version_info[:meta][:livecheck][:regex] = regex.inspect if regex.present? - resource_version_info[:meta][:livecheck][:cached] = true if strategy_data[:cached] == true - - end - resource_version_info[:meta][:url] = {} - resource_version_info[:meta][:url][:original] = original_url - resource_version_info[:meta][:url][:processed] = url if url != original_url + puts "Strategy: #{strategy.blank? ? "None" : strategy_name}" + puts "Regex: #{livecheck_regex.inspect}" if livecheck_regex.present? end - else - # If there's no livecheck block in resource - resource_version_info[:version][:latest] = resource.version - if json && verbose - resource_version_info[:meta] = {} - resource_version_info[:meta][:url] = resource.url.to_s + + if livecheck_strategy.present? + if livecheck_url.blank? && strategy.method(:find_versions).parameters.include?([:keyreq, :url]) + odebug "#{strategy_name} strategy requires a URL" + next + elsif livecheck_strategy != :page_match && strategies.exclude?(strategy) + odebug "#{strategy_name} strategy does not apply to this URL" + next + end end + next if strategy.blank? + + homebrew_curl = case strategy_name + when "PageMatch", "HeaderMatch" + use_homebrew_curl?(resource, url) + end + puts "Homebrew curl?: Yes" if debug && homebrew_curl.present? + strategy_data = strategy.find_versions( + url: url, regex: livecheck_regex, + homebrew_curl: homebrew_curl, &livecheck_strategy_block + ) + match_version_map = strategy_data[:matches] + regex = strategy_data[:regex] + messages = strategy_data[:messages] + checked_urls << url + + if messages.is_a?(Array) && match_version_map.blank? + puts messages unless json + next if i + 1 < urls.length + + return status_hash(resource, "error", messages, full_name: full_name, verbose: verbose) + end + + if debug + if strategy_data[:url].present? && strategy_data[:url] != url + puts "URL (strategy): #{strategy_data[:url]}" + end + puts "URL (final): #{strategy_data[:final_url]}" if strategy_data[:final_url].present? + if strategy_data[:regex].present? && strategy_data[:regex] != livecheck_regex + puts "Regex (strategy): #{strategy_data[:regex].inspect}" + end + puts "Cached?: Yes" if strategy_data[:cached] == true + end + + match_version_map.delete_if do |_match, version| + next true if version.blank? + next false if has_livecheckable + + UNSTABLE_VERSION_KEYWORDS.any? do |rejection| + version.to_s.include?(rejection) + end + end + + next if match_version_map.blank? + + if debug + puts + puts "Matched Versions:" + + if verbose + match_version_map.each do |match, version| + puts "#{match} => #{version.inspect}" + end + else + puts match_version_map.values.join(", ") + end + end + + resource_version_info[:version][:latest] = Version.new(match_version_map.values.max_by do |v| + LivecheckVersion.create(resource, v) + end) + + next unless json + + resource_version_info[:meta] = {} + resource_version_info[:meta][:livecheckable] = has_livecheckable ? "Yes" : "No" + if has_livecheckable + resource_version_info[:meta][:livecheck] = {} + resource_version_info[:meta][:livecheck][:url] = {} + if livecheck_url.is_a?(Symbol) && livecheck_url_string + resource_version_info[:meta][:livecheck][:url][:symbol] = + livecheck_url + end + if strategy_data[:url].present? && strategy_data[:url] != url + resource_version_info[:meta][:livecheck][:url][:strategy] = strategy_data[:url] + end + if strategy_data[:final_url] + resource_version_info[:meta][:livecheck][:url][:final] = + strategy_data[:final_url] + end + if homebrew_curl.present? + resource_version_info[:meta][:livecheck][:url][:homebrew_curl] = + homebrew_curl + end + resource_version_info[:meta][:livecheck][:strategy] = strategy.present? ? strategy_name : nil + if strategies.present? + resource_version_info[:meta][:livecheck][:strategies] = strategies.map do |s| + livecheck_strategy_names[s] + end + end + resource_version_info[:meta][:livecheck][:regex] = regex.inspect if regex.present? + resource_version_info[:meta][:livecheck][:cached] = true if strategy_data[:cached] == true + + end + resource_version_info[:meta][:url] = {} + resource_version_info[:meta][:url][:original] = original_url + resource_version_info[:meta][:url][:processed] = url if url != original_url + end + else + # If there's no livecheck block in resource + resource_version_info[:version][:latest] = resource.version + if json && verbose + resource_version_info[:meta] = {} + resource_version_info[:meta][:url] = resource.url.to_s end - resources_version << resource_version_info end - resources_version + resource_version_info end # Identifies the latest version of the formula and returns a Hash containing From eb2dcf7ea97b864c88a3f7e11a412b8d9a369a48 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Sun, 31 Jul 2022 12:29:20 +0500 Subject: [PATCH 038/138] Update livecheck command: Casks don't have resource blocks Co-authored-by: Nanda H Krishna --- Library/Homebrew/dev-cmd/livecheck.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Library/Homebrew/dev-cmd/livecheck.rb b/Library/Homebrew/dev-cmd/livecheck.rb index dc080605a7..9fa4c9bcc5 100644 --- a/Library/Homebrew/dev-cmd/livecheck.rb +++ b/Library/Homebrew/dev-cmd/livecheck.rb @@ -36,7 +36,7 @@ module Homebrew switch "--json", description: "Output information in JSON format." switch "-r", "--resources", - description: "Check resources with livecheck blocks for a given formulae/casks." + description: "Also check resources for formulae." switch "-q", "--quiet", description: "Suppress warnings, don't print a progress bar for JSON output." switch "--formula", "--formulae", From 6ec81ac31ce270a75ec81a6240db4721c73d9145 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Sun, 31 Jul 2022 09:33:01 +0200 Subject: [PATCH 039/138] No need to show that no resources exists for formulae --- Library/Homebrew/livecheck/livecheck.rb | 5 ----- 1 file changed, 5 deletions(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index 46053f062b..d2976bff3c 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -306,11 +306,6 @@ module Homebrew latest_resources = resource_version_info.map do |resource| { name: resource[:resource], version: resource[:version][:latest] } end - - elsif debug || verbose - # In case we don't have any resources for that Formula/Cask - onoe "No resources to check for '#{formula_or_cask_name(formula_or_cask, full_name: full_name)}'" - end end if latest.blank? From 5beb7c177214e4e5774c4318c5f79a8bde39342a Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Sun, 31 Jul 2022 09:35:41 +0200 Subject: [PATCH 040/138] Simplified check resources' condition for Formulae --- Library/Homebrew/livecheck/livecheck.rb | 33 +++++++++++-------------- 1 file changed, 14 insertions(+), 19 deletions(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index d2976bff3c..4bdceab01b 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -284,28 +284,23 @@ module Homebrew end # Check current and latest resources (if "--resources" flag is given) - if check_resources + # Only check current and latest versions if we have resources to check against + if check_resources && formula_or_cask.resources.present? + current_resources = formula_or_cask.resources.map do |resource| + { name: resource.name, version: resource.version, livecheckable: resource.livecheckable? } + end - has_resources = formula_or_cask.resources.any? + resource_version_info = resource_version( + formula_or_cask, + json: json, + full_name: use_full_name, + verbose: verbose, + debug: debug, + ) - # Only check current and latest versions if we have resources to check against - if has_resources + latest_resources = resource_version_info.map do |resource| + { name: resource[:resource], version: resource[:version][:latest] } - current_resources = formula_or_cask.resources.map do |resource| - { name: resource.name, version: resource.version, livecheckable: resource.livecheckable? } - end - - resource_version_info = resource_version( - formula_or_cask, - json: json, - full_name: use_full_name, - verbose: verbose, - debug: debug, - ) - - latest_resources = resource_version_info.map do |resource| - { name: resource[:resource], version: resource[:version][:latest] } - end end if latest.blank? From fe94bfb0f1693a40454f23c448f63f8db360cb6d Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Sun, 31 Jul 2022 12:38:00 +0500 Subject: [PATCH 041/138] Updated livecheck_version Co-authored-by: Nanda H Krishna --- Library/Homebrew/livecheck/livecheck_version.rb | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Library/Homebrew/livecheck/livecheck_version.rb b/Library/Homebrew/livecheck/livecheck_version.rb index c0753cc4b2..ba557cf4ad 100644 --- a/Library/Homebrew/livecheck/livecheck_version.rb +++ b/Library/Homebrew/livecheck/livecheck_version.rb @@ -16,9 +16,7 @@ module Homebrew } def self.create(package_or_resource, version) versions = case package_or_resource - when Resource - [version] - when Formula + when Formula, Resource [version] when Cask::Cask version.to_s.split(/[,:]/).map { |s| Version.new(s) } From c074e8c020b5edc911f8034893130ebdb5c2c2a5 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Sun, 31 Jul 2022 12:38:40 +0500 Subject: [PATCH 042/138] Aligned output with the existing style seen in #latest_version Co-authored-by: Sam Ford <1584702+samford@users.noreply.github.com> --- Library/Homebrew/livecheck/livecheck.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index 4bdceab01b..484eefbf58 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -693,8 +693,8 @@ module Homebrew puts <<~EOS EOS - odebug "Resource: #{resource_name(resource, full_name: full_name)}" - odebug "Livecheckable?: #{has_livecheckable ? "Yes" : "No"}" + puts "Resource: #{resource_name(resource, full_name: full_name)}" + puts "Livecheckable?: #{has_livecheckable ? "Yes" : "No"}" end resource_version_info = { From 4088c4683e3a38250e12e226a88ff9fef58dd3ed Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Sun, 31 Jul 2022 12:39:23 +0500 Subject: [PATCH 043/138] Indenting resources by two spaces Co-authored-by: Sam Ford <1584702+samford@users.noreply.github.com> --- Library/Homebrew/livecheck/livecheck.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index 484eefbf58..16b4ca54e3 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -521,7 +521,7 @@ module Homebrew info[:version][:latest] end - puts "-- #{resource_s}: #{current_s} ==> #{latest_s}" + puts " #{resource_s}: #{current_s} ==> #{latest_s}" end end From 40bbbd601eca738725e192dd638cbc1e868b7171 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Sun, 31 Jul 2022 09:49:19 +0200 Subject: [PATCH 044/138] Refractored `resource_version` to work for a single resource --- Library/Homebrew/livecheck/livecheck.rb | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index 16b4ca54e3..50813756ce 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -290,17 +290,20 @@ module Homebrew { name: resource.name, version: resource.version, livecheckable: resource.livecheckable? } end - resource_version_info = resource_version( - formula_or_cask, - json: json, - full_name: use_full_name, - verbose: verbose, - debug: debug, - ) + resource_version_info = formula_or_cask.resources.map do |resource| + resource_info = resource_version( + resource, + json: json, + full_name: use_full_name, + verbose: verbose, + debug: debug, + ) + resource_info + end latest_resources = resource_version_info.map do |resource| { name: resource[:resource], version: resource[:version][:latest] } - + end end if latest.blank? From 4f8f852fbc86112ba5a8d7255bcda06e7a20cee5 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Sun, 31 Jul 2022 10:08:39 +0200 Subject: [PATCH 045/138] Refactored `print_latest_version` for resources as well --- Library/Homebrew/livecheck/livecheck.rb | 27 ++++++++++--------------- 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index 50813756ce..31a629dfd9 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -360,19 +360,12 @@ module Homebrew next info end - # if check_resources && has_resources && debug - # puts <<~EOS - - # ---------- - - # EOS - # end print_latest_version(info, verbose: verbose, ambiguous_cask: ambiguous_casks.include?(formula_or_cask)) - if check_resources && has_resources + if check_resources && formula_or_cask.resources.present? resources_info = [] latest_resources_names = latest_resources.map { |r| r[:name] } - current_resources.each_with_index do |resource, _i| + current_resources.each_with_index do |resource| current = resource[:version] current_str = current.to_s latest = if latest_resources_names.include?(resource[:name].to_s) @@ -528,12 +521,14 @@ module Homebrew end end - # Formats and prints the livecheck result for a formula. - sig { params(info: Hash, verbose: T::Boolean, ambiguous_cask: T::Boolean).void } - def print_latest_version(info, verbose:, ambiguous_cask: false) - formula_or_cask_s = "#{Tty.blue}#{info[:formula] || info[:cask]}#{Tty.reset}" - formula_or_cask_s += " (cask)" if ambiguous_cask - formula_or_cask_s += " (guessed)" if !info[:meta][:livecheckable] && verbose + # Formats and prints the livecheck result for a formula/cask/resource. + sig { params(info: Hash, verbose: T::Boolean, ambiguous_cask: T::Boolean, check_resource: T::Boolean).void } + def print_latest_version(info, verbose:, ambiguous_cask: false, check_resource: false) + package_or_resource_s = " " if check_resource + package_or_resource_s += "#{Tty.blue}#{info[:formula] || info[:cask] || info[:resource]}#{Tty.reset}" + package_or_resource_s += " (cask)" if ambiguous_cask && !check_resource + package_or_resource_s += " (guessed)" if !info[:meta][:livecheckable] && !check_resource && verbose + package_or_resource_s += " (livecheckable)" if check_resource && info[:livecheckable] && verbose current_s = if info[:version][:newer_than_upstream] "#{Tty.red}#{info[:version][:current]}#{Tty.reset}" @@ -547,7 +542,7 @@ module Homebrew info[:version][:latest] end - puts "#{formula_or_cask_s}: #{current_s} ==> #{latest_s}" + puts "#{package_or_resource_s}: #{current_s} ==> #{latest_s}" end sig { From 4de65099060a613a37bde2c225d419ef0981cbf6 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Sun, 31 Jul 2022 10:09:20 +0200 Subject: [PATCH 046/138] Removed `print_latest_resource_version` --- Library/Homebrew/livecheck/livecheck.rb | 23 ----------------------- 1 file changed, 23 deletions(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index 31a629dfd9..eabd984ab8 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -498,29 +498,6 @@ module Homebrew status_hash end - # Formats and prints the livecheck result for a resource (for a given Formula or Cask). - sig { params(resources_info: Array(Hash), verbose: T::Boolean, ambiguous_cask: T::Boolean).void } - def print_latest_resource_version(resources_info, verbose:, ambiguous_cask: false) - resources_info.each_with_index do |info, _i| - resource_s = "#{Tty.blue}#{info[:resource]}#{Tty.reset}" - resource_s += " (livecheckable)" if info[:livecheckable] && verbose - - current_s = if info[:version][:newer_than_upstream] - "#{Tty.red}#{info[:version][:current]}#{Tty.reset}" - else - info[:version][:current] - end - - latest_s = if info[:version][:outdated] - "#{Tty.green}#{info[:version][:latest]}#{Tty.reset}" - else - info[:version][:latest] - end - - puts " #{resource_s}: #{current_s} ==> #{latest_s}" - end - end - # Formats and prints the livecheck result for a formula/cask/resource. sig { params(info: Hash, verbose: T::Boolean, ambiguous_cask: T::Boolean, check_resource: T::Boolean).void } def print_latest_version(info, verbose:, ambiguous_cask: false, check_resource: false) From ce202dc61c5924c1b5257c7bf3b6aa577095f61b Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Sun, 31 Jul 2022 10:17:15 +0200 Subject: [PATCH 047/138] Updated livecheck: Refactored for resources' output --- Library/Homebrew/livecheck/livecheck.rb | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index eabd984ab8..2372ef13e3 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -360,12 +360,12 @@ module Homebrew next info end - print_latest_version(info, verbose: verbose, ambiguous_cask: ambiguous_casks.include?(formula_or_cask)) + print_latest_version(info, verbose: verbose, ambiguous_cask: ambiguous_casks.include?(formula_or_cask), check_resource: false) if check_resources && formula_or_cask.resources.present? resources_info = [] latest_resources_names = latest_resources.map { |r| r[:name] } - current_resources.each_with_index do |resource| + current_resources.each do |resource| current = resource[:version] current_str = current.to_s latest = if latest_resources_names.include?(resource[:name].to_s) @@ -390,11 +390,14 @@ module Homebrew } resources_info << info end - print_latest_resource_version( - resources_info, - verbose: verbose, - ambiguous_cask: ambiguous_casks.include?(formula_or_cask) - ) + resources_info.each do |info| + print_latest_version( + info, + verbose: verbose, + ambiguous_cask: ambiguous_casks.include?(formula_or_cask), + check_resource: true, + ) + end end nil @@ -535,10 +538,8 @@ module Homebrew when :url package_or_resource.url&.to_s if package_or_resource.is_a?(Cask::Cask) || package_or_resource.is_a?(Resource) when :head, :stable - # Resource's "url" is considered "stable" by default. And some resources may contain in "head" block as well + # Since resource's "url" is considered "stable" by default. And some resources may contain in "head" block as well package_or_resource.send(:url)&.to_s if package_or_resource.is_a?(Resource) - # Not sure how to handle this ? - # Do I have to add :stable / :head in Resources' as well (like it's being implemented in Formula ?) package_or_resource.send(livecheck_url)&.url if package_or_resource.is_a?(Formula) when :homepage package_or_resource.homepage From b651fe475cf92475be66f5fe5129297dbbc084a9 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Sun, 31 Jul 2022 10:24:55 +0200 Subject: [PATCH 048/138] Added `newer_than_upstream` and `outdated` in resource info --- Library/Homebrew/livecheck/livecheck.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index 2372ef13e3..94a6b3ed1f 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -849,6 +849,8 @@ module Homebrew resource_version_info[:meta][:url] = resource.url.to_s end end + resource_version_info[:version][:newer_than_upstream] = resource_version_info[:version][:current] > resource_version_info[:version][:latest] + resource_version_info[:version][:outdated] = resource_version_info[:version][:current] < resource_version_info[:version][:latest] resource_version_info end From 6daa22bc8ee1d6353bb80a54042dcb5fb4b3a1b2 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Mon, 1 Aug 2022 23:34:53 +0200 Subject: [PATCH 049/138] Fixed issue with `print_latest_version` --- Library/Homebrew/livecheck/livecheck.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index 94a6b3ed1f..bf66457896 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -504,7 +504,7 @@ module Homebrew # Formats and prints the livecheck result for a formula/cask/resource. sig { params(info: Hash, verbose: T::Boolean, ambiguous_cask: T::Boolean, check_resource: T::Boolean).void } def print_latest_version(info, verbose:, ambiguous_cask: false, check_resource: false) - package_or_resource_s = " " if check_resource + package_or_resource_s = check_resource ? " " : "" package_or_resource_s += "#{Tty.blue}#{info[:formula] || info[:cask] || info[:resource]}#{Tty.reset}" package_or_resource_s += " (cask)" if ambiguous_cask && !check_resource package_or_resource_s += " (guessed)" if !info[:meta][:livecheckable] && !check_resource && verbose From e718318eaf094fcd3c80b1b2863dc9d11b9d5950 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Mon, 1 Aug 2022 23:50:18 +0200 Subject: [PATCH 050/138] Fixed issue with info[:meta] for resources --- Library/Homebrew/livecheck/livecheck.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index bf66457896..26e5b75844 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -381,7 +381,7 @@ module Homebrew info = {} info[:resource] = resource[:name] - info[:livecheckable] = resource[:livecheckable] + info[:meta] = { livecheckable: resource[:livecheckable], } info[:version] = { current: current_str, latest: latest_str, @@ -508,7 +508,7 @@ module Homebrew package_or_resource_s += "#{Tty.blue}#{info[:formula] || info[:cask] || info[:resource]}#{Tty.reset}" package_or_resource_s += " (cask)" if ambiguous_cask && !check_resource package_or_resource_s += " (guessed)" if !info[:meta][:livecheckable] && !check_resource && verbose - package_or_resource_s += " (livecheckable)" if check_resource && info[:livecheckable] && verbose + package_or_resource_s += " (livecheckable)" if check_resource && info[:meta][:livecheckable] && verbose current_s = if info[:version][:newer_than_upstream] "#{Tty.red}#{info[:version][:current]}#{Tty.reset}" From 9c4b9b7e147fdee27d3bdb1d28be79e87084e8b4 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Tue, 2 Aug 2022 00:27:53 +0200 Subject: [PATCH 051/138] Refactored a bit + `brew style --fix` --- Library/Homebrew/livecheck/livecheck.rb | 48 +++++++++++-------------- 1 file changed, 20 insertions(+), 28 deletions(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index 26e5b75844..686c0be5ff 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -293,10 +293,10 @@ module Homebrew resource_version_info = formula_or_cask.resources.map do |resource| resource_info = resource_version( resource, - json: json, + json: json, full_name: use_full_name, - verbose: verbose, - debug: debug, + verbose: verbose, + debug: debug, ) resource_info end @@ -360,7 +360,8 @@ module Homebrew next info end - print_latest_version(info, verbose: verbose, ambiguous_cask: ambiguous_casks.include?(formula_or_cask), check_resource: false) + print_latest_version(info, verbose: verbose, ambiguous_cask: ambiguous_casks.include?(formula_or_cask), +check_resource: false) if check_resources && formula_or_cask.resources.present? resources_info = [] @@ -381,7 +382,7 @@ module Homebrew info = {} info[:resource] = resource[:name] - info[:meta] = { livecheckable: resource[:livecheckable], } + info[:meta] = { livecheckable: resource[:livecheckable] } info[:version] = { current: current_str, latest: latest_str, @@ -390,10 +391,10 @@ module Homebrew } resources_info << info end - resources_info.each do |info| + resources_info.each do |r_info| print_latest_version( - info, - verbose: verbose, + r_info, + verbose: verbose, ambiguous_cask: ambiguous_casks.include?(formula_or_cask), check_resource: true, ) @@ -538,7 +539,8 @@ module Homebrew when :url package_or_resource.url&.to_s if package_or_resource.is_a?(Cask::Cask) || package_or_resource.is_a?(Resource) when :head, :stable - # Since resource's "url" is considered "stable" by default. And some resources may contain in "head" block as well + # Since resource's "url" is considered "stable" by default. + # And some resources may contain in "head" block as well package_or_resource.send(:url)&.to_s if package_or_resource.is_a?(Resource) package_or_resource.send(livecheck_url)&.url if package_or_resource.is_a?(Formula) when :homepage @@ -785,7 +787,6 @@ module Homebrew version.to_s.include?(rejection) end end - next if match_version_map.blank? if debug @@ -804,14 +805,11 @@ module Homebrew resource_version_info[:version][:latest] = Version.new(match_version_map.values.max_by do |v| LivecheckVersion.create(resource, v) end) - next unless json - resource_version_info[:meta] = {} - resource_version_info[:meta][:livecheckable] = has_livecheckable ? "Yes" : "No" + resource_version_info[:meta] = { livecheckable: has_livecheckable ? "Yes" : "No" } if has_livecheckable - resource_version_info[:meta][:livecheck] = {} - resource_version_info[:meta][:livecheck][:url] = {} + resource_version_info[:meta][:livecheck] = { url: {} } if livecheck_url.is_a?(Symbol) && livecheck_url_string resource_version_info[:meta][:livecheck][:url][:symbol] = livecheck_url @@ -823,10 +821,7 @@ module Homebrew resource_version_info[:meta][:livecheck][:url][:final] = strategy_data[:final_url] end - if homebrew_curl.present? - resource_version_info[:meta][:livecheck][:url][:homebrew_curl] = - homebrew_curl - end + resource_version_info[:meta][:livecheck][:url][:homebrew_curl] = homebrew_curl if homebrew_curl.present? resource_version_info[:meta][:livecheck][:strategy] = strategy.present? ? strategy_name : nil if strategies.present? resource_version_info[:meta][:livecheck][:strategies] = strategies.map do |s| @@ -835,22 +830,19 @@ module Homebrew end resource_version_info[:meta][:livecheck][:regex] = regex.inspect if regex.present? resource_version_info[:meta][:livecheck][:cached] = true if strategy_data[:cached] == true - end - resource_version_info[:meta][:url] = {} - resource_version_info[:meta][:url][:original] = original_url + resource_version_info[:meta][:url] = { original: original_url } resource_version_info[:meta][:url][:processed] = url if url != original_url end else # If there's no livecheck block in resource resource_version_info[:version][:latest] = resource.version - if json && verbose - resource_version_info[:meta] = {} - resource_version_info[:meta][:url] = resource.url.to_s - end + resource_version_info[:meta] = { url: resource.url.to_s } if json && verbose end - resource_version_info[:version][:newer_than_upstream] = resource_version_info[:version][:current] > resource_version_info[:version][:latest] - resource_version_info[:version][:outdated] = resource_version_info[:version][:current] < resource_version_info[:version][:latest] + resource_version_info[:version][:newer_than_upstream] = + resource_version_info[:version][:current] > resource_version_info[:version][:latest] + resource_version_info[:version][:outdated] = + resource_version_info[:version][:current] < resource_version_info[:version][:latest] resource_version_info end From 87b8c7bb6d44830b94f1b2cf0e633e24cb934203 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Tue, 2 Aug 2022 03:33:34 +0500 Subject: [PATCH 052/138] Added double blank line before resources to better separate the debug output Co-authored-by: Sam Ford <1584702+samford@users.noreply.github.com> --- Library/Homebrew/livecheck/livecheck.rb | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index 686c0be5ff..ee92b696d1 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -668,9 +668,7 @@ check_resource: false) has_livecheckable = resource.livecheckable? if debug - puts <<~EOS - - EOS + puts "\n\n" puts "Resource: #{resource_name(resource, full_name: full_name)}" puts "Livecheckable?: #{has_livecheckable ? "Yes" : "No"}" end From 609485cdd77c020bca51cefc8ed85704e3e649c1 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Tue, 2 Aug 2022 00:35:16 +0200 Subject: [PATCH 053/138] Added a blank line before the output from `print_latest_version` in the debug output --- Library/Homebrew/livecheck/livecheck.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index 686c0be5ff..c31edc5c76 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -359,7 +359,7 @@ module Homebrew info.except!(:meta) unless verbose next info end - + puts if debug print_latest_version(info, verbose: verbose, ambiguous_cask: ambiguous_casks.include?(formula_or_cask), check_resource: false) From 26cdf025063e8e9d3fa51faa301d255c07342c2a Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Tue, 2 Aug 2022 00:52:01 +0200 Subject: [PATCH 054/138] Fix typecheck issues for livecheckable resources --- Library/Homebrew/cli/args.rbi | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Library/Homebrew/cli/args.rbi b/Library/Homebrew/cli/args.rbi index 32b1cd8e6e..e59eb5cac8 100644 --- a/Library/Homebrew/cli/args.rbi +++ b/Library/Homebrew/cli/args.rbi @@ -30,6 +30,9 @@ module Homebrew sig { returns(T::Boolean) } def newer_only?; end + sig { returns(T::Boolean) } + def resources?; end + sig { returns(T::Boolean) } def full_name?; end From ac614e29f9b411b8f845f7e630ae4c3064b24a7b Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Tue, 2 Aug 2022 00:54:18 +0200 Subject: [PATCH 055/138] After brew typecheck --fix --- Library/Homebrew/livecheck/livecheck.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index db1a341f40..e6f0d01399 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -269,7 +269,7 @@ module Homebrew end current_str = current.to_s - current = LivecheckVersion.create(formula_or_cask, current) + current = T.let(LivecheckVersion.create(formula_or_cask, current), T.untyped) latest = if formula&.head_only? formula.head.downloader.fetch_last_commit @@ -321,7 +321,7 @@ module Homebrew end latest_str = latest.to_s - latest = LivecheckVersion.create(formula_or_cask, latest) + latest = T.let(LivecheckVersion.create(formula_or_cask, latest), T.untyped) is_outdated = if formula&.head_only? # A HEAD-only formula is considered outdated if the latest upstream From fd4a02ff349f7a8988394c2de6862a8decf48c23 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Wed, 3 Aug 2022 18:35:52 +0500 Subject: [PATCH 056/138] Refactored `check_resource` to `resource` in `print_latest_version` Co-authored-by: Nanda H Krishna --- Library/Homebrew/livecheck/livecheck.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index e6f0d01399..aee88d19b8 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -503,8 +503,8 @@ check_resource: false) end # Formats and prints the livecheck result for a formula/cask/resource. - sig { params(info: Hash, verbose: T::Boolean, ambiguous_cask: T::Boolean, check_resource: T::Boolean).void } - def print_latest_version(info, verbose:, ambiguous_cask: false, check_resource: false) + sig { params(info: Hash, verbose: T::Boolean, ambiguous_cask: T::Boolean, resource: T::Boolean).void } + def print_latest_version(info, verbose:, ambiguous_cask: false, resource: false) package_or_resource_s = check_resource ? " " : "" package_or_resource_s += "#{Tty.blue}#{info[:formula] || info[:cask] || info[:resource]}#{Tty.reset}" package_or_resource_s += " (cask)" if ambiguous_cask && !check_resource From 06d45fea8025510df709507d6919be53cd454c92 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Wed, 3 Aug 2022 18:36:55 +0500 Subject: [PATCH 057/138] Minor fix: `ambiguous_cask` should be false for `resources` Co-authored-by: Nanda H Krishna --- Library/Homebrew/livecheck/livecheck.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index aee88d19b8..0c94611141 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -395,7 +395,7 @@ check_resource: false) print_latest_version( r_info, verbose: verbose, - ambiguous_cask: ambiguous_casks.include?(formula_or_cask), + ambiguous_cask: false, check_resource: true, ) end From 424c5bfce2f441d42a86a394d754ccb408a854d5 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Wed, 3 Aug 2022 18:37:36 +0500 Subject: [PATCH 058/138] Minor change: update parameters Co-authored-by: Nanda H Krishna --- Library/Homebrew/livecheck/livecheck.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index 0c94611141..3029a04f4d 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -396,7 +396,7 @@ check_resource: false) r_info, verbose: verbose, ambiguous_cask: false, - check_resource: true, + resource: true, ) end end From 9b31dc7e873a4ca8dfa788ce17906fe7b6fa9ff1 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Wed, 3 Aug 2022 18:41:44 +0500 Subject: [PATCH 059/138] Refactored `print_latest_version` for resource Co-authored-by: Nanda H Krishna --- Library/Homebrew/livecheck/livecheck.rb | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index 3029a04f4d..9f94042906 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -505,11 +505,10 @@ check_resource: false) # Formats and prints the livecheck result for a formula/cask/resource. sig { params(info: Hash, verbose: T::Boolean, ambiguous_cask: T::Boolean, resource: T::Boolean).void } def print_latest_version(info, verbose:, ambiguous_cask: false, resource: false) - package_or_resource_s = check_resource ? " " : "" + package_or_resource_s = resource ? " " : "" package_or_resource_s += "#{Tty.blue}#{info[:formula] || info[:cask] || info[:resource]}#{Tty.reset}" - package_or_resource_s += " (cask)" if ambiguous_cask && !check_resource - package_or_resource_s += " (guessed)" if !info[:meta][:livecheckable] && !check_resource && verbose - package_or_resource_s += " (livecheckable)" if check_resource && info[:meta][:livecheckable] && verbose + package_or_resource_s += " (cask)" if ambiguous_cask + package_or_resource_s += " (guessed)" if !info[:meta][:livecheckable] && verbose current_s = if info[:version][:newer_than_upstream] "#{Tty.red}#{info[:version][:current]}#{Tty.reset}" From 6f79b5dee292257692148017529f6b25badc47cb Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Wed, 3 Aug 2022 15:47:32 +0200 Subject: [PATCH 060/138] Minor change: fix the argument for formulae --- Library/Homebrew/livecheck/livecheck.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index 9f94042906..4be77e196f 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -361,7 +361,7 @@ module Homebrew end puts if debug print_latest_version(info, verbose: verbose, ambiguous_cask: ambiguous_casks.include?(formula_or_cask), -check_resource: false) +resource: false) if check_resources && formula_or_cask.resources.present? resources_info = [] @@ -396,7 +396,7 @@ check_resource: false) r_info, verbose: verbose, ambiguous_cask: false, - resource: true, + resource: true, ) end end From e7843775379bf300b81424314903adbc582ef397 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Wed, 3 Aug 2022 16:07:48 +0200 Subject: [PATCH 061/138] Code refactoring for `info` Hash for resources --- Library/Homebrew/livecheck/livecheck.rb | 33 +++++++++++++------------ 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index 4be77e196f..d3349670e9 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -348,21 +348,6 @@ module Homebrew info[:meta][:head_only] = true if formula&.head_only? info[:meta].merge!(version_info[:meta]) if version_info.present? && version_info.key?(:meta) - info[:resources] = resource_version_info if check_resources - - next if newer_only && !info[:version][:outdated] - - has_a_newer_upstream_version ||= true - - if json - progress&.increment - info.except!(:meta) unless verbose - next info - end - puts if debug - print_latest_version(info, verbose: verbose, ambiguous_cask: ambiguous_casks.include?(formula_or_cask), -resource: false) - if check_resources && formula_or_cask.resources.present? resources_info = [] latest_resources_names = latest_resources.map { |r| r[:name] } @@ -391,6 +376,22 @@ resource: false) } resources_info << info end + info[:resources] = resources_info + end + + next if newer_only && !info[:version][:outdated] + + has_a_newer_upstream_version ||= true + + if json + progress&.increment + info.except!(:meta) unless verbose + next info + end + puts if debug + print_latest_version(info, verbose: verbose, ambiguous_cask: ambiguous_casks.include?(formula_or_cask), resource: false) + + if check_resources && formula_or_cask.resources.present? resources_info.each do |r_info| print_latest_version( r_info, @@ -650,7 +651,7 @@ resource: false) # couldn't be found for a given resource. sig { params( - resource: T.any(Resource), + resource: Resource, json: T::Boolean, full_name: T::Boolean, verbose: T::Boolean, From 495f8f2193d8477a03bb54c47ecb8b924365096a Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Sun, 7 Aug 2022 16:59:53 +0200 Subject: [PATCH 062/138] Return `download_name` when `--full-name` is passed for resources --- Library/Homebrew/livecheck/livecheck.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index d3349670e9..1d381c2710 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -467,7 +467,7 @@ module Homebrew # provided; returns the name otherwise. sig { params(resource: Resource, full_name: T::Boolean).returns(String) } def resource_name(resource, full_name: false) - full_name ? resource.full_name : resource.name + full_name ? resource.download_name : resource.name end sig { From 71648a5714fd00d312d2d61482a3b1dfd4fca675 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Sun, 7 Aug 2022 17:06:03 +0200 Subject: [PATCH 063/138] Updated `brew livecheck` bash completions for `--resources` flag --- completions/bash/brew | 1 + 1 file changed, 1 insertion(+) diff --git a/completions/bash/brew b/completions/bash/brew index 86abb433c2..ea9d874338 100644 --- a/completions/bash/brew +++ b/completions/bash/brew @@ -1330,6 +1330,7 @@ _brew_livecheck() { --cask --debug --formula + --resources --full-name --help --installed From c825ab7dfe6680c7df630b97adf2b918a61eeeb1 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Sun, 7 Aug 2022 17:06:17 +0200 Subject: [PATCH 064/138] Updated `brew livecheck` fish completions for `--resources` flag --- completions/fish/brew.fish | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/completions/fish/brew.fish b/completions/fish/brew.fish index d1ba1881af..b80f4b814b 100644 --- a/completions/fish/brew.fish +++ b/completions/fish/brew.fish @@ -948,11 +948,12 @@ __fish_brew_complete_arg 'list; and not __fish_seen_argument -l cask -l casks' - __fish_brew_complete_arg 'list; and not __fish_seen_argument -l formula -l formulae' -a '(__fish_brew_suggest_casks_installed)' -__fish_brew_complete_cmd 'livecheck' 'Check for newer versions of formulae and/or casks from upstream' +__fish_brew_complete_cmd 'livecheck' 'Check for newer versions of formulae, resources and/or casks from upstream' __fish_brew_complete_arg 'livecheck' -l all -d 'Check all available formulae/casks' __fish_brew_complete_arg 'livecheck' -l cask -d 'Only check casks' __fish_brew_complete_arg 'livecheck' -l debug -d 'Display any debugging information' __fish_brew_complete_arg 'livecheck' -l formula -d 'Only check formulae' +__fish_brew_complete_arg 'livecheck' -l resources -d 'Also check resources for formulae' __fish_brew_complete_arg 'livecheck' -l full-name -d 'Print formulae/casks with fully-qualified names' __fish_brew_complete_arg 'livecheck' -l help -d 'Show this message' __fish_brew_complete_arg 'livecheck' -l installed -d 'Check formulae/casks that are currently installed' From 7855e18042267c3b755e49615a4c1ad25c77e9e9 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Sun, 7 Aug 2022 17:06:40 +0200 Subject: [PATCH 065/138] Updated `brew livecheck` zsh completions for `--resources` flag --- completions/zsh/_brew | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/completions/zsh/_brew b/completions/zsh/_brew index 7c33b10012..8290d9433f 100644 --- a/completions/zsh/_brew +++ b/completions/zsh/_brew @@ -174,7 +174,7 @@ __brew_internal_commands() { 'link:Symlink all of formula'\''s installed files into Homebrew'\''s prefix' 'linkage:Check the library links from the given formula kegs' 'list:List all installed formulae and casks' - 'livecheck:Check for newer versions of formulae and/or casks from upstream' + 'livecheck:Check for newer versions of formulae, resources and/or casks from upstream' 'log:Show the `git log` for formula or cask, or show the log for the Homebrew repository if no formula or cask is provided' 'migrate:Migrate renamed packages to new names, where formula are old names of packages' 'missing:Check the given formula kegs for missing dependencies' @@ -1167,6 +1167,7 @@ _brew_livecheck() { '--quiet[Suppress warnings, don'\''t print a progress bar for JSON output]' \ '(--all --installed)--tap[Check formulae/casks within the given tap, specified as user`/`repo]' \ '--verbose[Make some output more verbose]' \ + '--resources[Also check resources for formulae]' \ - formula \ '(--cask)--formula[Only check formulae]' \ '*::formula:__brew_formulae' \ From 81a7d6edd732d903ab653400ee4a51d4d8fb896a Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Sun, 7 Aug 2022 17:13:17 +0200 Subject: [PATCH 066/138] Fixed issue with --json flag for resources --- Library/Homebrew/livecheck/livecheck.rb | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index 1d381c2710..e988ba6535 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -285,7 +285,7 @@ module Homebrew # Check current and latest resources (if "--resources" flag is given) # Only check current and latest versions if we have resources to check against - if check_resources && formula_or_cask.resources.present? + if check_resources && formula_or_cask.is_a?(Formula) && formula_or_cask.resources.present? current_resources = formula_or_cask.resources.map do |resource| { name: resource.name, version: resource.version, livecheckable: resource.livecheckable? } end @@ -348,7 +348,7 @@ module Homebrew info[:meta][:head_only] = true if formula&.head_only? info[:meta].merge!(version_info[:meta]) if version_info.present? && version_info.key?(:meta) - if check_resources && formula_or_cask.resources.present? + if check_resources && formula_or_cask.is_a?(Formula) && formula_or_cask.resources.present? resources_info = [] latest_resources_names = latest_resources.map { |r| r[:name] } current_resources.each do |resource| @@ -365,16 +365,16 @@ module Homebrew is_newer_than_upstream = current > latest is_outdated = (current != latest) && !is_newer_than_upstream - info = {} - info[:resource] = resource[:name] - info[:meta] = { livecheckable: resource[:livecheckable] } - info[:version] = { + res_info = {} + res_info[:resource] = resource[:name] + res_info[:meta] = { livecheckable: resource[:livecheckable] } + res_info[:version] = { current: current_str, latest: latest_str, newer_than_upstream: is_newer_than_upstream, outdated: is_outdated, } - resources_info << info + resources_info << res_info end info[:resources] = resources_info end From eb9bc93fae552ae4600c9c0b78ef8bd5d19d95a1 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Sun, 7 Aug 2022 17:19:59 +0200 Subject: [PATCH 067/138] Removed unnecessary `:meta` from info hash --- Library/Homebrew/livecheck/livecheck.rb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index e988ba6535..94a08826fd 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -367,7 +367,6 @@ module Homebrew res_info = {} res_info[:resource] = resource[:name] - res_info[:meta] = { livecheckable: resource[:livecheckable] } res_info[:version] = { current: current_str, latest: latest_str, @@ -509,7 +508,7 @@ module Homebrew package_or_resource_s = resource ? " " : "" package_or_resource_s += "#{Tty.blue}#{info[:formula] || info[:cask] || info[:resource]}#{Tty.reset}" package_or_resource_s += " (cask)" if ambiguous_cask - package_or_resource_s += " (guessed)" if !info[:meta][:livecheckable] && verbose + package_or_resource_s += " (guessed)" if verbose && !info[:meta][:livecheckable] current_s = if info[:version][:newer_than_upstream] "#{Tty.red}#{info[:version][:current]}#{Tty.reset}" From 656b18b13a783274dba4c6578a1bd9babf146d1e Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Sun, 7 Aug 2022 17:24:53 +0200 Subject: [PATCH 068/138] Minor change: updated doc for `resource_version` method --- Library/Homebrew/livecheck/livecheck.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index 94a08826fd..010c0c06d6 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -645,7 +645,7 @@ module Homebrew homebrew_curl_root_domains.include?(url_root_domain) end - # Identifies the latest version of the resource in a given Formulae/Casks and returns a Hash containing + # Identifies the latest version of the resource in a given Formulae and returns a Hash containing # the version information for a resource. Returns a nil value if a latest version # couldn't be found for a given resource. sig { From 6055f782184658dda1ac32678319152f81daf77b Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Sun, 7 Aug 2022 18:14:24 +0200 Subject: [PATCH 069/138] Refactored code for resources in `livecheck` command --- Library/Homebrew/livecheck/livecheck.rb | 332 ++++++++++++------------ 1 file changed, 167 insertions(+), 165 deletions(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index 010c0c06d6..1cdff96ee1 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -286,9 +286,9 @@ module Homebrew # Check current and latest resources (if "--resources" flag is given) # Only check current and latest versions if we have resources to check against if check_resources && formula_or_cask.is_a?(Formula) && formula_or_cask.resources.present? - current_resources = formula_or_cask.resources.map do |resource| - { name: resource.name, version: resource.version, livecheckable: resource.livecheckable? } - end + # current_resources = formula_or_cask.resources.map do |resource| + # { name: resource.name, version: resource.version, livecheckable: resource.livecheckable? } + # end resource_version_info = formula_or_cask.resources.map do |resource| resource_info = resource_version( @@ -301,9 +301,11 @@ module Homebrew resource_info end - latest_resources = resource_version_info.map do |resource| - { name: resource[:resource], version: resource[:version][:latest] } - end + # p "resource_version_info: #{resource_version_info}" + + # latest_resources = resource_version_info.map do |resource| + # { name: resource[:resource], version: resource[:version][:latest] } + # end end if latest.blank? @@ -348,34 +350,36 @@ module Homebrew info[:meta][:head_only] = true if formula&.head_only? info[:meta].merge!(version_info[:meta]) if version_info.present? && version_info.key?(:meta) + if check_resources && formula_or_cask.is_a?(Formula) && formula_or_cask.resources.present? - resources_info = [] - latest_resources_names = latest_resources.map { |r| r[:name] } - current_resources.each do |resource| - current = resource[:version] - current_str = current.to_s - latest = if latest_resources_names.include?(resource[:name].to_s) - res = latest_resources.find { |r| r[:name].to_s == resource[:name].to_s } - res[:version] - else - current - end - latest_str = latest.to_s + info[:resources] = resource_version_info + # resources_info = [] + # latest_resources_names = latest_resources.map { |r| r[:name] } + # current_resources.each do |resource| + # current = resource[:version] + # current_str = current.to_s + # latest = if latest_resources_names.include?(resource[:name].to_s) + # res = latest_resources.find { |r| r[:name].to_s == resource[:name].to_s } + # res[:version] + # else + # current + # end + # latest_str = latest.to_s - is_newer_than_upstream = current > latest - is_outdated = (current != latest) && !is_newer_than_upstream + # is_newer_than_upstream = current > latest + # is_outdated = (current != latest) && !is_newer_than_upstream - res_info = {} - res_info[:resource] = resource[:name] - res_info[:version] = { - current: current_str, - latest: latest_str, - newer_than_upstream: is_newer_than_upstream, - outdated: is_outdated, - } - resources_info << res_info - end - info[:resources] = resources_info + # res_info = {} + # res_info[:resource] = resource[:name] + # res_info[:version] = { + # current: current_str, + # latest: latest_str, + # newer_than_upstream: is_newer_than_upstream, + # outdated: is_outdated, + # } + # resources_info << res_info + # end + # info[:resources] = resources_info end next if newer_only && !info[:version][:outdated] @@ -391,7 +395,7 @@ module Homebrew print_latest_version(info, verbose: verbose, ambiguous_cask: ambiguous_casks.include?(formula_or_cask), resource: false) if check_resources && formula_or_cask.resources.present? - resources_info.each do |r_info| + resource_version_info.each do |r_info| print_latest_version( r_info, verbose: verbose, @@ -672,174 +676,172 @@ module Homebrew puts "Livecheckable?: #{has_livecheckable ? "Yes" : "No"}" end - resource_version_info = { - resource: resource_name(resource, full_name: full_name), - version: { - current: resource.version, - }, - } + resource_version_info = {} - # Check resources with livecheck block (will be updated in the future) - if has_livecheckable - livecheck = resource.livecheck - livecheck_url = livecheck.url - livecheck_regex = livecheck.regex - livecheck_strategy = livecheck.strategy - livecheck_strategy_block = livecheck.strategy_block + livecheck = resource.livecheck + livecheck_url = has_livecheckable ? livecheck.url : resource.url + livecheck_regex = livecheck&.regex + livecheck_strategy = livecheck&.strategy + livecheck_strategy_block = livecheck&.strategy_block - livecheck_url_string = livecheck_url_to_string( - livecheck_url, - resource, + livecheck_url_string = livecheck_url_to_string( + livecheck_url, + resource, + ) + + urls = [livecheck_url_string] if livecheck_url_string + urls ||= checkable_urls(resource) + + checked_urls = [] + + urls.each_with_index do |original_url, i| + # Only preprocess the URL when it's appropriate + url = if STRATEGY_SYMBOLS_TO_SKIP_PREPROCESS_URL.include?(livecheck_strategy) + original_url + else + preprocess_url(original_url) + end + next if checked_urls.include?(url) + + strategies = Strategy.from_url( + url, + livecheck_strategy: livecheck_strategy, + url_provided: livecheck_url.present?, + regex_provided: livecheck_regex.present?, + block_provided: livecheck_strategy_block.present?, ) - urls = [livecheck_url_string] if livecheck_url_string - urls ||= checkable_urls(resource) + strategy = Strategy.from_symbol(livecheck_strategy) || strategies.first + strategy_name = livecheck_strategy_names[strategy] - checked_urls = [] - - urls.each_with_index do |original_url, i| - # Only preprocess the URL when it's appropriate - url = if STRATEGY_SYMBOLS_TO_SKIP_PREPROCESS_URL.include?(livecheck_strategy) - original_url + if debug + puts + if livecheck_url.is_a?(Symbol) + # This assumes the URL symbol will fit within the available space + puts "URL (#{livecheck_url}):".ljust(18, " ") + original_url else - preprocess_url(original_url) + puts "URL: #{original_url}" end - next if checked_urls.include?(url) + puts "URL (processed): #{url}" if url != original_url + if strategies.present? && verbose + puts "Strategies: #{strategies.map { |s| livecheck_strategy_names[s] }.join(", ")}" + end + puts "Strategy: #{strategy.blank? ? "None" : strategy_name}" + puts "Regex: #{livecheck_regex.inspect}" if livecheck_regex.present? + end - strategies = Strategy.from_url( - url, - livecheck_strategy: livecheck_strategy, - url_provided: livecheck_url.present?, - regex_provided: livecheck_regex.present?, - block_provided: livecheck_strategy_block.present?, - ) + if livecheck_strategy.present? + if livecheck_url.blank? && strategy.method(:find_versions).parameters.include?([:keyreq, :url]) + odebug "#{strategy_name} strategy requires a URL" + next + elsif livecheck_strategy != :page_match && strategies.exclude?(strategy) + odebug "#{strategy_name} strategy does not apply to this URL" + next + end + end + next if strategy.blank? - strategy = Strategy.from_symbol(livecheck_strategy) || strategies.first - strategy_name = livecheck_strategy_names[strategy] + homebrew_curl = case strategy_name + when "PageMatch", "HeaderMatch" + use_homebrew_curl?(resource, url) + end + puts "Homebrew curl?: Yes" if debug && homebrew_curl.present? + strategy_data = strategy.find_versions( + url: url, regex: livecheck_regex, + homebrew_curl: homebrew_curl, &livecheck_strategy_block + ) + match_version_map = strategy_data[:matches] + regex = strategy_data[:regex] + messages = strategy_data[:messages] + checked_urls << url - if debug - puts - if livecheck_url.is_a?(Symbol) - # This assumes the URL symbol will fit within the available space - puts "URL (#{livecheck_url}):".ljust(18, " ") + original_url - else - puts "URL: #{original_url}" + if messages.is_a?(Array) && match_version_map.blank? + puts messages unless json + next if i + 1 < urls.length + + return status_hash(resource, "error", messages, full_name: full_name, verbose: verbose) + end + + if debug + if strategy_data[:url].present? && strategy_data[:url] != url + puts "URL (strategy): #{strategy_data[:url]}" + end + puts "URL (final): #{strategy_data[:final_url]}" if strategy_data[:final_url].present? + if strategy_data[:regex].present? && strategy_data[:regex] != livecheck_regex + puts "Regex (strategy): #{strategy_data[:regex].inspect}" + end + puts "Cached?: Yes" if strategy_data[:cached] == true + end + + match_version_map.delete_if do |_match, version| + next true if version.blank? + next false if has_livecheckable + + UNSTABLE_VERSION_KEYWORDS.any? do |rejection| + version.to_s.include?(rejection) + end + end + next if match_version_map.blank? + + if debug + puts + puts "Matched Versions:" + + if verbose + match_version_map.each do |match, version| + puts "#{match} => #{version.inspect}" end - puts "URL (processed): #{url}" if url != original_url - if strategies.present? && verbose - puts "Strategies: #{strategies.map { |s| livecheck_strategy_names[s] }.join(", ")}" - end - puts "Strategy: #{strategy.blank? ? "None" : strategy_name}" - puts "Regex: #{livecheck_regex.inspect}" if livecheck_regex.present? + else + puts match_version_map.values.join(", ") end + end - if livecheck_strategy.present? - if livecheck_url.blank? && strategy.method(:find_versions).parameters.include?([:keyreq, :url]) - odebug "#{strategy_name} strategy requires a URL" - next - elsif livecheck_strategy != :page_match && strategies.exclude?(strategy) - odebug "#{strategy_name} strategy does not apply to this URL" - next - end - end - next if strategy.blank? + res_current = resource.version + res_latest = Version.new(match_version_map.values.max_by do |v| LivecheckVersion.create(resource, v) end) - homebrew_curl = case strategy_name - when "PageMatch", "HeaderMatch" - use_homebrew_curl?(resource, url) - end - puts "Homebrew curl?: Yes" if debug && homebrew_curl.present? - strategy_data = strategy.find_versions( - url: url, regex: livecheck_regex, - homebrew_curl: homebrew_curl, &livecheck_strategy_block - ) - match_version_map = strategy_data[:matches] - regex = strategy_data[:regex] - messages = strategy_data[:messages] - checked_urls << url + is_newer_than_upstream = res_current > res_latest + is_outdated = (res_current != res_latest) && !is_newer_than_upstream - if messages.is_a?(Array) && match_version_map.blank? - puts messages unless json - next if i + 1 < urls.length - - return status_hash(resource, "error", messages, full_name: full_name, verbose: verbose) - end - - if debug - if strategy_data[:url].present? && strategy_data[:url] != url - puts "URL (strategy): #{strategy_data[:url]}" - end - puts "URL (final): #{strategy_data[:final_url]}" if strategy_data[:final_url].present? - if strategy_data[:regex].present? && strategy_data[:regex] != livecheck_regex - puts "Regex (strategy): #{strategy_data[:regex].inspect}" - end - puts "Cached?: Yes" if strategy_data[:cached] == true - end - - match_version_map.delete_if do |_match, version| - next true if version.blank? - next false if has_livecheckable - - UNSTABLE_VERSION_KEYWORDS.any? do |rejection| - version.to_s.include?(rejection) - end - end - next if match_version_map.blank? - - if debug - puts - puts "Matched Versions:" - - if verbose - match_version_map.each do |match, version| - puts "#{match} => #{version.inspect}" - end - else - puts match_version_map.values.join(", ") - end - end - - resource_version_info[:version][:latest] = Version.new(match_version_map.values.max_by do |v| - LivecheckVersion.create(resource, v) - end) - next unless json + resource_version_info = { + resource: resource_name(resource, full_name: full_name), + version: { + current: res_current.to_s, + latest: res_latest.to_s, + newer_than_upstream: is_newer_than_upstream, + outdated: is_outdated, + }, + } + if json && verbose resource_version_info[:meta] = { livecheckable: has_livecheckable ? "Yes" : "No" } if has_livecheckable - resource_version_info[:meta][:livecheck] = { url: {} } + res_livecheck = { url: {} } if livecheck_url.is_a?(Symbol) && livecheck_url_string - resource_version_info[:meta][:livecheck][:url][:symbol] = + res_livecheck[:url][:symbol] = livecheck_url end if strategy_data[:url].present? && strategy_data[:url] != url - resource_version_info[:meta][:livecheck][:url][:strategy] = strategy_data[:url] + res_livecheck[:url][:strategy] = strategy_data[:url] end if strategy_data[:final_url] - resource_version_info[:meta][:livecheck][:url][:final] = + res_livecheck[:url][:final] = strategy_data[:final_url] end - resource_version_info[:meta][:livecheck][:url][:homebrew_curl] = homebrew_curl if homebrew_curl.present? - resource_version_info[:meta][:livecheck][:strategy] = strategy.present? ? strategy_name : nil + res_livecheck[:url][:homebrew_curl] = homebrew_curl if homebrew_curl.present? + res_livecheck[:strategy] = strategy.present? ? strategy_name : nil if strategies.present? - resource_version_info[:meta][:livecheck][:strategies] = strategies.map do |s| + res_livecheck[:strategies] = strategies.map do |s| livecheck_strategy_names[s] end end - resource_version_info[:meta][:livecheck][:regex] = regex.inspect if regex.present? - resource_version_info[:meta][:livecheck][:cached] = true if strategy_data[:cached] == true + res_livecheck[:regex] = regex.inspect if regex.present? + res_livecheck[:cached] = true if strategy_data[:cached] == true + resource_version_info[:meta][:livecheck] = res_livecheck end resource_version_info[:meta][:url] = { original: original_url } resource_version_info[:meta][:url][:processed] = url if url != original_url end - else - # If there's no livecheck block in resource - resource_version_info[:version][:latest] = resource.version - resource_version_info[:meta] = { url: resource.url.to_s } if json && verbose end - resource_version_info[:version][:newer_than_upstream] = - resource_version_info[:version][:current] > resource_version_info[:version][:latest] - resource_version_info[:version][:outdated] = - resource_version_info[:version][:current] < resource_version_info[:version][:latest] resource_version_info end From b95a5188bff3601929082fed8d1b76a7e629f0df Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Sun, 7 Aug 2022 18:34:03 +0200 Subject: [PATCH 070/138] Refactored code for `brew livecheck --resources --json` --- Library/Homebrew/livecheck/livecheck.rb | 56 ++++--------------------- 1 file changed, 7 insertions(+), 49 deletions(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index 1cdff96ee1..cecd3f00e9 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -285,11 +285,8 @@ module Homebrew # Check current and latest resources (if "--resources" flag is given) # Only check current and latest versions if we have resources to check against - if check_resources && formula_or_cask.is_a?(Formula) && formula_or_cask.resources.present? - # current_resources = formula_or_cask.resources.map do |resource| - # { name: resource.name, version: resource.version, livecheckable: resource.livecheckable? } - # end - + 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| resource_info = resource_version( resource, @@ -300,12 +297,6 @@ module Homebrew ) resource_info end - - # p "resource_version_info: #{resource_version_info}" - - # latest_resources = resource_version_info.map do |resource| - # { name: resource[:resource], version: resource[:version][:latest] } - # end end if latest.blank? @@ -350,37 +341,7 @@ module Homebrew info[:meta][:head_only] = true if formula&.head_only? info[:meta].merge!(version_info[:meta]) if version_info.present? && version_info.key?(:meta) - - if check_resources && formula_or_cask.is_a?(Formula) && formula_or_cask.resources.present? - info[:resources] = resource_version_info - # resources_info = [] - # latest_resources_names = latest_resources.map { |r| r[:name] } - # current_resources.each do |resource| - # current = resource[:version] - # current_str = current.to_s - # latest = if latest_resources_names.include?(resource[:name].to_s) - # res = latest_resources.find { |r| r[:name].to_s == resource[:name].to_s } - # res[:version] - # else - # current - # end - # latest_str = latest.to_s - - # is_newer_than_upstream = current > latest - # is_outdated = (current != latest) && !is_newer_than_upstream - - # res_info = {} - # res_info[:resource] = resource[:name] - # res_info[:version] = { - # current: current_str, - # latest: latest_str, - # newer_than_upstream: is_newer_than_upstream, - # outdated: is_outdated, - # } - # resources_info << res_info - # end - # info[:resources] = resources_info - end + info[:resources] = resource_version_info if check_for_resources next if newer_only && !info[:version][:outdated] @@ -394,7 +355,7 @@ module Homebrew puts if debug print_latest_version(info, verbose: verbose, ambiguous_cask: ambiguous_casks.include?(formula_or_cask), resource: false) - if check_resources && formula_or_cask.resources.present? + if check_for_resources resource_version_info.each do |r_info| print_latest_version( r_info, @@ -512,7 +473,7 @@ module Homebrew package_or_resource_s = resource ? " " : "" package_or_resource_s += "#{Tty.blue}#{info[:formula] || info[:cask] || info[:resource]}#{Tty.reset}" package_or_resource_s += " (cask)" if ambiguous_cask - package_or_resource_s += " (guessed)" if verbose && !info[:meta][:livecheckable] + package_or_resource_s += " (guessed)" if verbose && !resource && !info[:meta][:livecheckable] current_s = if info[:version][:newer_than_upstream] "#{Tty.red}#{info[:version][:current]}#{Tty.reset}" @@ -798,7 +759,6 @@ module Homebrew res_current = resource.version res_latest = Version.new(match_version_map.values.max_by do |v| LivecheckVersion.create(resource, v) end) - is_newer_than_upstream = res_current > res_latest is_outdated = (res_current != res_latest) && !is_newer_than_upstream @@ -817,15 +777,13 @@ module Homebrew if has_livecheckable res_livecheck = { url: {} } if livecheck_url.is_a?(Symbol) && livecheck_url_string - res_livecheck[:url][:symbol] = - livecheck_url + res_livecheck[:url][:symbol] = livecheck_url end if strategy_data[:url].present? && strategy_data[:url] != url res_livecheck[:url][:strategy] = strategy_data[:url] end if strategy_data[:final_url] - res_livecheck[:url][:final] = - strategy_data[:final_url] + res_livecheck[:url][:final] = strategy_data[:final_url] end res_livecheck[:url][:homebrew_curl] = homebrew_curl if homebrew_curl.present? res_livecheck[:strategy] = strategy.present? ? strategy_name : nil From 3d83e181421d775e8fe1a2f9f554704b715972f3 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Sun, 7 Aug 2022 19:03:12 +0200 Subject: [PATCH 071/138] Updated `--json` debug info for livecheckable resources --- Library/Homebrew/livecheck/livecheck.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index cecd3f00e9..5663e58514 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -773,9 +773,11 @@ module Homebrew } if json && verbose - resource_version_info[:meta] = { livecheckable: has_livecheckable ? "Yes" : "No" } + resource_version_info[:meta] = { url: { original: original_url } } + resource_version_info[:meta][:url][:processed] = url if url != original_url + resource_version_info[:meta][:livecheckable] = has_livecheckable ? "Yes" : "No" if has_livecheckable - res_livecheck = { url: {} } + res_livecheck = { url: { original: livecheck_url } } if livecheck_url.is_a?(Symbol) && livecheck_url_string res_livecheck[:url][:symbol] = livecheck_url end @@ -796,8 +798,6 @@ module Homebrew res_livecheck[:cached] = true if strategy_data[:cached] == true resource_version_info[:meta][:livecheck] = res_livecheck end - resource_version_info[:meta][:url] = { original: original_url } - resource_version_info[:meta][:url][:processed] = url if url != original_url end end resource_version_info From 53b0d60f75a6b478e418d660ef7e3fb1145cb601 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Sun, 7 Aug 2022 19:14:13 +0200 Subject: [PATCH 072/138] After running `brew style --fix` --- Library/Homebrew/livecheck/livecheck.rb | 56 ++++++++++++------------- 1 file changed, 27 insertions(+), 29 deletions(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index 5663e58514..efc59530c6 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -353,7 +353,8 @@ module Homebrew next info end puts if debug - print_latest_version(info, verbose: verbose, ambiguous_cask: ambiguous_casks.include?(formula_or_cask), resource: false) + print_latest_version(info, verbose: verbose, ambiguous_cask: ambiguous_casks.include?(formula_or_cask), +resource: false) if check_for_resources resource_version_info.each do |r_info| @@ -758,47 +759,44 @@ module Homebrew end res_current = resource.version - res_latest = Version.new(match_version_map.values.max_by do |v| LivecheckVersion.create(resource, v) end) + res_latest = Version.new(match_version_map.values.max_by { |v| LivecheckVersion.create(resource, v) }) is_newer_than_upstream = res_current > res_latest is_outdated = (res_current != res_latest) && !is_newer_than_upstream resource_version_info = { resource: resource_name(resource, full_name: full_name), version: { - current: res_current.to_s, - latest: res_latest.to_s, + current: res_current.to_s, + latest: res_latest.to_s, newer_than_upstream: is_newer_than_upstream, outdated: is_outdated, }, } - if json && verbose - resource_version_info[:meta] = { url: { original: original_url } } - resource_version_info[:meta][:url][:processed] = url if url != original_url - resource_version_info[:meta][:livecheckable] = has_livecheckable ? "Yes" : "No" - if has_livecheckable - res_livecheck = { url: { original: livecheck_url } } - if livecheck_url.is_a?(Symbol) && livecheck_url_string - res_livecheck[:url][:symbol] = livecheck_url - end - if strategy_data[:url].present? && strategy_data[:url] != url - res_livecheck[:url][:strategy] = strategy_data[:url] - end - if strategy_data[:final_url] - res_livecheck[:url][:final] = strategy_data[:final_url] - end - res_livecheck[:url][:homebrew_curl] = homebrew_curl if homebrew_curl.present? - res_livecheck[:strategy] = strategy.present? ? strategy_name : nil - if strategies.present? - res_livecheck[:strategies] = strategies.map do |s| - livecheck_strategy_names[s] - end - end - res_livecheck[:regex] = regex.inspect if regex.present? - res_livecheck[:cached] = true if strategy_data[:cached] == true - resource_version_info[:meta][:livecheck] = res_livecheck + next unless json + next unless verbose + + resource_version_info[:meta] = { url: { original: original_url } } + resource_version_info[:meta][:url][:processed] = url if url != original_url + resource_version_info[:meta][:livecheckable] = has_livecheckable ? "Yes" : "No" + next unless has_livecheckable + + res_livecheck = { url: { original: livecheck_url } } + res_livecheck[:url][:symbol] = livecheck_url if livecheck_url.is_a?(Symbol) && livecheck_url_string + if strategy_data[:url].present? && strategy_data[:url] != url + res_livecheck[:url][:strategy] = strategy_data[:url] + end + res_livecheck[:url][:final] = strategy_data[:final_url] if strategy_data[:final_url] + res_livecheck[:url][:homebrew_curl] = homebrew_curl if homebrew_curl.present? + res_livecheck[:strategy] = strategy.present? ? strategy_name : nil + if strategies.present? + res_livecheck[:strategies] = strategies.map do |s| + livecheck_strategy_names[s] end end + res_livecheck[:regex] = regex.inspect if regex.present? + res_livecheck[:cached] = true if strategy_data[:cached] == true + resource_version_info[:meta][:livecheck] = res_livecheck end resource_version_info end From 0c9ff722ae3466ffb56fcbbcd42b1290740c197e Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Sun, 7 Aug 2022 19:36:06 +0200 Subject: [PATCH 073/138] Fixed typecheck errors --- Library/Homebrew/livecheck/livecheck.rb | 27 ++++++++++++++----------- 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index efc59530c6..dd80df3010 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -269,7 +269,6 @@ module Homebrew end current_str = current.to_s - current = T.let(LivecheckVersion.create(formula_or_cask, current), T.untyped) latest = if formula&.head_only? formula.head.downloader.fetch_last_commit @@ -314,7 +313,6 @@ module Homebrew end latest_str = latest.to_s - latest = T.let(LivecheckVersion.create(formula_or_cask, latest), T.untyped) is_outdated = if formula&.head_only? # A HEAD-only formula is considered outdated if the latest upstream @@ -453,9 +451,9 @@ resource: false) if formula status_hash[:formula] = formula_name(formula, full_name: full_name) elsif cask - status_hash[:cask] = cask_name(package_or_resource, full_name: full_name) + status_hash[:cask] = cask_name(cask, full_name: full_name) elsif resource - status_hash[:resource] = resource_name(package_or_resource, full_name: full_name) + status_hash[:resource] = resource_name(resource, full_name: full_name) end status_hash[:status] = status_str status_hash[:messages] = messages if messages.is_a?(Array) @@ -509,7 +507,7 @@ resource: false) package_or_resource.send(:url)&.to_s if package_or_resource.is_a?(Resource) package_or_resource.send(livecheck_url)&.url if package_or_resource.is_a?(Formula) when :homepage - package_or_resource.homepage + package_or_resource.homepage unless package_or_resource.is_a?(Resource) end end @@ -582,29 +580,34 @@ resource: false) url end - # livecheck should fetch a URL using brewed curl if the formula/cask + # livecheck should fetch a URL using brewed curl if the formula/resource/cask # contains a `stable`/`url` or `head` URL `using: :homebrew_curl` that # shares the same root domain. - sig { params(formula_or_cask: T.any(Formula, Cask::Cask), url: String).returns(T::Boolean) } - def use_homebrew_curl?(formula_or_cask, url) + sig { params(package_or_resource: T.any(Formula, Cask::Cask, Resource), url: String).returns(T::Boolean) } + def use_homebrew_curl?(package_or_resource, url) url_root_domain = Addressable::URI.parse(url)&.domain return false if url_root_domain.blank? # Collect root domains of URLs with `using: :homebrew_curl` homebrew_curl_root_domains = [] - case formula_or_cask + case package_or_resource when Formula [:stable, :head].each do |spec_name| - next unless (spec = formula_or_cask.send(spec_name)) + next unless (spec = package_or_resource.send(spec_name)) next unless spec.using == :homebrew_curl domain = Addressable::URI.parse(spec.url)&.domain homebrew_curl_root_domains << domain if domain.present? end when Cask::Cask - return false unless formula_or_cask.url.using == :homebrew_curl + return false unless package_or_resource.url.using == :homebrew_curl - domain = Addressable::URI.parse(formula_or_cask.url.to_s)&.domain + domain = Addressable::URI.parse(package_or_resource.url.to_s)&.domain + homebrew_curl_root_domains << domain if domain.present? + when Resource + return false unless package_or_resource.url == :homebrew_curl + + domain = Addressable::URI.parse(package_or_resource.url.to_s)&.domain homebrew_curl_root_domains << domain if domain.present? end From 9598cc128c270bae68a6b6e6fb2d257ef92d060b Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Sun, 7 Aug 2022 20:02:05 +0200 Subject: [PATCH 074/138] Disable block length metric for `resource_version` --- Library/Homebrew/livecheck/livecheck.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index dd80df3010..98c6979a45 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -659,6 +659,7 @@ resource: false) checked_urls = [] + # rubocop:disable Metrics/BlockLength urls.each_with_index do |original_url, i| # Only preprocess the URL when it's appropriate url = if STRATEGY_SYMBOLS_TO_SKIP_PREPROCESS_URL.include?(livecheck_strategy) From 6b0574acb186e086ed85d6d84a6c457b615fced0 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Sun, 7 Aug 2022 20:23:07 +0200 Subject: [PATCH 075/138] Updated test for resource in `livecheck_version` (i.e: `ibrew tests --only=livecheck/livecheck_version`) --- .../Homebrew/test/livecheck/livecheck_version_spec.rb | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Library/Homebrew/test/livecheck/livecheck_version_spec.rb b/Library/Homebrew/test/livecheck/livecheck_version_spec.rb index 95f445cd87..dbdaad6585 100644 --- a/Library/Homebrew/test/livecheck/livecheck_version_spec.rb +++ b/Library/Homebrew/test/livecheck/livecheck_version_spec.rb @@ -6,6 +6,7 @@ require "livecheck/livecheck_version" describe Homebrew::Livecheck::LivecheckVersion do let(:formula) { instance_double(Formula) } let(:cask) { instance_double(Cask::Cask) } + let(:resource) { instance_double(Resource) } before do # Case statements use #=== for case equality purposes @@ -13,6 +14,8 @@ describe Homebrew::Livecheck::LivecheckVersion do allow(Formula).to receive(:===).with(formula).and_return(true) allow(Cask::Cask).to receive(:===).and_call_original allow(Cask::Cask).to receive(:===).with(cask).and_return(true) + allow(Resource).to receive(:===).and_call_original + allow(Resource).to receive(:===).with(resource).and_return(true) end specify "::create" do @@ -28,5 +31,12 @@ describe Homebrew::Livecheck::LivecheckVersion do .to eq ["1.0", "100", "1426778671"] expect(described_class.create(cask, Version.new("0.17.0,20210111183933,226")).versions) .to eq ["0.17.0", "20210111183933", "226"] + + expect(described_class.create(resource, Version.new("1.1.6")).versions).to eq ["1.1.6"] + expect(described_class.create(resource, Version.new("2.19.0,1.8.0")).versions).to eq ["2.19.0,1.8.0"] + expect(described_class.create(resource, Version.new("1.0,100:1426778671")).versions).to eq ["1.0,100:1426778671"] + expect(described_class.create(resource, Version.new("0.17.0,20210111183933,226")).versions) + .to eq ["0.17.0,20210111183933,226"] + end end From 3476493583bc00cf912db27efd75049010210d8d Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Sun, 7 Aug 2022 20:47:17 +0200 Subject: [PATCH 076/138] Updated `livecheck_spec.rb` for resources --- .../Homebrew/test/livecheck/livecheck_spec.rb | 44 ++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/Library/Homebrew/test/livecheck/livecheck_spec.rb b/Library/Homebrew/test/livecheck/livecheck_spec.rb index 9b68e3f94b..ba85fc6c96 100644 --- a/Library/Homebrew/test/livecheck/livecheck_spec.rb +++ b/Library/Homebrew/test/livecheck/livecheck_spec.rb @@ -26,6 +26,27 @@ describe Homebrew::Livecheck do end end + let(:f_r) do + formula("test") do + desc "Test formula with a resource" + homepage "https://brew.sh" + url "https://brew.sh/test-0.0.1.tgz" + head "https://github.com/Homebrew/brew.git" + + resource "foo" do + url "https://brew.sh/foo-1.0.tar.gz" + sha256 "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef" + + livecheck do + url "https://brew.sh/test/releases" + regex(/foo[._-]v?(\d+(?:\.\d+)+)\.t/i) + end + end + end + end + + let(:r) { f_r.resources.first } + let(:c) do Cask::CaskLoader.load(+<<-RUBY) cask "test" do @@ -72,6 +93,16 @@ describe Homebrew::Livecheck do end end + describe "::resource_name" do + it "returns the name of the resource" do + expect(livecheck.resource_name(r)).to eq("foo") + end + + it "returns the full name of the resource" do + expect(livecheck.resource_name(r, full_name: true)).to eq("test--foo") + end + end + describe "::cask_name" do it "returns the token of the cask" do expect(livecheck.cask_name(c)).to eq("test") @@ -83,7 +114,7 @@ describe Homebrew::Livecheck do end describe "::status_hash" do - it "returns a hash containing the livecheck status" do + it "returns a hash containing the livecheck status for a formula" do expect(livecheck.status_hash(f, "error", ["Unable to get versions"])) .to eq({ formula: "test", @@ -94,6 +125,17 @@ describe Homebrew::Livecheck do }, }) end + it "returns a hash containing the livecheck status for a resource" do + expect(livecheck.status_hash(r, "error", ["Unable to get versions"])) + .to eq({ + resource: "foo", + status: "error", + messages: ["Unable to get versions"], + meta: { + livecheckable: true, + }, + }) + end end describe "::livecheck_url_to_string" do From 5d90e0136afe652ecfe0f73214ee6b276408acf3 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Sun, 7 Aug 2022 20:52:46 +0200 Subject: [PATCH 077/138] Added `livecheck_url_to_string` test for resources --- .../Homebrew/test/livecheck/livecheck_spec.rb | 27 ++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/Library/Homebrew/test/livecheck/livecheck_spec.rb b/Library/Homebrew/test/livecheck/livecheck_spec.rb index ba85fc6c96..217e18899a 100644 --- a/Library/Homebrew/test/livecheck/livecheck_spec.rb +++ b/Library/Homebrew/test/livecheck/livecheck_spec.rb @@ -148,6 +148,26 @@ describe Homebrew::Livecheck do end end + let(:f_r_livecheck_url) do + formula("test_livecheck_url") do + desc "Test Livecheck URL formula" + homepage "https://brew.sh" + url "https://brew.sh/test-0.0.1.tgz" + head "https://github.com/Homebrew/brew.git" + resource "foo" do + url "https://brew.sh/foo-1.0.tar.gz" + sha256 "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef" + + livecheck do + url "https://brew.sh/test/releases" + regex(/foo[._-]v?(\d+(?:\.\d+)+)\.t/i) + end + end + end + end + + let(:r_livecheck_url) { f_r_livecheck_url.resources.first } + let(:c_livecheck_url) do Cask::CaskLoader.load(+<<-RUBY) cask "test_livecheck_url" do @@ -161,11 +181,16 @@ describe Homebrew::Livecheck do RUBY end - it "returns a URL string when given a livecheck_url string" do + it "returns a URL string when given a livecheck_url string for formula" do f_livecheck_url.livecheck.url(livecheck_url) expect(livecheck.livecheck_url_to_string(livecheck_url, f_livecheck_url)).to eq(livecheck_url) end + it "returns a URL string when given a livecheck_url string for resource" do + r_livecheck_url.livecheck.url(livecheck_url) + expect(livecheck.livecheck_url_to_string(livecheck_url, r_livecheck_url)).to eq(livecheck_url) + end + it "returns a URL symbol when given a valid livecheck_url symbol" do f_livecheck_url.livecheck.url(:head) expect(livecheck.livecheck_url_to_string(head_url, f_livecheck_url)).to eq(head_url) From eba3d5cf1c7873fabfc3bacdf29994c4e5f8495a Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Sun, 7 Aug 2022 20:58:10 +0200 Subject: [PATCH 078/138] Added tests for resource when given a valid livecheck_url symbol --- Library/Homebrew/test/livecheck/livecheck_spec.rb | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Library/Homebrew/test/livecheck/livecheck_spec.rb b/Library/Homebrew/test/livecheck/livecheck_spec.rb index 217e18899a..c8d2d16131 100644 --- a/Library/Homebrew/test/livecheck/livecheck_spec.rb +++ b/Library/Homebrew/test/livecheck/livecheck_spec.rb @@ -206,6 +206,15 @@ describe Homebrew::Livecheck do c_livecheck_url.livecheck.url(:url) expect(livecheck.livecheck_url_to_string(cask_url, c_livecheck_url)).to eq(cask_url) + + r_livecheck_url.livecheck.url(:url) + expect(livecheck.livecheck_url_to_string(cask_url, r_livecheck_url)).to eq(cask_url) + + r_livecheck_url.livecheck.url(:head) + expect(livecheck.livecheck_url_to_string(head_url, r_livecheck_url)).to eq(head_url) + + r_livecheck_url.livecheck.url(:stable) + expect(livecheck.livecheck_url_to_string(stable_url, r_livecheck_url)).to eq(stable_url) end it "returns nil when not given a string or valid symbol" do From 7ae71097eeab0501c9c2fea9cd22a5112294c1ff Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Sun, 7 Aug 2022 21:10:10 +0200 Subject: [PATCH 079/138] Added tests for resources for `livecheck_url_to_string` --- Library/Homebrew/test/livecheck/livecheck_spec.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Library/Homebrew/test/livecheck/livecheck_spec.rb b/Library/Homebrew/test/livecheck/livecheck_spec.rb index c8d2d16131..e8397d7cd8 100644 --- a/Library/Homebrew/test/livecheck/livecheck_spec.rb +++ b/Library/Homebrew/test/livecheck/livecheck_spec.rb @@ -11,6 +11,7 @@ describe Homebrew::Livecheck do let(:homepage_url) { "https://brew.sh" } let(:livecheck_url) { "https://formulae.brew.sh/api/formula/ruby.json" } let(:stable_url) { "https://brew.sh/test-0.0.1.tgz" } + let(:resource_url) { "https://brew.sh/foo-1.0.tar.gz" } let(:f) do formula("test") do @@ -220,8 +221,10 @@ describe Homebrew::Livecheck do it "returns nil when not given a string or valid symbol" do expect(livecheck.livecheck_url_to_string(nil, f_livecheck_url)).to be_nil expect(livecheck.livecheck_url_to_string(nil, c_livecheck_url)).to be_nil + expect(livecheck.livecheck_url_to_string(nil, r_livecheck_url)).to be_nil expect(livecheck.livecheck_url_to_string(:invalid_symbol, f_livecheck_url)).to be_nil expect(livecheck.livecheck_url_to_string(:invalid_symbol, c_livecheck_url)).to be_nil + expect(livecheck.livecheck_url_to_string(:invalid_symbol, r_livecheck_url)).to be_nil end end @@ -229,6 +232,7 @@ describe Homebrew::Livecheck do it "returns the list of URLs to check" do expect(livecheck.checkable_urls(f)).to eq([stable_url, head_url, homepage_url]) expect(livecheck.checkable_urls(c)).to eq([cask_url, homepage_url]) + expect(livecheck.checkable_urls(r)).to eq([resource_url]) expect(livecheck.checkable_urls(f_duplicate_urls)).to eq([stable_url, head_url]) end end From 99a32700d2c6c5986944ec83395e0b1f74381ba8 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Sun, 7 Aug 2022 21:30:23 +0200 Subject: [PATCH 080/138] Added resources' tests for `use_homebrew_curl?` method --- .../Homebrew/test/livecheck/livecheck_spec.rb | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/Library/Homebrew/test/livecheck/livecheck_spec.rb b/Library/Homebrew/test/livecheck/livecheck_spec.rb index e8397d7cd8..40bd67772a 100644 --- a/Library/Homebrew/test/livecheck/livecheck_spec.rb +++ b/Library/Homebrew/test/livecheck/livecheck_spec.rb @@ -155,6 +155,7 @@ describe Homebrew::Livecheck do homepage "https://brew.sh" url "https://brew.sh/test-0.0.1.tgz" head "https://github.com/Homebrew/brew.git" + resource "foo" do url "https://brew.sh/foo-1.0.tar.gz" sha256 "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef" @@ -254,6 +255,27 @@ describe Homebrew::Livecheck do end end + let(:f_r_homebrew_curl) do + formula("test_homebrew_curl") do + desc "Test homebrew_curl formula" + homepage "https://brew.sh" + url "https://brew.sh/test-0.0.1.tgz" + head "https://github.com/Homebrew/brew.git" + + resource "foo" do + url "https://brew.sh/foo-1.0.tar.gz", using: :homebrew_curl + sha256 "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef" + + livecheck do + url "https://brew.sh/test/releases" + regex(/foo[._-]v?(\d+(?:\.\d+)+)\.t/i) + end + end + end + end + + let(:r_homebrew_curl) { f_r_homebrew_curl.resources.first } + let(:c_homebrew_curl) do Cask::CaskLoader.load(+<<-RUBY) cask "test" do @@ -286,6 +308,13 @@ describe Homebrew::Livecheck do expect(livecheck.use_homebrew_curl?(c_homebrew_curl, example_url)).to be(false) end + it "returns `false` if a `using: homebrew_curl` is present in a resource url" do + expect(livecheck.use_homebrew_curl?(r_homebrew_curl, livecheck_url)).to be(false) + expect(livecheck.use_homebrew_curl?(r_homebrew_curl, homepage_url)).to be(false) + expect(livecheck.use_homebrew_curl?(r_homebrew_curl, stable_url)).to be(false) + expect(livecheck.use_homebrew_curl?(r_homebrew_curl, example_url)).to be(false) + end + it "returns `false` if a `using: homebrew_curl` URL is not present" do expect(livecheck.use_homebrew_curl?(f, livecheck_url)).to be(false) expect(livecheck.use_homebrew_curl?(f, homepage_url)).to be(false) @@ -299,6 +328,7 @@ describe Homebrew::Livecheck do it "returns `false` if URL string does not contain a domain" do expect(livecheck.use_homebrew_curl?(f_homebrew_curl, "test")).to be(false) + expect(livecheck.use_homebrew_curl?(r_homebrew_curl, "test")).to be(false) end end From e15f0b22b9b025f5c6e8fe3cbc5f034d577e5768 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Sun, 7 Aug 2022 21:30:56 +0200 Subject: [PATCH 081/138] Added resources' tests for `use_homebrew_curl?` method (`brew tests --only=livecheck/livecheck`) --- .../Homebrew/test/livecheck/livecheck_spec.rb | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/Library/Homebrew/test/livecheck/livecheck_spec.rb b/Library/Homebrew/test/livecheck/livecheck_spec.rb index e8397d7cd8..40bd67772a 100644 --- a/Library/Homebrew/test/livecheck/livecheck_spec.rb +++ b/Library/Homebrew/test/livecheck/livecheck_spec.rb @@ -155,6 +155,7 @@ describe Homebrew::Livecheck do homepage "https://brew.sh" url "https://brew.sh/test-0.0.1.tgz" head "https://github.com/Homebrew/brew.git" + resource "foo" do url "https://brew.sh/foo-1.0.tar.gz" sha256 "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef" @@ -254,6 +255,27 @@ describe Homebrew::Livecheck do end end + let(:f_r_homebrew_curl) do + formula("test_homebrew_curl") do + desc "Test homebrew_curl formula" + homepage "https://brew.sh" + url "https://brew.sh/test-0.0.1.tgz" + head "https://github.com/Homebrew/brew.git" + + resource "foo" do + url "https://brew.sh/foo-1.0.tar.gz", using: :homebrew_curl + sha256 "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef" + + livecheck do + url "https://brew.sh/test/releases" + regex(/foo[._-]v?(\d+(?:\.\d+)+)\.t/i) + end + end + end + end + + let(:r_homebrew_curl) { f_r_homebrew_curl.resources.first } + let(:c_homebrew_curl) do Cask::CaskLoader.load(+<<-RUBY) cask "test" do @@ -286,6 +308,13 @@ describe Homebrew::Livecheck do expect(livecheck.use_homebrew_curl?(c_homebrew_curl, example_url)).to be(false) end + it "returns `false` if a `using: homebrew_curl` is present in a resource url" do + expect(livecheck.use_homebrew_curl?(r_homebrew_curl, livecheck_url)).to be(false) + expect(livecheck.use_homebrew_curl?(r_homebrew_curl, homepage_url)).to be(false) + expect(livecheck.use_homebrew_curl?(r_homebrew_curl, stable_url)).to be(false) + expect(livecheck.use_homebrew_curl?(r_homebrew_curl, example_url)).to be(false) + end + it "returns `false` if a `using: homebrew_curl` URL is not present" do expect(livecheck.use_homebrew_curl?(f, livecheck_url)).to be(false) expect(livecheck.use_homebrew_curl?(f, homepage_url)).to be(false) @@ -299,6 +328,7 @@ describe Homebrew::Livecheck do it "returns `false` if URL string does not contain a domain" do expect(livecheck.use_homebrew_curl?(f_homebrew_curl, "test")).to be(false) + expect(livecheck.use_homebrew_curl?(r_homebrew_curl, "test")).to be(false) end end From d0355d76401c60a5b4dc900635868740ff261f9b Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Sun, 7 Aug 2022 21:49:16 +0200 Subject: [PATCH 082/138] Fixed `brew style` issues with livecheck tests --- .../Homebrew/test/livecheck/livecheck_spec.rb | 56 +++++-------------- .../test/livecheck/livecheck_version_spec.rb | 1 - 2 files changed, 15 insertions(+), 42 deletions(-) diff --git a/Library/Homebrew/test/livecheck/livecheck_spec.rb b/Library/Homebrew/test/livecheck/livecheck_spec.rb index 40bd67772a..e74426253d 100644 --- a/Library/Homebrew/test/livecheck/livecheck_spec.rb +++ b/Library/Homebrew/test/livecheck/livecheck_spec.rb @@ -11,7 +11,6 @@ describe Homebrew::Livecheck do let(:homepage_url) { "https://brew.sh" } let(:livecheck_url) { "https://formulae.brew.sh/api/formula/ruby.json" } let(:stable_url) { "https://brew.sh/test-0.0.1.tgz" } - let(:resource_url) { "https://brew.sh/foo-1.0.tar.gz" } let(:f) do formula("test") do @@ -24,15 +23,6 @@ describe Homebrew::Livecheck do url "https://formulae.brew.sh/api/formula/ruby.json" regex(/"stable":"(\d+(?:\.\d+)+)"/i) end - end - end - - let(:f_r) do - formula("test") do - desc "Test formula with a resource" - homepage "https://brew.sh" - url "https://brew.sh/test-0.0.1.tgz" - head "https://github.com/Homebrew/brew.git" resource "foo" do url "https://brew.sh/foo-1.0.tar.gz" @@ -46,7 +36,7 @@ describe Homebrew::Livecheck do end end - let(:r) { f_r.resources.first } + let(:r) { f.resources.first } let(:c) do Cask::CaskLoader.load(+<<-RUBY) @@ -66,15 +56,6 @@ describe Homebrew::Livecheck do RUBY end - let(:f_duplicate_urls) do - formula("test_duplicate_urls") do - desc "Test formula with a duplicate URL" - homepage "https://github.com/Homebrew/brew.git" - url "https://brew.sh/test-0.0.1.tgz" - head "https://github.com/Homebrew/brew.git" - end - end - describe "::resolve_livecheck_reference" do context "when a formula/cask has a livecheck block without formula/cask methods" do it "returns [nil, []]" do @@ -126,10 +107,11 @@ describe Homebrew::Livecheck do }, }) end + it "returns a hash containing the livecheck status for a resource" do expect(livecheck.status_hash(r, "error", ["Unable to get versions"])) .to eq({ - resource: "foo", + resource: "foo", status: "error", messages: ["Unable to get versions"], meta: { @@ -141,15 +123,6 @@ describe Homebrew::Livecheck do describe "::livecheck_url_to_string" do let(:f_livecheck_url) do - formula("test_livecheck_url") do - desc "Test Livecheck URL formula" - homepage "https://brew.sh" - url "https://brew.sh/test-0.0.1.tgz" - head "https://github.com/Homebrew/brew.git" - end - end - - let(:f_r_livecheck_url) do formula("test_livecheck_url") do desc "Test Livecheck URL formula" homepage "https://brew.sh" @@ -168,7 +141,7 @@ describe Homebrew::Livecheck do end end - let(:r_livecheck_url) { f_r_livecheck_url.resources.first } + let(:r_livecheck_url) { f_livecheck_url.resources.first } let(:c_livecheck_url) do Cask::CaskLoader.load(+<<-RUBY) @@ -230,6 +203,16 @@ describe Homebrew::Livecheck do end describe "::checkable_urls" do + let(:resource_url) { "https://brew.sh/foo-1.0.tar.gz" } + let(:f_duplicate_urls) do + formula("test_duplicate_urls") do + desc "Test formula with a duplicate URL" + homepage "https://github.com/Homebrew/brew.git" + url "https://brew.sh/test-0.0.1.tgz" + head "https://github.com/Homebrew/brew.git" + end + end + it "returns the list of URLs to check" do expect(livecheck.checkable_urls(f)).to eq([stable_url, head_url, homepage_url]) expect(livecheck.checkable_urls(c)).to eq([cask_url, homepage_url]) @@ -252,15 +235,6 @@ describe Homebrew::Livecheck do url "https://formulae.brew.sh/api/formula/ruby.json" regex(/"stable":"(\d+(?:\.\d+)+)"/i) end - end - end - - let(:f_r_homebrew_curl) do - formula("test_homebrew_curl") do - desc "Test homebrew_curl formula" - homepage "https://brew.sh" - url "https://brew.sh/test-0.0.1.tgz" - head "https://github.com/Homebrew/brew.git" resource "foo" do url "https://brew.sh/foo-1.0.tar.gz", using: :homebrew_curl @@ -274,7 +248,7 @@ describe Homebrew::Livecheck do end end - let(:r_homebrew_curl) { f_r_homebrew_curl.resources.first } + let(:r_homebrew_curl) { f_homebrew_curl.resources.first } let(:c_homebrew_curl) do Cask::CaskLoader.load(+<<-RUBY) diff --git a/Library/Homebrew/test/livecheck/livecheck_version_spec.rb b/Library/Homebrew/test/livecheck/livecheck_version_spec.rb index dbdaad6585..14d070ba23 100644 --- a/Library/Homebrew/test/livecheck/livecheck_version_spec.rb +++ b/Library/Homebrew/test/livecheck/livecheck_version_spec.rb @@ -37,6 +37,5 @@ describe Homebrew::Livecheck::LivecheckVersion do expect(described_class.create(resource, Version.new("1.0,100:1426778671")).versions).to eq ["1.0,100:1426778671"] expect(described_class.create(resource, Version.new("0.17.0,20210111183933,226")).versions) .to eq ["0.17.0,20210111183933,226"] - end end From 1ca2350e3561670d6fe5fa15da63d9534ed35e9d Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Sun, 7 Aug 2022 22:24:37 +0200 Subject: [PATCH 083/138] Added an error message if `--resources` flag is given with a Cask --- Library/Homebrew/livecheck/livecheck.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index 98c6979a45..0ac07948c7 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -218,6 +218,8 @@ module Homebrew formula = formula_or_cask if formula_or_cask.is_a?(Formula) cask = formula_or_cask if formula_or_cask.is_a?(Cask::Cask) + onoe "'--resources' flag does not work with a Cask" if check_resources && formula_or_cask.is_a?(Cask::Cask) + use_full_name = full_name || ambiguous_names.include?(formula_or_cask) name = formula_or_cask_name(formula_or_cask, full_name: use_full_name) From be7dde6aace68c63e660bd262c2eebe7c86103c4 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Mon, 8 Aug 2022 01:37:45 +0200 Subject: [PATCH 084/138] Minor fixes --- Library/Homebrew/livecheck/livecheck.rb | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index 0ac07948c7..eb10dc2637 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -513,7 +513,7 @@ resource: false) end end - # Returns an Array containing the formula/cask URLs that can be used by livecheck. + # Returns an Array containing the formula/resource/cask URLs that can be used by livecheck. sig { params(package_or_resource: T.any(Formula, Cask::Cask, Resource)).returns(T::Array[String]) } def checkable_urls(package_or_resource) urls = [] @@ -804,10 +804,11 @@ resource: false) res_livecheck[:cached] = true if strategy_data[:cached] == true resource_version_info[:meta][:livecheck] = res_livecheck end + # rubocop:enable Metrics/BlockLength resource_version_info end - # Identifies the latest version of the formula and returns a Hash containing + # Identifies the latest version of the formula/cask and returns a Hash containing # the version information. Returns nil if a latest version couldn't be found. # rubocop:disable Metrics/CyclomaticComplexity sig { From a169d79fee435fd87ccdea750ac4c024b826a677 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Mon, 8 Aug 2022 01:43:24 +0200 Subject: [PATCH 085/138] Updated `brew livecheck` doc --- docs/Brew-Livecheck.md | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/docs/Brew-Livecheck.md b/docs/Brew-Livecheck.md index fbbef6c7dc..6a1347ca72 100644 --- a/docs/Brew-Livecheck.md +++ b/docs/Brew-Livecheck.md @@ -1,27 +1,29 @@ # `brew livecheck` -The `brew livecheck` command finds the newest version of a formula or cask's software by checking upstream. Livecheck has [strategies](https://rubydoc.brew.sh/Homebrew/Livecheck/Strategy.html) to identify versions from various sources, such as Git repositories, websites, etc. +The `brew livecheck` command finds the newest version of a formula, resource or cask's software by checking upstream. Livecheck has [strategies](https://rubydoc.brew.sh/Homebrew/Livecheck/Strategy.html) to identify versions from various sources, such as Git repositories, websites, etc. ## Behavior When livecheck isn't given instructions for how to check for upstream versions, it does the following by default: -1. For formulae: Collect the `head`, `stable`, and `homepage` URLs, in that order. For casks: Collect the `url` and `homepage` URLs, in that order. -1. Determine if any strategies apply to the first URL. If not, try the next URL. -1. If a strategy can be applied, use it to check for new versions. -1. Return the newest version (or an error if versions could not be found at any available URLs). +1. For __formulae__: Collect the `stable`, `head` and `homepage` URLs, in that order. For __casks__: Collect the `appcast`, `url` and `homepage` URLs, in that order. For __resource__: Collect the `url` (since resource's url is considered `stable` by default) +2. Determine if any strategies apply to the first URL. If not, try the next URL. +3. If a strategy can be applied, use it to check for new versions. +4. Return the newest version (or an error if versions could not be found at any available URLs). It's sometimes necessary to override this default behavior to create a working check. If a source doesn't provide the newest version, we need to check a different one. If livecheck doesn't correctly match version text, we need to provide an appropriate regex or `strategy` block. -This can be accomplished by adding a `livecheck` block to the formula/cask. For more information on the available methods, please refer to the [`Livecheck` class documentation](https://rubydoc.brew.sh/Livecheck.html). +This can be accomplished by adding a `livecheck` block to the formula/resource/cask. For more information on the available methods, please refer to the [`Livecheck` class documentation](https://rubydoc.brew.sh/Livecheck.html). ## Creating a check -1. **Use the debug output to understand the situation**. `brew livecheck --debug |` provides information about which URLs livecheck tries, any strategies that apply, matched versions, etc. +1. **Use the debug output to understand the situation**. `brew livecheck --debug |` provides information about which URLs livecheck tries, any strategies that apply, matched versions, etc. `brew livecheck --debug --resources ` will provides livecheck's debug information about the resources as well. -1. **Research available sources to select a URL**. Try removing the file name from `stable`/`url`, to see if this is a directory listing page. If that doesn't work, try to find a page that links to the file (e.g. a download page). If it's not possible to find the newest version on the website, try checking other sources from the formula/cask. When necessary, search for other sources outside of the formula/cask. +> Note: `--resources` flag only works with Formulae. -1. **Create a regex, if necessary**. If the check works without a regex and wouldn't benefit from having one, it's usually fine to omit it. More information on creating regexes can be found in the [regex guidelines](#regex-guidelines) section. +2. **Research available sources to select a URL**. Try removing the file name from `stable`/`url`, to see if this is a directory listing page. If that doesn't work, try to find a page that links to the file (e.g. a download page). If it's not possible to find the newest version on the website, try checking other sources from the formula/cask. When necessary, search for other sources outside of the formula/cask. + +3. **Create a regex, if necessary**. If the check works without a regex and wouldn't benefit from having one, it's usually fine to omit it. More information on creating regexes can be found in the [regex guidelines](#regex-guidelines) section. ### General guidelines From d1584b67b9cc21ff387424f4e21bbf05ef610ed7 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Wed, 10 Aug 2022 20:50:14 +0200 Subject: [PATCH 086/138] Removed the error message for Cask in case `--resources` flag is given --- Library/Homebrew/livecheck/livecheck.rb | 2 -- 1 file changed, 2 deletions(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index eb10dc2637..c34f307eb2 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -218,8 +218,6 @@ module Homebrew formula = formula_or_cask if formula_or_cask.is_a?(Formula) cask = formula_or_cask if formula_or_cask.is_a?(Cask::Cask) - onoe "'--resources' flag does not work with a Cask" if check_resources && formula_or_cask.is_a?(Cask::Cask) - use_full_name = full_name || ambiguous_names.include?(formula_or_cask) name = formula_or_cask_name(formula_or_cask, full_name: use_full_name) From f9f3d3d84bf419c0a3bd90526d157d2b328a15ad Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Wed, 10 Aug 2022 22:00:08 +0200 Subject: [PATCH 087/138] Minor refractoring --- Library/Homebrew/livecheck/livecheck.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index c34f307eb2..b50da24f14 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -284,8 +284,8 @@ module Homebrew # Check current and latest resources (if "--resources" flag is given) # Only check current and latest versions if we have resources to check against - check_for_resources = check_resources && formula_or_cask.is_a?(Formula) && formula_or_cask.resources.present? - if check_for_resources + check_resources = check_resources && formula_or_cask.is_a?(Formula) && formula_or_cask.resources.present? + if check_resources resource_version_info = formula_or_cask.resources.map do |resource| resource_info = resource_version( resource, @@ -339,7 +339,7 @@ module Homebrew info[:meta][:head_only] = true if formula&.head_only? info[:meta].merge!(version_info[:meta]) if version_info.present? && version_info.key?(:meta) - info[:resources] = resource_version_info if check_for_resources + info[:resources] = resource_version_info if check_resources next if newer_only && !info[:version][:outdated] @@ -354,7 +354,7 @@ module Homebrew print_latest_version(info, verbose: verbose, ambiguous_cask: ambiguous_casks.include?(formula_or_cask), resource: false) - if check_for_resources + if check_resources resource_version_info.each do |r_info| print_latest_version( r_info, From c111a5bc9dd3b9ca94d23b678f0ac9a8be955ace Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Thu, 11 Aug 2022 21:00:28 +0200 Subject: [PATCH 088/138] Revert back changes + modified `resource_name` method --- Library/Homebrew/livecheck/livecheck.rb | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index b50da24f14..2e2233e4d1 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -284,8 +284,8 @@ module Homebrew # Check current and latest resources (if "--resources" flag is given) # Only check current and latest versions if we have resources to check against - check_resources = check_resources && formula_or_cask.is_a?(Formula) && formula_or_cask.resources.present? - if check_resources + 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| resource_info = resource_version( resource, @@ -339,7 +339,7 @@ module Homebrew info[:meta][:head_only] = true if formula&.head_only? info[:meta].merge!(version_info[:meta]) if version_info.present? && version_info.key?(:meta) - info[:resources] = resource_version_info if check_resources + info[:resources] = resource_version_info if check_for_resources next if newer_only && !info[:version][:outdated] @@ -354,7 +354,7 @@ module Homebrew print_latest_version(info, verbose: verbose, ambiguous_cask: ambiguous_casks.include?(formula_or_cask), resource: false) - if check_resources + if check_for_resources resource_version_info.each do |r_info| print_latest_version( r_info, @@ -430,7 +430,7 @@ resource: false) # provided; returns the name otherwise. sig { params(resource: Resource, full_name: T::Boolean).returns(String) } def resource_name(resource, full_name: false) - full_name ? resource.download_name : resource.name + resource.name end sig { From 54c9338ed4bb944acb8f76cd5195c246de04b64d Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Thu, 11 Aug 2022 21:25:24 +0200 Subject: [PATCH 089/138] Removed `use_homebrew_curl?` for resources --- Library/Homebrew/livecheck/livecheck.rb | 15 ++----------- .../Homebrew/test/livecheck/livecheck_spec.rb | 22 +------------------ 2 files changed, 3 insertions(+), 34 deletions(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index 2e2233e4d1..c3eeae87d6 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -583,7 +583,7 @@ resource: false) # livecheck should fetch a URL using brewed curl if the formula/resource/cask # contains a `stable`/`url` or `head` URL `using: :homebrew_curl` that # shares the same root domain. - sig { params(package_or_resource: T.any(Formula, Cask::Cask, Resource), url: String).returns(T::Boolean) } + sig { params(package_or_resource: T.any(Formula, Cask::Cask), url: String).returns(T::Boolean) } def use_homebrew_curl?(package_or_resource, url) url_root_domain = Addressable::URI.parse(url)&.domain return false if url_root_domain.blank? @@ -602,11 +602,6 @@ resource: false) when Cask::Cask return false unless package_or_resource.url.using == :homebrew_curl - domain = Addressable::URI.parse(package_or_resource.url.to_s)&.domain - homebrew_curl_root_domains << domain if domain.present? - when Resource - return false unless package_or_resource.url == :homebrew_curl - domain = Addressable::URI.parse(package_or_resource.url.to_s)&.domain homebrew_curl_root_domains << domain if domain.present? end @@ -707,14 +702,9 @@ resource: false) end next if strategy.blank? - homebrew_curl = case strategy_name - when "PageMatch", "HeaderMatch" - use_homebrew_curl?(resource, url) - end - puts "Homebrew curl?: Yes" if debug && homebrew_curl.present? strategy_data = strategy.find_versions( url: url, regex: livecheck_regex, - homebrew_curl: homebrew_curl, &livecheck_strategy_block + homebrew_curl: false, &livecheck_strategy_block ) match_version_map = strategy_data[:matches] regex = strategy_data[:regex] @@ -791,7 +781,6 @@ resource: false) res_livecheck[:url][:strategy] = strategy_data[:url] end res_livecheck[:url][:final] = strategy_data[:final_url] if strategy_data[:final_url] - res_livecheck[:url][:homebrew_curl] = homebrew_curl if homebrew_curl.present? res_livecheck[:strategy] = strategy.present? ? strategy_name : nil if strategies.present? res_livecheck[:strategies] = strategies.map do |s| diff --git a/Library/Homebrew/test/livecheck/livecheck_spec.rb b/Library/Homebrew/test/livecheck/livecheck_spec.rb index e74426253d..069f03fa0d 100644 --- a/Library/Homebrew/test/livecheck/livecheck_spec.rb +++ b/Library/Homebrew/test/livecheck/livecheck_spec.rb @@ -81,7 +81,7 @@ describe Homebrew::Livecheck do end it "returns the full name of the resource" do - expect(livecheck.resource_name(r, full_name: true)).to eq("test--foo") + expect(livecheck.resource_name(r, full_name: true)).to eq("foo") end end @@ -235,21 +235,9 @@ describe Homebrew::Livecheck do url "https://formulae.brew.sh/api/formula/ruby.json" regex(/"stable":"(\d+(?:\.\d+)+)"/i) end - - resource "foo" do - url "https://brew.sh/foo-1.0.tar.gz", using: :homebrew_curl - sha256 "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef" - - livecheck do - url "https://brew.sh/test/releases" - regex(/foo[._-]v?(\d+(?:\.\d+)+)\.t/i) - end - end end end - let(:r_homebrew_curl) { f_homebrew_curl.resources.first } - let(:c_homebrew_curl) do Cask::CaskLoader.load(+<<-RUBY) cask "test" do @@ -282,13 +270,6 @@ describe Homebrew::Livecheck do expect(livecheck.use_homebrew_curl?(c_homebrew_curl, example_url)).to be(false) end - it "returns `false` if a `using: homebrew_curl` is present in a resource url" do - expect(livecheck.use_homebrew_curl?(r_homebrew_curl, livecheck_url)).to be(false) - expect(livecheck.use_homebrew_curl?(r_homebrew_curl, homepage_url)).to be(false) - expect(livecheck.use_homebrew_curl?(r_homebrew_curl, stable_url)).to be(false) - expect(livecheck.use_homebrew_curl?(r_homebrew_curl, example_url)).to be(false) - end - it "returns `false` if a `using: homebrew_curl` URL is not present" do expect(livecheck.use_homebrew_curl?(f, livecheck_url)).to be(false) expect(livecheck.use_homebrew_curl?(f, homepage_url)).to be(false) @@ -302,7 +283,6 @@ describe Homebrew::Livecheck do it "returns `false` if URL string does not contain a domain" do expect(livecheck.use_homebrew_curl?(f_homebrew_curl, "test")).to be(false) - expect(livecheck.use_homebrew_curl?(r_homebrew_curl, "test")).to be(false) end end From 2ae583c836e410dc59d72b13b87daa0ac5a2bdf4 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Thu, 11 Aug 2022 21:50:54 +0200 Subject: [PATCH 090/138] Removed `resource_name` method --- Library/Homebrew/livecheck/livecheck.rb | 17 ++++------------- .../Homebrew/test/livecheck/livecheck_spec.rb | 10 ---------- 2 files changed, 4 insertions(+), 23 deletions(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index c3eeae87d6..bf986c6324 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -398,15 +398,13 @@ resource: false) puts JSON.pretty_generate(formulae_checked.compact) end - sig { params(formula_or_cask: T.any(Formula, Cask::Cask, Resource), full_name: T::Boolean).returns(String) } + sig { params(formula_or_cask: T.any(Formula, Cask::Cask), full_name: T::Boolean).returns(String) } def formula_or_cask_name(formula_or_cask, full_name: false) case formula_or_cask when Formula formula_name(formula_or_cask, full_name: full_name) when Cask::Cask cask_name(formula_or_cask, full_name: full_name) - when Resource - resource_name(formula_or_cask, full_name: full_name) else T.absurd(formula_or_cask) end @@ -426,13 +424,6 @@ resource: false) full_name ? formula.full_name : formula.name end - # Returns the fully-qualified name of a resource if the `full_name` argument is - # provided; returns the name otherwise. - sig { params(resource: Resource, full_name: T::Boolean).returns(String) } - def resource_name(resource, full_name: false) - resource.name - end - sig { params( package_or_resource: T.any(Formula, Cask::Cask, Resource), @@ -453,7 +444,7 @@ resource: false) elsif cask status_hash[:cask] = cask_name(cask, full_name: full_name) elsif resource - status_hash[:resource] = resource_name(resource, full_name: full_name) + status_hash[:resource] = resource.name end status_hash[:status] = status_str status_hash[:messages] = messages if messages.is_a?(Array) @@ -632,7 +623,7 @@ resource: false) if debug puts "\n\n" - puts "Resource: #{resource_name(resource, full_name: full_name)}" + puts "Resource: #{resource.name}" puts "Livecheckable?: #{has_livecheckable ? "Yes" : "No"}" end @@ -758,7 +749,7 @@ resource: false) is_outdated = (res_current != res_latest) && !is_newer_than_upstream resource_version_info = { - resource: resource_name(resource, full_name: full_name), + resource: resource.name, version: { current: res_current.to_s, latest: res_latest.to_s, diff --git a/Library/Homebrew/test/livecheck/livecheck_spec.rb b/Library/Homebrew/test/livecheck/livecheck_spec.rb index 069f03fa0d..a9f31774fa 100644 --- a/Library/Homebrew/test/livecheck/livecheck_spec.rb +++ b/Library/Homebrew/test/livecheck/livecheck_spec.rb @@ -75,16 +75,6 @@ describe Homebrew::Livecheck do end end - describe "::resource_name" do - it "returns the name of the resource" do - expect(livecheck.resource_name(r)).to eq("foo") - end - - it "returns the full name of the resource" do - expect(livecheck.resource_name(r, full_name: true)).to eq("foo") - end - end - describe "::cask_name" do it "returns the token of the cask" do expect(livecheck.cask_name(c)).to eq("test") From beb4f02ae3f080e3e0e5904b17d3484fd60e2d80 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Thu, 11 Aug 2022 21:59:53 +0200 Subject: [PATCH 091/138] Revert back changes in `doc` and `completions` --- completions/bash/brew | 1 - completions/fish/brew.fish | 3 +-- completions/zsh/_brew | 3 +-- docs/Brew-Livecheck.md | 20 +++++++++----------- 4 files changed, 11 insertions(+), 16 deletions(-) diff --git a/completions/bash/brew b/completions/bash/brew index b9a439efb2..7ee107cea1 100644 --- a/completions/bash/brew +++ b/completions/bash/brew @@ -1349,7 +1349,6 @@ _brew_livecheck() { --cask --debug --formula - --resources --full-name --help --installed diff --git a/completions/fish/brew.fish b/completions/fish/brew.fish index 762412032e..17e0059810 100644 --- a/completions/fish/brew.fish +++ b/completions/fish/brew.fish @@ -958,12 +958,11 @@ __fish_brew_complete_arg 'list; and not __fish_seen_argument -l cask -l casks' - __fish_brew_complete_arg 'list; and not __fish_seen_argument -l formula -l formulae' -a '(__fish_brew_suggest_casks_installed)' -__fish_brew_complete_cmd 'livecheck' 'Check for newer versions of formulae, resources and/or casks from upstream' +__fish_brew_complete_cmd 'livecheck' 'Check for newer versions of formulae and/or casks from upstream' __fish_brew_complete_arg 'livecheck' -l all -d 'Check all available formulae/casks' __fish_brew_complete_arg 'livecheck' -l cask -d 'Only check casks' __fish_brew_complete_arg 'livecheck' -l debug -d 'Display any debugging information' __fish_brew_complete_arg 'livecheck' -l formula -d 'Only check formulae' -__fish_brew_complete_arg 'livecheck' -l resources -d 'Also check resources for formulae' __fish_brew_complete_arg 'livecheck' -l full-name -d 'Print formulae/casks with fully-qualified names' __fish_brew_complete_arg 'livecheck' -l help -d 'Show this message' __fish_brew_complete_arg 'livecheck' -l installed -d 'Check formulae/casks that are currently installed' diff --git a/completions/zsh/_brew b/completions/zsh/_brew index 208c74ccb7..e8b6c5d327 100644 --- a/completions/zsh/_brew +++ b/completions/zsh/_brew @@ -175,7 +175,7 @@ __brew_internal_commands() { 'link:Symlink all of formula'\''s installed files into Homebrew'\''s prefix' 'linkage:Check the library links from the given formula kegs' 'list:List all installed formulae and casks' - 'livecheck:Check for newer versions of formulae, resources and/or casks from upstream' + 'livecheck:Check for newer versions of formulae and/or casks from upstream' 'log:Show the `git log` for formula or cask, or show the log for the Homebrew repository if no formula or cask is provided' 'migrate:Migrate renamed packages to new names, where formula are old names of packages' 'missing:Check the given formula kegs for missing dependencies' @@ -1180,7 +1180,6 @@ _brew_livecheck() { '--quiet[Suppress warnings, don'\''t print a progress bar for JSON output]' \ '(--all --installed)--tap[Check formulae/casks within the given tap, specified as user`/`repo]' \ '--verbose[Make some output more verbose]' \ - '--resources[Also check resources for formulae]' \ - formula \ '(--cask)--formula[Only check formulae]' \ '*::formula:__brew_formulae' \ diff --git a/docs/Brew-Livecheck.md b/docs/Brew-Livecheck.md index 6a1347ca72..fbbef6c7dc 100644 --- a/docs/Brew-Livecheck.md +++ b/docs/Brew-Livecheck.md @@ -1,29 +1,27 @@ # `brew livecheck` -The `brew livecheck` command finds the newest version of a formula, resource or cask's software by checking upstream. Livecheck has [strategies](https://rubydoc.brew.sh/Homebrew/Livecheck/Strategy.html) to identify versions from various sources, such as Git repositories, websites, etc. +The `brew livecheck` command finds the newest version of a formula or cask's software by checking upstream. Livecheck has [strategies](https://rubydoc.brew.sh/Homebrew/Livecheck/Strategy.html) to identify versions from various sources, such as Git repositories, websites, etc. ## Behavior When livecheck isn't given instructions for how to check for upstream versions, it does the following by default: -1. For __formulae__: Collect the `stable`, `head` and `homepage` URLs, in that order. For __casks__: Collect the `appcast`, `url` and `homepage` URLs, in that order. For __resource__: Collect the `url` (since resource's url is considered `stable` by default) -2. Determine if any strategies apply to the first URL. If not, try the next URL. -3. If a strategy can be applied, use it to check for new versions. -4. Return the newest version (or an error if versions could not be found at any available URLs). +1. For formulae: Collect the `head`, `stable`, and `homepage` URLs, in that order. For casks: Collect the `url` and `homepage` URLs, in that order. +1. Determine if any strategies apply to the first URL. If not, try the next URL. +1. If a strategy can be applied, use it to check for new versions. +1. Return the newest version (or an error if versions could not be found at any available URLs). It's sometimes necessary to override this default behavior to create a working check. If a source doesn't provide the newest version, we need to check a different one. If livecheck doesn't correctly match version text, we need to provide an appropriate regex or `strategy` block. -This can be accomplished by adding a `livecheck` block to the formula/resource/cask. For more information on the available methods, please refer to the [`Livecheck` class documentation](https://rubydoc.brew.sh/Livecheck.html). +This can be accomplished by adding a `livecheck` block to the formula/cask. For more information on the available methods, please refer to the [`Livecheck` class documentation](https://rubydoc.brew.sh/Livecheck.html). ## Creating a check -1. **Use the debug output to understand the situation**. `brew livecheck --debug |` provides information about which URLs livecheck tries, any strategies that apply, matched versions, etc. `brew livecheck --debug --resources ` will provides livecheck's debug information about the resources as well. +1. **Use the debug output to understand the situation**. `brew livecheck --debug |` provides information about which URLs livecheck tries, any strategies that apply, matched versions, etc. -> Note: `--resources` flag only works with Formulae. +1. **Research available sources to select a URL**. Try removing the file name from `stable`/`url`, to see if this is a directory listing page. If that doesn't work, try to find a page that links to the file (e.g. a download page). If it's not possible to find the newest version on the website, try checking other sources from the formula/cask. When necessary, search for other sources outside of the formula/cask. -2. **Research available sources to select a URL**. Try removing the file name from `stable`/`url`, to see if this is a directory listing page. If that doesn't work, try to find a page that links to the file (e.g. a download page). If it's not possible to find the newest version on the website, try checking other sources from the formula/cask. When necessary, search for other sources outside of the formula/cask. - -3. **Create a regex, if necessary**. If the check works without a regex and wouldn't benefit from having one, it's usually fine to omit it. More information on creating regexes can be found in the [regex guidelines](#regex-guidelines) section. +1. **Create a regex, if necessary**. If the check works without a regex and wouldn't benefit from having one, it's usually fine to omit it. More information on creating regexes can be found in the [regex guidelines](#regex-guidelines) section. ### General guidelines From 93ebe42a72e33e40c2c4c355f0cbc3e996599730 Mon Sep 17 00:00:00 2001 From: hyuraku <32809703+hyuraku@users.noreply.github.com> Date: Mon, 15 Aug 2022 21:48:57 +0900 Subject: [PATCH 092/138] add dry-run option to cask#install --- Library/Homebrew/cask/cmd/install.rb | 4 +++- Library/Homebrew/cask/installer.rb | 9 +++++++-- Library/Homebrew/cmd/install.rb | 3 +++ 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/Library/Homebrew/cask/cmd/install.rb b/Library/Homebrew/cask/cmd/install.rb index 69bd9d80fa..2d477f10e8 100644 --- a/Library/Homebrew/cask/cmd/install.rb +++ b/Library/Homebrew/cask/cmd/install.rb @@ -56,7 +56,8 @@ module Cask require_sha: nil, quarantine: nil, quiet: nil, - zap: nil + zap: nil, + dry_run: nil ) odie "Installing casks is supported only on macOS" unless OS.mac? @@ -69,6 +70,7 @@ module Cask quarantine: quarantine, quiet: quiet, zap: zap, + dry_run: dry_run, }.compact options[:quarantine] = true if options[:quarantine].nil? diff --git a/Library/Homebrew/cask/installer.rb b/Library/Homebrew/cask/installer.rb index c0417e311d..e13eb423e3 100644 --- a/Library/Homebrew/cask/installer.rb +++ b/Library/Homebrew/cask/installer.rb @@ -24,7 +24,7 @@ module Cask skip_cask_deps: false, binaries: true, verbose: false, zap: false, require_sha: false, upgrade: false, installed_as_dependency: false, quarantine: true, - verify_download_integrity: true, quiet: false) + verify_download_integrity: true, quiet: false, dry_run: false) @cask = cask @command = command @force = force @@ -39,11 +39,12 @@ module Cask @quarantine = quarantine @verify_download_integrity = verify_download_integrity @quiet = quiet + @dry_run = dry_run end attr_predicate :binaries?, :force?, :skip_cask_deps?, :require_sha?, :reinstall?, :upgrade?, :verbose?, :zap?, :installed_as_dependency?, - :quarantine?, :quiet? + :quarantine?, :quiet?, :dry_run? def self.caveats(cask) odebug "Printing caveats" @@ -96,6 +97,10 @@ module Cask check_conflicts print caveats + if dry_run? + puts "#{Formatter.identifier(@cask)} would be installed" + exit + end fetch uninstall_existing_cask if reinstall? diff --git a/Library/Homebrew/cmd/install.rb b/Library/Homebrew/cmd/install.rb index a312190440..2acb56baba 100644 --- a/Library/Homebrew/cmd/install.rb +++ b/Library/Homebrew/cmd/install.rb @@ -45,6 +45,8 @@ module Homebrew "(binaries and symlinks are excluded, unless originally from the same cask)." switch "-v", "--verbose", description: "Print the verification and postinstall steps." + switch "-n", "--dry-run", + description: "Show what would be installed, but do not actually install anything." [ [:switch, "--formula", "--formulae", { description: "Treat all named arguments as formulae.", @@ -193,6 +195,7 @@ module Homebrew skip_cask_deps: args.skip_cask_deps?, quarantine: args.quarantine?, quiet: args.quiet?, + dry_run: args.dry_run?, ) end From 634fcad1b230fabe3a6b6d094541b0151178867f Mon Sep 17 00:00:00 2001 From: hyuraku <32809703+hyuraku@users.noreply.github.com> Date: Tue, 16 Aug 2022 20:59:01 +0900 Subject: [PATCH 093/138] add dry-run option to formula#install --- Library/Homebrew/cmd/install.rb | 4 +++- Library/Homebrew/formula_installer.rb | 11 +++++++++-- Library/Homebrew/install.rb | 4 +++- Library/Homebrew/upgrade.rb | 1 + 4 files changed, 16 insertions(+), 4 deletions(-) diff --git a/Library/Homebrew/cmd/install.rb b/Library/Homebrew/cmd/install.rb index 2acb56baba..60f2733cd1 100644 --- a/Library/Homebrew/cmd/install.rb +++ b/Library/Homebrew/cmd/install.rb @@ -245,6 +245,7 @@ module Homebrew debug: args.debug?, quiet: args.quiet?, verbose: args.verbose?, + dry_run: args.dry_run?, ) Upgrade.check_installed_dependents( @@ -260,9 +261,10 @@ module Homebrew debug: args.debug?, quiet: args.quiet?, verbose: args.verbose?, + dry_run: args.dry_run?, ) - Cleanup.periodic_clean! + Cleanup.periodic_clean!(dry_run: args.dry_run?) Homebrew.messages.display_messages(display_times: args.display_times?) rescue FormulaUnreadableError, FormulaClassUnavailableError, diff --git a/Library/Homebrew/formula_installer.rb b/Library/Homebrew/formula_installer.rb index e895c09215..759fb247c7 100644 --- a/Library/Homebrew/formula_installer.rb +++ b/Library/Homebrew/formula_installer.rb @@ -40,7 +40,7 @@ class FormulaInstaller attr_predicate :show_summary_heading?, :show_header? attr_predicate :force_bottle?, :ignore_deps?, :only_deps?, :interactive?, :git?, :force?, :overwrite?, :keep_tmp? attr_predicate :debug_symbols? - attr_predicate :verbose?, :debug?, :quiet? + attr_predicate :verbose?, :debug?, :quiet?, :dry_run? def initialize( formula, @@ -66,7 +66,8 @@ class FormulaInstaller overwrite: false, debug: false, quiet: false, - verbose: false + verbose: false, + dry_run: false ) @formula = formula @env = env @@ -90,6 +91,7 @@ class FormulaInstaller @verbose = verbose @quiet = quiet @debug = debug + @dry_run = dry_run @installed_as_dependency = installed_as_dependency @installed_on_request = installed_on_request @options = options @@ -696,6 +698,7 @@ class FormulaInstaller debug: debug?, quiet: quiet?, verbose: verbose?, + dry_run: dry_run?, ) fi.prelude fi.fetch @@ -1182,6 +1185,10 @@ class FormulaInstaller return if self.class.fetched.include?(formula) fetch_dependencies + if dry_run? + puts "#{Formatter.identifier(formula.full_name)} would be installed" + return + end return if only_deps? diff --git a/Library/Homebrew/install.rb b/Library/Homebrew/install.rb index 3d838dac3e..8154dd1325 100644 --- a/Library/Homebrew/install.rb +++ b/Library/Homebrew/install.rb @@ -274,7 +274,8 @@ module Homebrew overwrite: false, debug: false, quiet: false, - verbose: false + verbose: false, + dry_run: false ) formula_installers = formulae_to_install.map do |f| Migrator.migrate_if_needed(f, force: force) @@ -300,6 +301,7 @@ module Homebrew debug: debug, quiet: quiet, verbose: verbose, + dry_run: dry_run, ) begin diff --git a/Library/Homebrew/upgrade.rb b/Library/Homebrew/upgrade.rb index 54e3223c18..82b6b7a691 100644 --- a/Library/Homebrew/upgrade.rb +++ b/Library/Homebrew/upgrade.rb @@ -208,6 +208,7 @@ module Homebrew # possible for the existing build to interfere with the build we are about to # do! Seriously, it happens! kegs.each(&:unlink) if kegs.present? + return if formula_installer.dry_run? formula_installer.install formula_installer.finish From 8a7f445d1f1095cf2587f6d4e3e9fde630459f7e Mon Sep 17 00:00:00 2001 From: hyuraku <32809703+hyuraku@users.noreply.github.com> Date: Wed, 17 Aug 2022 22:14:05 +0900 Subject: [PATCH 094/138] repair how to show casks to be installed --- Library/Homebrew/cask/cmd/install.rb | 21 ++++++++++++++++++++- Library/Homebrew/cask/installer.rb | 11 +++-------- 2 files changed, 23 insertions(+), 9 deletions(-) diff --git a/Library/Homebrew/cask/cmd/install.rb b/Library/Homebrew/cask/cmd/install.rb index 2d477f10e8..6c4d71572a 100644 --- a/Library/Homebrew/cask/cmd/install.rb +++ b/Library/Homebrew/cask/cmd/install.rb @@ -70,14 +70,33 @@ module Cask quarantine: quarantine, quiet: quiet, zap: zap, - dry_run: dry_run, }.compact options[:quarantine] = true if options[:quarantine].nil? + if dry_run + casks_to_install = casks.reject(&:installed?) + if casks_to_install.present? + ohai "Would install #{casks_to_install.count} #{"package".pluralize(casks_to_install.count)}:" + puts casks_to_install.map(&:full_name).join(" ") + end + end + require "cask/installer" casks.each do |cask| + if dry_run + dep_names = CaskDependent.new(cask) + .runtime_dependencies + .reject(&:installed?) + .map(&:to_formula) + .map(&:name) + if dep_names.present? + ohai "Would install #{dep_names.count} #{"dependency".pluralize(dep_names.count)} for #{cask.full_name}:" + puts dep_names.join(" ") + end + next + end Installer.new(cask, **options).install rescue CaskAlreadyInstalledError => e opoo e.message diff --git a/Library/Homebrew/cask/installer.rb b/Library/Homebrew/cask/installer.rb index e13eb423e3..18337bd043 100644 --- a/Library/Homebrew/cask/installer.rb +++ b/Library/Homebrew/cask/installer.rb @@ -24,7 +24,7 @@ module Cask skip_cask_deps: false, binaries: true, verbose: false, zap: false, require_sha: false, upgrade: false, installed_as_dependency: false, quarantine: true, - verify_download_integrity: true, quiet: false, dry_run: false) + verify_download_integrity: true, quiet: false) @cask = cask @command = command @force = force @@ -39,12 +39,11 @@ module Cask @quarantine = quarantine @verify_download_integrity = verify_download_integrity @quiet = quiet - @dry_run = dry_run end attr_predicate :binaries?, :force?, :skip_cask_deps?, :require_sha?, :reinstall?, :upgrade?, :verbose?, :zap?, :installed_as_dependency?, - :quarantine?, :quiet?, :dry_run? + :quarantine?, :quiet? def self.caveats(cask) odebug "Printing caveats" @@ -97,13 +96,9 @@ module Cask check_conflicts print caveats - if dry_run? - puts "#{Formatter.identifier(@cask)} would be installed" - exit - end + fetch uninstall_existing_cask if reinstall? - backup if force? && @cask.staged_path.exist? && @cask.metadata_versioned_path.exist? oh1 "Installing Cask #{Formatter.identifier(@cask)}" From 66817c0c320c8fcf27de47923d0657c87fbf08f6 Mon Sep 17 00:00:00 2001 From: hyuraku <32809703+hyuraku@users.noreply.github.com> Date: Wed, 17 Aug 2022 22:14:20 +0900 Subject: [PATCH 095/138] repair how to show formula to be installed --- Library/Homebrew/formula_installer.rb | 4 ---- Library/Homebrew/install.rb | 32 ++++++++++++++++++++++++--- Library/Homebrew/upgrade.rb | 1 - 3 files changed, 29 insertions(+), 8 deletions(-) diff --git a/Library/Homebrew/formula_installer.rb b/Library/Homebrew/formula_installer.rb index 759fb247c7..aa25be9bbd 100644 --- a/Library/Homebrew/formula_installer.rb +++ b/Library/Homebrew/formula_installer.rb @@ -1185,10 +1185,6 @@ class FormulaInstaller return if self.class.fetched.include?(formula) fetch_dependencies - if dry_run? - puts "#{Formatter.identifier(formula.full_name)} would be installed" - return - end return if only_deps? diff --git a/Library/Homebrew/install.rb b/Library/Homebrew/install.rb index 8154dd1325..382ecb8076 100644 --- a/Library/Homebrew/install.rb +++ b/Library/Homebrew/install.rb @@ -278,7 +278,7 @@ module Homebrew dry_run: false ) formula_installers = formulae_to_install.map do |f| - Migrator.migrate_if_needed(f, force: force) + Migrator.migrate_if_needed(f, force: force, dry_run: dry_run) build_options = f.build fi = FormulaInstaller.new( @@ -305,8 +305,10 @@ module Homebrew ) begin - fi.prelude - fi.fetch + unless dry_run + fi.prelude + fi.fetch + end fi rescue CannotInstallFormulaError => e ofail e.message @@ -317,6 +319,14 @@ module Homebrew end end.compact + if dry_run + formulae_name_to_install = formulae_to_install.map(&:name) + if formulae_name_to_install.present? + ohai "Would install #{formulae_name_to_install.count} #{"package".pluralize(formulae_name_to_install.count)}:" + puts formulae_name_to_install.join(" ") + end + end + formula_installers.each do |fi| install_formula(fi) Cleanup.install_formula_clean!(fi.formula) @@ -326,11 +336,27 @@ module Homebrew def install_formula(formula_installer) f = formula_installer.formula + if formula_installer.dry_run? + print_dry_run_dependencies(f, formula_installer.compute_dependencies) + return + end + upgrade = f.linked? && f.outdated? && !f.head? && !Homebrew::EnvConfig.no_install_upgrade? Upgrade.install_formula(formula_installer, upgrade: upgrade) end private_class_method :install_formula + + def print_dry_run_dependencies(formula, dependencies) + return unless dependencies.present? + + plural = "dependency".pluralize(dependencies.count) + ohai "Would install #{dependencies.count} #{plural} for #{formula.name}:" + formula_names = dependencies.map(&:first).map(&:to_formula).map(&:name) + puts formula_names.join(" ") + end + + private_class_method :print_dry_run_dependencies end end diff --git a/Library/Homebrew/upgrade.rb b/Library/Homebrew/upgrade.rb index 82b6b7a691..54e3223c18 100644 --- a/Library/Homebrew/upgrade.rb +++ b/Library/Homebrew/upgrade.rb @@ -208,7 +208,6 @@ module Homebrew # possible for the existing build to interfere with the build we are about to # do! Seriously, it happens! kegs.each(&:unlink) if kegs.present? - return if formula_installer.dry_run? formula_installer.install formula_installer.finish From 1bfcf314ac855275d342021fdd1e783d00e3106d Mon Sep 17 00:00:00 2001 From: hyuraku <32809703+hyuraku@users.noreply.github.com> Date: Thu, 18 Aug 2022 00:16:11 +0900 Subject: [PATCH 096/138] repair style --- Library/Homebrew/cask/cmd/install.rb | 6 ++++-- Library/Homebrew/install.rb | 7 ++++--- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/Library/Homebrew/cask/cmd/install.rb b/Library/Homebrew/cask/cmd/install.rb index 6c4d71572a..82333efb68 100644 --- a/Library/Homebrew/cask/cmd/install.rb +++ b/Library/Homebrew/cask/cmd/install.rb @@ -77,7 +77,8 @@ module Cask if dry_run casks_to_install = casks.reject(&:installed?) if casks_to_install.present? - ohai "Would install #{casks_to_install.count} #{"package".pluralize(casks_to_install.count)}:" + plural = "package".pluralize(casks_to_install.count) + ohai "Would install #{casks_to_install.count} #{plural}:" puts casks_to_install.map(&:full_name).join(" ") end end @@ -92,7 +93,8 @@ module Cask .map(&:to_formula) .map(&:name) if dep_names.present? - ohai "Would install #{dep_names.count} #{"dependency".pluralize(dep_names.count)} for #{cask.full_name}:" + plural = "dependency".pluralize(dep_names.count) + ohai "Would install #{dep_names.count} #{plural} for #{cask.full_name}:" puts dep_names.join(" ") end next diff --git a/Library/Homebrew/install.rb b/Library/Homebrew/install.rb index 382ecb8076..5cb3d09380 100644 --- a/Library/Homebrew/install.rb +++ b/Library/Homebrew/install.rb @@ -322,7 +322,8 @@ module Homebrew if dry_run formulae_name_to_install = formulae_to_install.map(&:name) if formulae_name_to_install.present? - ohai "Would install #{formulae_name_to_install.count} #{"package".pluralize(formulae_name_to_install.count)}:" + plural = "package".pluralize(casks_to_install.count) + ohai "Would install #{formulae_name_to_install.count} #{plural}:" puts formulae_name_to_install.join(" ") end end @@ -348,11 +349,11 @@ module Homebrew private_class_method :install_formula def print_dry_run_dependencies(formula, dependencies) - return unless dependencies.present? + return if dependencies.empry? plural = "dependency".pluralize(dependencies.count) ohai "Would install #{dependencies.count} #{plural} for #{formula.name}:" - formula_names = dependencies.map(&:first).map(&:to_formula).map(&:name) + formula_names = dependencies.map(&:first).map(&:to_formula).map(&:name) puts formula_names.join(" ") end From 9377346bdf8f2d13d265b1b5fa39bb77ce998909 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Wed, 17 Aug 2022 17:41:34 +0200 Subject: [PATCH 097/138] Minor fixes --- Library/Homebrew/livecheck/livecheck.rb | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index bf986c6324..57d3e06d1c 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -269,6 +269,7 @@ module Homebrew end current_str = current.to_s + current = LivecheckVersion.create(formula_or_cask, current) latest = if formula&.head_only? formula.head.downloader.fetch_last_commit @@ -287,14 +288,13 @@ module Homebrew 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| - resource_info = resource_version( + resource_version( resource, json: json, full_name: use_full_name, verbose: verbose, debug: debug, ) - resource_info end end @@ -313,6 +313,7 @@ module Homebrew end latest_str = latest.to_s + latest = LivecheckVersion.create(formula_or_cask, latest) is_outdated = if formula&.head_only? # A HEAD-only formula is considered outdated if the latest upstream @@ -623,8 +624,8 @@ resource: false) if debug puts "\n\n" - puts "Resource: #{resource.name}" - puts "Livecheckable?: #{has_livecheckable ? "Yes" : "No"}" + puts "Resource: #{resource.name}" + puts "Livecheckable?: #{has_livecheckable ? "Yes" : "No"}" end resource_version_info = {} From 4bbcab235b69e44affc31a47179a80a818b50c3e Mon Sep 17 00:00:00 2001 From: hyuraku <32809703+hyuraku@users.noreply.github.com> Date: Fri, 19 Aug 2022 20:08:38 +0900 Subject: [PATCH 098/138] change local variable --- Library/Homebrew/install.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Library/Homebrew/install.rb b/Library/Homebrew/install.rb index 5cb3d09380..953b7545b0 100644 --- a/Library/Homebrew/install.rb +++ b/Library/Homebrew/install.rb @@ -322,7 +322,7 @@ module Homebrew if dry_run formulae_name_to_install = formulae_to_install.map(&:name) if formulae_name_to_install.present? - plural = "package".pluralize(casks_to_install.count) + plural = "package".pluralize(formulae_name_to_install.count) ohai "Would install #{formulae_name_to_install.count} #{plural}:" puts formulae_name_to_install.join(" ") end From 0f544be8ffdc42a227b288566a4ab43e38cf95d3 Mon Sep 17 00:00:00 2001 From: hyuraku <32809703+hyuraku@users.noreply.github.com> Date: Fri, 19 Aug 2022 21:43:41 +0900 Subject: [PATCH 099/138] remove dry-run option from FormulaInstaller --- Library/Homebrew/formula_installer.rb | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/Library/Homebrew/formula_installer.rb b/Library/Homebrew/formula_installer.rb index aa25be9bbd..e895c09215 100644 --- a/Library/Homebrew/formula_installer.rb +++ b/Library/Homebrew/formula_installer.rb @@ -40,7 +40,7 @@ class FormulaInstaller attr_predicate :show_summary_heading?, :show_header? attr_predicate :force_bottle?, :ignore_deps?, :only_deps?, :interactive?, :git?, :force?, :overwrite?, :keep_tmp? attr_predicate :debug_symbols? - attr_predicate :verbose?, :debug?, :quiet?, :dry_run? + attr_predicate :verbose?, :debug?, :quiet? def initialize( formula, @@ -66,8 +66,7 @@ class FormulaInstaller overwrite: false, debug: false, quiet: false, - verbose: false, - dry_run: false + verbose: false ) @formula = formula @env = env @@ -91,7 +90,6 @@ class FormulaInstaller @verbose = verbose @quiet = quiet @debug = debug - @dry_run = dry_run @installed_as_dependency = installed_as_dependency @installed_on_request = installed_on_request @options = options @@ -698,7 +696,6 @@ class FormulaInstaller debug: debug?, quiet: quiet?, verbose: verbose?, - dry_run: dry_run?, ) fi.prelude fi.fetch From b61ae5942166e9ffcd49b0595fddcb726cd36f75 Mon Sep 17 00:00:00 2001 From: hyuraku <32809703+hyuraku@users.noreply.github.com> Date: Fri, 19 Aug 2022 21:43:57 +0900 Subject: [PATCH 100/138] repair syntax --- Library/Homebrew/cask/cmd/install.rb | 24 ++++++++++++------------ Library/Homebrew/cask/installer.rb | 2 +- Library/Homebrew/install.rb | 14 +++++++------- 3 files changed, 20 insertions(+), 20 deletions(-) diff --git a/Library/Homebrew/cask/cmd/install.rb b/Library/Homebrew/cask/cmd/install.rb index 82333efb68..fb410b83d5 100644 --- a/Library/Homebrew/cask/cmd/install.rb +++ b/Library/Homebrew/cask/cmd/install.rb @@ -81,24 +81,24 @@ module Cask ohai "Would install #{casks_to_install.count} #{plural}:" puts casks_to_install.map(&:full_name).join(" ") end - end - - require "cask/installer" - - casks.each do |cask| - if dry_run + casks.each do |cask| dep_names = CaskDependent.new(cask) .runtime_dependencies .reject(&:installed?) .map(&:to_formula) .map(&:name) - if dep_names.present? - plural = "dependency".pluralize(dep_names.count) - ohai "Would install #{dep_names.count} #{plural} for #{cask.full_name}:" - puts dep_names.join(" ") - end - next + next if dep_names.blank? + + plural = "dependency".pluralize(dep_names.count) + ohai "Would install #{dep_names.count} #{plural} for #{cask.full_name}:" + puts dep_names.join(" ") end + return + end + + require "cask/installer" + + casks.each do |cask| Installer.new(cask, **options).install rescue CaskAlreadyInstalledError => e opoo e.message diff --git a/Library/Homebrew/cask/installer.rb b/Library/Homebrew/cask/installer.rb index 18337bd043..9ef2b3bea2 100644 --- a/Library/Homebrew/cask/installer.rb +++ b/Library/Homebrew/cask/installer.rb @@ -96,8 +96,8 @@ module Cask check_conflicts print caveats - fetch + uninstall_existing_cask if reinstall? backup if force? && @cask.staged_path.exist? && @cask.metadata_versioned_path.exist? diff --git a/Library/Homebrew/install.rb b/Library/Homebrew/install.rb index 953b7545b0..9a4cddc3b9 100644 --- a/Library/Homebrew/install.rb +++ b/Library/Homebrew/install.rb @@ -301,7 +301,6 @@ module Homebrew debug: debug, quiet: quiet, verbose: verbose, - dry_run: dry_run, ) begin @@ -325,7 +324,13 @@ module Homebrew plural = "package".pluralize(formulae_name_to_install.count) ohai "Would install #{formulae_name_to_install.count} #{plural}:" puts formulae_name_to_install.join(" ") + + formula_installers.each do |fi| + f = fi.formula + print_dry_run_dependencies(f, fi.compute_dependencies) + end end + return end formula_installers.each do |fi| @@ -337,11 +342,6 @@ module Homebrew def install_formula(formula_installer) f = formula_installer.formula - if formula_installer.dry_run? - print_dry_run_dependencies(f, formula_installer.compute_dependencies) - return - end - upgrade = f.linked? && f.outdated? && !f.head? && !Homebrew::EnvConfig.no_install_upgrade? Upgrade.install_formula(formula_installer, upgrade: upgrade) @@ -349,7 +349,7 @@ module Homebrew private_class_method :install_formula def print_dry_run_dependencies(formula, dependencies) - return if dependencies.empry? + return if dependencies.empty? plural = "dependency".pluralize(dependencies.count) ohai "Would install #{dependencies.count} #{plural} for #{formula.name}:" From 990f71367b196eb886855be1e083e28ef22ae220 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Tue, 23 Aug 2022 16:08:18 +0200 Subject: [PATCH 101/138] Refactoring `resource_version` to always return hash info --- Library/Homebrew/livecheck/livecheck.rb | 35 ++++++++++--------------- 1 file changed, 14 insertions(+), 21 deletions(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index 57d3e06d1c..79260999d0 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -290,10 +290,9 @@ module Homebrew resource_version_info = formula_or_cask.resources.map do |resource| resource_version( resource, - json: json, - full_name: use_full_name, - verbose: verbose, - debug: debug, + json: json, + verbose: verbose, + debug: debug, ) end end @@ -349,19 +348,18 @@ module Homebrew if json progress&.increment info.except!(:meta) unless verbose + resource_version_info.map! { |r| r.except!(:meta) } if check_for_resources && !verbose next info end puts if debug - print_latest_version(info, verbose: verbose, ambiguous_cask: ambiguous_casks.include?(formula_or_cask), -resource: false) + print_latest_version(info, verbose: verbose, ambiguous_cask: ambiguous_casks.include?(formula_or_cask)) if check_for_resources resource_version_info.each do |r_info| print_latest_version( r_info, - verbose: verbose, - ambiguous_cask: false, - resource: true, + verbose: verbose, + resource: true, ) end end @@ -464,7 +462,7 @@ resource: false) package_or_resource_s = resource ? " " : "" package_or_resource_s += "#{Tty.blue}#{info[:formula] || info[:cask] || info[:resource]}#{Tty.reset}" package_or_resource_s += " (cask)" if ambiguous_cask - package_or_resource_s += " (guessed)" if verbose && !resource && !info[:meta][:livecheckable] + package_or_resource_s += " (guessed)" if verbose && !info[:meta][:livecheckable] current_s = if info[:version][:newer_than_upstream] "#{Tty.red}#{info[:version][:current]}#{Tty.reset}" @@ -606,17 +604,15 @@ resource: false) # couldn't be found for a given resource. sig { params( - resource: Resource, - json: T::Boolean, - full_name: T::Boolean, - verbose: T::Boolean, - debug: T::Boolean, + resource: Resource, + json: T::Boolean, + verbose: T::Boolean, + debug: T::Boolean, ).returns(T.nilable(Hash)) } def resource_version( resource, json: false, - full_name: false, verbose: false, debug: false ) @@ -707,7 +703,7 @@ resource: false) puts messages unless json next if i + 1 < urls.length - return status_hash(resource, "error", messages, full_name: full_name, verbose: verbose) + return status_hash(resource, "error", messages, verbose: verbose) end if debug @@ -759,12 +755,9 @@ resource: false) }, } - next unless json - next unless verbose - resource_version_info[:meta] = { url: { original: original_url } } resource_version_info[:meta][:url][:processed] = url if url != original_url - resource_version_info[:meta][:livecheckable] = has_livecheckable ? "Yes" : "No" + resource_version_info[:meta][:livecheckable] = has_livecheckable next unless has_livecheckable res_livecheck = { url: { original: livecheck_url } } From 374dd3dea24ff4648fccb61bcbb177f03d543498 Mon Sep 17 00:00:00 2001 From: hyuraku <32809703+hyuraku@users.noreply.github.com> Date: Sat, 27 Aug 2022 22:29:07 +0900 Subject: [PATCH 102/138] repair if syntax and remove useless line --- Library/Homebrew/cask/cmd/install.rb | 5 ++--- Library/Homebrew/cask/installer.rb | 1 - Library/Homebrew/install.rb | 5 ++--- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/Library/Homebrew/cask/cmd/install.rb b/Library/Homebrew/cask/cmd/install.rb index fb410b83d5..8b088de6b3 100644 --- a/Library/Homebrew/cask/cmd/install.rb +++ b/Library/Homebrew/cask/cmd/install.rb @@ -75,9 +75,8 @@ module Cask options[:quarantine] = true if options[:quarantine].nil? if dry_run - casks_to_install = casks.reject(&:installed?) - if casks_to_install.present? - plural = "package".pluralize(casks_to_install.count) + if (casks_to_install = casks.reject(&:installed?).presence) + plural = "cask".pluralize(casks_to_install.count) ohai "Would install #{casks_to_install.count} #{plural}:" puts casks_to_install.map(&:full_name).join(" ") end diff --git a/Library/Homebrew/cask/installer.rb b/Library/Homebrew/cask/installer.rb index 9ef2b3bea2..06b015517a 100644 --- a/Library/Homebrew/cask/installer.rb +++ b/Library/Homebrew/cask/installer.rb @@ -97,7 +97,6 @@ module Cask print caveats fetch - uninstall_existing_cask if reinstall? backup if force? && @cask.staged_path.exist? && @cask.metadata_versioned_path.exist? diff --git a/Library/Homebrew/install.rb b/Library/Homebrew/install.rb index 9a4cddc3b9..9b21b1029b 100644 --- a/Library/Homebrew/install.rb +++ b/Library/Homebrew/install.rb @@ -319,9 +319,8 @@ module Homebrew end.compact if dry_run - formulae_name_to_install = formulae_to_install.map(&:name) - if formulae_name_to_install.present? - plural = "package".pluralize(formulae_name_to_install.count) + if (formulae_name_to_install = formulae_to_install.map(&:name)) + plural = "formula".pluralize(formulae_name_to_install.count) ohai "Would install #{formulae_name_to_install.count} #{plural}:" puts formulae_name_to_install.join(" ") From 5491f7b1bd1af1f394826225d2385c042f947bb6 Mon Sep 17 00:00:00 2001 From: hyuraku <32809703+hyuraku@users.noreply.github.com> Date: Sat, 3 Sep 2022 16:01:55 +0900 Subject: [PATCH 103/138] share Install.print_dry_run_dependencies --- Library/Homebrew/install.rb | 8 +++----- Library/Homebrew/upgrade.rb | 25 ++++++++----------------- 2 files changed, 11 insertions(+), 22 deletions(-) diff --git a/Library/Homebrew/install.rb b/Library/Homebrew/install.rb index 9b21b1029b..51cd1bf42a 100644 --- a/Library/Homebrew/install.rb +++ b/Library/Homebrew/install.rb @@ -326,7 +326,7 @@ module Homebrew formula_installers.each do |fi| f = fi.formula - print_dry_run_dependencies(f, fi.compute_dependencies) + print_dry_run_dependencies(f, fi.compute_dependencies, &:name) end end return @@ -347,16 +347,14 @@ module Homebrew end private_class_method :install_formula - def print_dry_run_dependencies(formula, dependencies) + def print_dry_run_dependencies(formula, dependencies, &block) return if dependencies.empty? plural = "dependency".pluralize(dependencies.count) ohai "Would install #{dependencies.count} #{plural} for #{formula.name}:" - formula_names = dependencies.map(&:first).map(&:to_formula).map(&:name) + formula_names = dependencies.map(&:first).map(&:to_formula).map(&block) puts formula_names.join(" ") end - - private_class_method :print_dry_run_dependencies end end diff --git a/Library/Homebrew/upgrade.rb b/Library/Homebrew/upgrade.rb index 54e3223c18..48a1a363c9 100644 --- a/Library/Homebrew/upgrade.rb +++ b/Library/Homebrew/upgrade.rb @@ -94,22 +94,6 @@ module Homebrew .map { |k| Keg.new(k.resolved_path) } end - def print_dry_run_dependencies(formula, fi_deps) - return if fi_deps.empty? - - plural = "dependency".pluralize(fi_deps.count) - ohai "Would upgrade #{fi_deps.count} #{plural} for #{formula.full_specified_name}:" - formulae_upgrades = fi_deps.map(&:first).map(&:to_formula).map do |f| - name = f.full_specified_name - if f.optlinked? - "#{name} #{Keg.new(f.opt_prefix).version} -> #{f.pkg_version}" - else - "#{name} #{f.pkg_version}" - end - end - puts formulae_upgrades.join(", ") - end - def print_upgrade_message(formula, fi_options) version_upgrade = if formula.optlinked? "#{Keg.new(formula.opt_prefix).version} -> #{formula.pkg_version}" @@ -178,7 +162,14 @@ module Homebrew formula = formula_installer.formula if dry_run - print_dry_run_dependencies(formula, formula_installer.compute_dependencies) + Install.print_dry_run_dependencies(formula, formula_installer.compute_dependencies) do |f| + name = f.full_specified_name + if f.optlinked? + "#{name} #{Keg.new(f.opt_prefix).version} -> #{f.pkg_version}" + else + "#{name} #{f.pkg_version}" + end + end return end From d0e83d39a028babe1a1509ea4d198c9b9d5be6ba Mon Sep 17 00:00:00 2001 From: hyuraku <32809703+hyuraku@users.noreply.github.com> Date: Tue, 6 Sep 2022 22:07:44 +0900 Subject: [PATCH 104/138] add empty line --- Library/Homebrew/cask/installer.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/Library/Homebrew/cask/installer.rb b/Library/Homebrew/cask/installer.rb index 06b015517a..c0417e311d 100644 --- a/Library/Homebrew/cask/installer.rb +++ b/Library/Homebrew/cask/installer.rb @@ -98,6 +98,7 @@ module Cask print caveats fetch uninstall_existing_cask if reinstall? + backup if force? && @cask.staged_path.exist? && @cask.metadata_versioned_path.exist? oh1 "Installing Cask #{Formatter.identifier(@cask)}" From 8496ca0416d9283a3a0d9a25583cdbd670b53aab Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Wed, 14 Sep 2022 03:42:12 +0200 Subject: [PATCH 105/138] Added `skip_conditions` support for resource --- Library/Homebrew/dev-cmd/bump.rb | 19 ++--- Library/Homebrew/livecheck/skip_conditions.rb | 77 +++++++++++-------- 2 files changed, 54 insertions(+), 42 deletions(-) diff --git a/Library/Homebrew/dev-cmd/bump.rb b/Library/Homebrew/dev-cmd/bump.rb index 009865c85d..0bc0bbc96a 100644 --- a/Library/Homebrew/dev-cmd/bump.rb +++ b/Library/Homebrew/dev-cmd/bump.rb @@ -72,17 +72,18 @@ module Homebrew ambiguous_casks = [] if !args.formula? && !args.cask? - ambiguous_casks = formulae_and_casks.group_by { |item| Livecheck.formula_or_cask_name(item, full_name: true) } - .values - .select { |items| items.length > 1 } - .flatten - .select { |item| item.is_a?(Cask::Cask) } + ambiguous_casks = formulae_and_casks \ + .group_by { |item| Livecheck.package_or_resource_name(item, full_name: true) } + .values + .select { |items| items.length > 1 } + .flatten + .select { |item| item.is_a?(Cask::Cask) } end ambiguous_names = [] unless args.full_name? ambiguous_names = - (formulae_and_casks - ambiguous_casks).group_by { |item| Livecheck.formula_or_cask_name(item) } + (formulae_and_casks - ambiguous_casks).group_by { |item| Livecheck.package_or_resource_name(item) } .values .select { |items| items.length > 1 } .flatten @@ -92,7 +93,7 @@ module Homebrew puts if i.positive? use_full_name = args.full_name? || ambiguous_names.include?(formula_or_cask) - name = Livecheck.formula_or_cask_name(formula_or_cask, full_name: use_full_name) + name = Livecheck.package_or_resource_name(formula_or_cask, full_name: use_full_name) repository = if formula_or_cask.is_a?(Formula) if formula_or_cask.head_only? ohai name @@ -157,7 +158,7 @@ module Homebrew rescue next end - name = Livecheck.formula_or_cask_name(formula_or_cask) + name = Livecheck.package_or_resource_name(formula_or_cask) ambiguous_cask = begin formula_or_cask.is_a?(Cask::Cask) && !args.cask? && Formula[name] rescue FormulaUnavailableError @@ -178,7 +179,7 @@ module Homebrew end def livecheck_result(formula_or_cask) - name = Livecheck.formula_or_cask_name(formula_or_cask) + name = Livecheck.package_or_resource_name(formula_or_cask) referenced_formula_or_cask, = Livecheck.resolve_livecheck_reference(formula_or_cask, full_name: false, debug: false) diff --git a/Library/Homebrew/livecheck/skip_conditions.rb b/Library/Homebrew/livecheck/skip_conditions.rb index f5d2f08358..fe93813378 100644 --- a/Library/Homebrew/livecheck/skip_conditions.rb +++ b/Library/Homebrew/livecheck/skip_conditions.rb @@ -6,7 +6,7 @@ require "livecheck/livecheck" module Homebrew module Livecheck # The `Livecheck::SkipConditions` module primarily contains methods that - # check for various formula/cask conditions where a check should be skipped. + # check for various formula/cask/resource conditions where a check should be skipped. # # @api private module SkipConditions @@ -16,14 +16,14 @@ module Homebrew sig { params( - formula_or_cask: T.any(Formula, Cask::Cask), - livecheckable: T::Boolean, - full_name: T::Boolean, - verbose: T::Boolean, + package_or_resource: T.any(Formula, Cask::Cask, Resource), + livecheckable: T::Boolean, + full_name: T::Boolean, + verbose: T::Boolean, ).returns(Hash) } - def formula_or_cask_skip(formula_or_cask, livecheckable, full_name: false, verbose: false) - formula = formula_or_cask if formula_or_cask.is_a?(Formula) + def package_or_resource_skip(package_or_resource, livecheckable, full_name: false, verbose: false) + formula = package_or_resource if package_or_resource.is_a?(Formula) if (stable_url = formula&.stable&.url) stable_is_gist = stable_url.match?(%r{https?://gist\.github(?:usercontent)?\.com/}i) @@ -33,8 +33,8 @@ module Homebrew stable_from_internet_archive = stable_url.match?(%r{https?://web\.archive\.org/}i) end - skip_message = if formula_or_cask.livecheck.skip_msg.present? - formula_or_cask.livecheck.skip_msg + skip_message = if package_or_resource.livecheck&.skip_msg.present? + package_or_resource.livecheck.skip_msg elsif !livecheckable if stable_from_google_code_archive "Stable URL is from Google Code Archive" @@ -45,10 +45,10 @@ module Homebrew end end - return {} if !formula_or_cask.livecheck.skip? && skip_message.blank? + return {} if !package_or_resource.livecheck&.skip? && skip_message.blank? skip_messages = skip_message ? [skip_message] : nil - Livecheck.status_hash(formula_or_cask, "skipped", skip_messages, full_name: full_name, verbose: verbose) + Livecheck.status_hash(package_or_resource, "skipped", skip_messages, full_name: full_name, verbose: verbose) end sig { @@ -157,7 +157,7 @@ module Homebrew # Skip conditions for formulae. FORMULA_CHECKS = [ - :formula_or_cask_skip, + :package_or_resource_skip, :formula_head_only, :formula_deprecated, :formula_disabled, @@ -166,76 +166,85 @@ module Homebrew # Skip conditions for casks. CASK_CHECKS = [ - :formula_or_cask_skip, + :package_or_resource_skip, :cask_discontinued, :cask_version_latest, :cask_url_unversioned, ].freeze - # If a formula/cask should be skipped, we return a hash from + # Skip conditions for resource + RESOURCE_CHECKS = [ + :package_or_resource_skip, + ].freeze + + # If a formula/cask/resource should be skipped, we return a hash from # `Livecheck#status_hash`, which contains a `status` type and sometimes # error `messages`. sig { params( - formula_or_cask: T.any(Formula, Cask::Cask), - full_name: T::Boolean, - verbose: T::Boolean, + package_or_resource: T.any(Formula, Cask::Cask, Resource), + full_name: T::Boolean, + verbose: T::Boolean, ).returns(Hash) } - def skip_information(formula_or_cask, full_name: false, verbose: false) - livecheckable = formula_or_cask.livecheckable? + def skip_information(package_or_resource, full_name: false, verbose: false) + livecheckable = package_or_resource.livecheckable? - checks = case formula_or_cask + checks = case package_or_resource when Formula FORMULA_CHECKS when Cask::Cask CASK_CHECKS + when Resource + RESOURCE_CHECKS end return {} unless checks checks.each do |method_name| - skip_hash = send(method_name, formula_or_cask, livecheckable, full_name: full_name, verbose: verbose) + skip_hash = send(method_name, package_or_resource, livecheckable, full_name: full_name, verbose: verbose) return skip_hash if skip_hash.present? end {} end - # Skip conditions for formulae/casks referenced in a `livecheck` block + # Skip conditions for formulae/casks/resources referenced in a `livecheck` block # are treated differently than normal. We only respect certain skip # conditions (returning the related hash) and others are treated as # errors. sig { params( - livecheck_formula_or_cask: T.any(Formula, Cask::Cask), - original_formula_or_cask_name: String, - full_name: T::Boolean, - verbose: T::Boolean, + livecheck_package_or_resource: T.any(Formula, Cask::Cask, Resource), + original_package_or_resource_name: String, + full_name: T::Boolean, + verbose: T::Boolean, ).returns(T.nilable(Hash)) } def referenced_skip_information( - livecheck_formula_or_cask, - original_formula_or_cask_name, + livecheck_package_or_resource, + original_package_or_resource_name, full_name: false, verbose: false ) skip_info = SkipConditions.skip_information( - livecheck_formula_or_cask, + livecheck_package_or_resource, full_name: full_name, verbose: verbose, ) return if skip_info.blank? - referenced_name = Livecheck.formula_or_cask_name(livecheck_formula_or_cask, full_name: full_name) - referenced_type = case livecheck_formula_or_cask + referenced_name = Livecheck.package_or_resource_name(livecheck_package_or_resource, full_name: full_name) + referenced_type = case livecheck_package_or_resource when Formula :formula when Cask::Cask :cask + when Resource + :resource end if skip_info[:status] != "error" && - !(skip_info[:status] == "skipped" && livecheck_formula_or_cask.livecheck.skip?) + !(skip_info[:status] == "skipped" && livecheck_package_or_resource.livecheck.skip?) error_msg_end = if skip_info[:status] == "skipped" "automatically skipped" else @@ -245,7 +254,7 @@ module Homebrew raise "Referenced #{referenced_type} (#{referenced_name}) is #{error_msg_end}" end - skip_info[referenced_type] = original_formula_or_cask_name + skip_info[referenced_type] = original_package_or_resource_name skip_info end @@ -258,6 +267,8 @@ module Homebrew skip_hash[:formula] elsif skip_hash[:cask].is_a?(String) skip_hash[:cask] + elsif skip_hash[:resource].is_a?(String) + skip_hash[:resource] end return unless name From 7a627565ac1c3c71f0dd87f7379ef41f01d7f9fe Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Wed, 14 Sep 2022 04:54:52 +0200 Subject: [PATCH 106/138] Fixed output issue --- Library/Homebrew/livecheck/livecheck.rb | 118 +++++++++++------- Library/Homebrew/livecheck/skip_conditions.rb | 2 +- 2 files changed, 77 insertions(+), 43 deletions(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index 79260999d0..fe47f0dd51 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -126,11 +126,11 @@ module Homebrew if debug # Print the chain of references for debugging puts "Reference Chain:" - puts formula_or_cask_name(first_formula_or_cask, full_name: full_name) + puts package_or_resource_name(first_formula_or_cask, full_name: full_name) references << referenced_formula_or_cask references.each do |ref_formula_or_cask| - puts formula_or_cask_name(ref_formula_or_cask, full_name: full_name) + puts package_or_resource_name(ref_formula_or_cask, full_name: full_name) end end @@ -179,17 +179,18 @@ module Homebrew ambiguous_casks = [] if handle_name_conflict - ambiguous_casks = formulae_and_casks_to_check.group_by { |item| formula_or_cask_name(item, full_name: true) } - .values - .select { |items| items.length > 1 } - .flatten - .select { |item| item.is_a?(Cask::Cask) } + ambiguous_casks = formulae_and_casks_to_check \ + .group_by { |item| package_or_resource_name(item, full_name: true) } + .values + .select { |items| items.length > 1 } + .flatten + .select { |item| item.is_a?(Cask::Cask) } end ambiguous_names = [] unless full_name ambiguous_names = - (formulae_and_casks_to_check - ambiguous_casks).group_by { |item| formula_or_cask_name(item) } + (formulae_and_casks_to_check - ambiguous_casks).group_by { |item| package_or_resource_name(item) } .values .select { |items| items.length > 1 } .flatten @@ -219,7 +220,7 @@ module Homebrew cask = formula_or_cask if formula_or_cask.is_a?(Cask::Cask) use_full_name = full_name || ambiguous_names.include?(formula_or_cask) - name = formula_or_cask_name(formula_or_cask, full_name: use_full_name) + 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) @@ -244,11 +245,31 @@ module Homebrew ) end + # Check current and latest resources (if "--resources" flag is given) + # Only check current and latest versions if we have resources to check against + 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) + if res_skip_info.present? + res_skip_info + else + resource_version( + resource, + json: json, + verbose: verbose, + debug: debug, + ) + end + end.compact + end + skip_info ||= SkipConditions.skip_information(formula_or_cask, full_name: use_full_name, verbose: verbose) if skip_info.present? next skip_info if json && !newer_only SkipConditions.print_skip_information(skip_info) if !newer_only && !quiet + print_resources_info(resource_version_info, verbose: verbose) if check_for_resources next end @@ -283,20 +304,6 @@ module Homebrew version_info[:latest] if version_info.present? end - # Check current and latest resources (if "--resources" flag is given) - # Only check current and latest versions if we have resources to check against - 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| - resource_version( - resource, - json: json, - verbose: verbose, - debug: debug, - ) - end - end - if latest.blank? no_versions_msg = "Unable to get versions" raise Livecheck::Error, no_versions_msg unless json @@ -353,17 +360,7 @@ module Homebrew end puts if debug print_latest_version(info, verbose: verbose, ambiguous_cask: ambiguous_casks.include?(formula_or_cask)) - - if check_for_resources - resource_version_info.each do |r_info| - print_latest_version( - r_info, - verbose: verbose, - resource: true, - ) - end - end - + print_resources_info(resource_version_info, verbose: verbose) if check_for_resources nil rescue => e Homebrew.failed = true @@ -373,13 +370,18 @@ module Homebrew progress&.increment status_hash(formula_or_cask, "error", [e.to_s], full_name: use_full_name, verbose: verbose) unless quiet elsif !quiet - name = formula_or_cask_name(formula_or_cask, full_name: use_full_name) + name = package_or_resource_name(formula_or_cask, full_name: use_full_name) name += " (cask)" if ambiguous_casks.include?(formula_or_cask) onoe "#{Tty.blue}#{name}#{Tty.reset}: #{e}" $stderr.puts e.backtrace if debug && !e.is_a?(Livecheck::Error) nil end + if check_for_resources + next if resource_version_info.blank? + next unless resource_version_info.empty? + print_resources_info(resource_version_info, verbose: verbose) + end end # rubocop:enable Metrics/BlockLength @@ -397,15 +399,17 @@ module Homebrew puts JSON.pretty_generate(formulae_checked.compact) end - sig { params(formula_or_cask: T.any(Formula, Cask::Cask), full_name: T::Boolean).returns(String) } - def formula_or_cask_name(formula_or_cask, full_name: false) - case formula_or_cask + sig { params(package_or_resource: T.any(Formula, Cask::Cask, Resource), full_name: T::Boolean).returns(String) } + def package_or_resource_name(package_or_resource, full_name: false) + case package_or_resource when Formula - formula_name(formula_or_cask, full_name: full_name) + formula_name(package_or_resource, full_name: full_name) when Cask::Cask - cask_name(formula_or_cask, full_name: full_name) + cask_name(package_or_resource, full_name: full_name) + when Resource + package_or_resource.name else - T.absurd(formula_or_cask) + T.absurd(package_or_resource) end end @@ -458,7 +462,7 @@ module Homebrew # Formats and prints the livecheck result for a formula/cask/resource. sig { params(info: Hash, verbose: T::Boolean, ambiguous_cask: T::Boolean, resource: T::Boolean).void } - def print_latest_version(info, verbose:, ambiguous_cask: false, resource: false) + def print_latest_version(info, verbose:false, ambiguous_cask: false, resource: false) package_or_resource_s = resource ? " " : "" package_or_resource_s += "#{Tty.blue}#{info[:formula] || info[:cask] || info[:resource]}#{Tty.reset}" package_or_resource_s += " (cask)" if ambiguous_cask @@ -479,6 +483,22 @@ module Homebrew puts "#{package_or_resource_s}: #{current_s} ==> #{latest_s}" end + # Prints the livecheck result for a resources for a given Formula. + sig { params(info: Hash, verbose: T::Boolean).void } + def print_resources_info(info, verbose:false) + info.each do |r_info| + if r_info.is_a?(Hash) && r_info[:status] && r_info[:messages] + SkipConditions.print_skip_information(r_info) + else + print_latest_version( + r_info, + verbose: verbose, + resource: true, + ) + end + end + end + sig { params( livecheck_url: T.any(String, Symbol), @@ -742,6 +762,11 @@ module Homebrew res_current = resource.version res_latest = Version.new(match_version_map.values.max_by { |v| LivecheckVersion.create(resource, v) }) + + if res_latest.to_s.blank? + return status_hash(resource, "error", ["Unable to get versions"], verbose: verbose) + end + is_newer_than_upstream = res_current > res_latest is_outdated = (res_current != res_latest) && !is_newer_than_upstream @@ -775,6 +800,14 @@ module Homebrew res_livecheck[:regex] = regex.inspect if regex.present? res_livecheck[:cached] = true if strategy_data[:cached] == true resource_version_info[:meta][:livecheck] = res_livecheck + rescue => e + Homebrew.failed = true + if json + status_hash(resource, "error", [e.to_s], verbose: verbose) + elsif onoe "#{Tty.blue}#{resource.name}#{Tty.reset}: #{e}" + $stderr.puts e.backtrace if debug && !e.is_a?(Livecheck::Error) + nil + end end # rubocop:enable Metrics/BlockLength resource_version_info @@ -950,6 +983,7 @@ module Homebrew end version_info = { + # latest: {}, latest: Version.new(match_version_map.values.max_by { |v| LivecheckVersion.create(formula_or_cask, v) }), } diff --git a/Library/Homebrew/livecheck/skip_conditions.rb b/Library/Homebrew/livecheck/skip_conditions.rb index fe93813378..7991f2d07d 100644 --- a/Library/Homebrew/livecheck/skip_conditions.rb +++ b/Library/Homebrew/livecheck/skip_conditions.rb @@ -268,7 +268,7 @@ module Homebrew elsif skip_hash[:cask].is_a?(String) skip_hash[:cask] elsif skip_hash[:resource].is_a?(String) - skip_hash[:resource] + " #{skip_hash[:resource]}" end return unless name From c06b80c2ca5f7d017529431352578c049c81731c Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Wed, 14 Sep 2022 04:59:01 +0200 Subject: [PATCH 107/138] After `brew style --fix` --- Library/Homebrew/livecheck/livecheck.rb | 25 ++++++++++--------------- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index fe47f0dd51..5192f3394b 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -251,16 +251,12 @@ module Homebrew if check_for_resources resource_version_info = formula_or_cask.resources.map do |resource| res_skip_info ||= SkipConditions.skip_information(resource, verbose: verbose) - if res_skip_info.present? - res_skip_info - else - resource_version( - resource, - json: json, - verbose: verbose, - debug: debug, - ) - end + res_skip_info.presence || resource_version( + resource, + json: json, + verbose: verbose, + debug: debug, + ) end.compact end @@ -380,6 +376,7 @@ module Homebrew if check_for_resources next if resource_version_info.blank? next unless resource_version_info.empty? + print_resources_info(resource_version_info, verbose: verbose) end end @@ -462,7 +459,7 @@ module Homebrew # Formats and prints the livecheck result for a formula/cask/resource. sig { params(info: Hash, verbose: T::Boolean, ambiguous_cask: T::Boolean, resource: T::Boolean).void } - def print_latest_version(info, verbose:false, ambiguous_cask: false, resource: false) + def print_latest_version(info, verbose: false, ambiguous_cask: false, resource: false) package_or_resource_s = resource ? " " : "" package_or_resource_s += "#{Tty.blue}#{info[:formula] || info[:cask] || info[:resource]}#{Tty.reset}" package_or_resource_s += " (cask)" if ambiguous_cask @@ -485,7 +482,7 @@ module Homebrew # Prints the livecheck result for a resources for a given Formula. sig { params(info: Hash, verbose: T::Boolean).void } - def print_resources_info(info, verbose:false) + def print_resources_info(info, verbose: false) info.each do |r_info| if r_info.is_a?(Hash) && r_info[:status] && r_info[:messages] SkipConditions.print_skip_information(r_info) @@ -763,9 +760,7 @@ module Homebrew res_current = resource.version res_latest = Version.new(match_version_map.values.max_by { |v| LivecheckVersion.create(resource, v) }) - if res_latest.to_s.blank? - return status_hash(resource, "error", ["Unable to get versions"], verbose: verbose) - end + return status_hash(resource, "error", ["Unable to get versions"], verbose: verbose) if res_latest.to_s.blank? is_newer_than_upstream = res_current > res_latest is_outdated = (res_current != res_latest) && !is_newer_than_upstream From f8ef7bd0e9da68bb74d002c8410aa15211f331f8 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Wed, 14 Sep 2022 06:05:43 +0200 Subject: [PATCH 108/138] Minor fixes --- Library/Homebrew/livecheck/livecheck.rb | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index 5192f3394b..0195e2f7a7 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -307,7 +307,11 @@ module Homebrew next version_info if version_info.is_a?(Hash) && version_info[:status] && version_info[:messages] - next status_hash(formula_or_cask, "error", [no_versions_msg], full_name: use_full_name, verbose: verbose) + latest_info = status_hash(formula_or_cask, "error", [no_versions_msg], full_name: use_full_name, + verbose: verbose) + latest_info[:resources] = resource_version_info if check_for_resources + + next latest_info end if (m = latest.to_s.match(/(.*)-release$/)) && !current.to_s.match(/.*-release$/) @@ -373,12 +377,7 @@ module Homebrew $stderr.puts e.backtrace if debug && !e.is_a?(Livecheck::Error) nil end - if check_for_resources - next if resource_version_info.blank? - next unless resource_version_info.empty? - - print_resources_info(resource_version_info, verbose: verbose) - end + print_resources_info(resource_version_info, verbose: verbose) if check_for_resources end # rubocop:enable Metrics/BlockLength From 3d9c6ddb755d881756e2bd55c108ce13e92839f5 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Sun, 18 Sep 2022 17:09:21 +0200 Subject: [PATCH 109/138] Minor fix: return error when `resource_version` method returns empty hash --- Library/Homebrew/livecheck/livecheck.rb | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index 0195e2f7a7..b7c5b7c8c2 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -251,13 +251,22 @@ module Homebrew 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.presence || resource_version( - resource, - json: json, - verbose: verbose, - debug: debug, - ) - end.compact + if res_skip_info.present? + res_skip_info + else + res_version_info = resource_version( + resource, + json: json, + verbose: verbose, + debug: debug, + ) + if res_version_info.empty? + status_hash(resource, "error", ["Unable to get versions"], verbose: verbose) + else + res_version_info + end + end + end.compact_blank end skip_info ||= SkipConditions.skip_information(formula_or_cask, full_name: use_full_name, verbose: verbose) @@ -704,6 +713,7 @@ module Homebrew next end end + puts if debug && strategy.blank? next if strategy.blank? strategy_data = strategy.find_versions( From 980538b8b269392d877244db81ce0b5276a38e7c Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Sun, 18 Sep 2022 17:29:44 +0200 Subject: [PATCH 110/138] Exclude `:meta` info for resources if `latest.blank?` for Formula --- Library/Homebrew/livecheck/livecheck.rb | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index b7c5b7c8c2..cbf18e5a75 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -318,7 +318,10 @@ module Homebrew latest_info = status_hash(formula_or_cask, "error", [no_versions_msg], full_name: use_full_name, verbose: verbose) - latest_info[:resources] = resource_version_info if check_for_resources + if check_for_resources + resource_version_info.map! { |r| r.except!(:meta) } unless verbose + latest_info[:resources] = resource_version_info + end next latest_info end From ee1210a495eea3163b95f21df48933a7aa4de913 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Sun, 18 Sep 2022 21:27:10 +0200 Subject: [PATCH 111/138] Fixed style and typecheck issues --- Library/Homebrew/livecheck/livecheck.rb | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index cbf18e5a75..60af738a6e 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -157,6 +157,8 @@ module Homebrew # Executes the livecheck logic for each formula/cask in the # `formulae_and_casks_to_check` array and prints the results. + # rubocop:disable Metrics/CyclomaticComplexity + # rubocop:disable Metrics/PerceivedComplexity sig { params( formulae_and_casks_to_check: T::Array[T.any(Formula, Cask::Cask)], @@ -406,6 +408,8 @@ module Homebrew puts JSON.pretty_generate(formulae_checked.compact) end + # rubocop:enable Metrics/CyclomaticComplexity + # rubocop:enable Metrics/PerceivedComplexity sig { params(package_or_resource: T.any(Formula, Cask::Cask, Resource), full_name: T::Boolean).returns(String) } def package_or_resource_name(package_or_resource, full_name: false) @@ -492,10 +496,10 @@ module Homebrew end # Prints the livecheck result for a resources for a given Formula. - sig { params(info: Hash, verbose: T::Boolean).void } + sig { params(info: T::Array[Hash], verbose: T::Boolean).void } def print_resources_info(info, verbose: false) info.each do |r_info| - if r_info.is_a?(Hash) && r_info[:status] && r_info[:messages] + if r_info[:status] && r_info[:messages] SkipConditions.print_skip_information(r_info) else print_latest_version( @@ -598,29 +602,29 @@ module Homebrew url end - # livecheck should fetch a URL using brewed curl if the formula/resource/cask + # livecheck should fetch a URL using brewed curl if the formula/cask # contains a `stable`/`url` or `head` URL `using: :homebrew_curl` that # shares the same root domain. - sig { params(package_or_resource: T.any(Formula, Cask::Cask), url: String).returns(T::Boolean) } - def use_homebrew_curl?(package_or_resource, url) + sig { params(formula_or_cask: T.any(Formula, Cask::Cask), url: String).returns(T::Boolean) } + def use_homebrew_curl?(formula_or_cask, url) url_root_domain = Addressable::URI.parse(url)&.domain return false if url_root_domain.blank? # Collect root domains of URLs with `using: :homebrew_curl` homebrew_curl_root_domains = [] - case package_or_resource + case formula_or_cask when Formula [:stable, :head].each do |spec_name| - next unless (spec = package_or_resource.send(spec_name)) + next unless (spec = formula_or_cask.send(spec_name)) next unless spec.using == :homebrew_curl domain = Addressable::URI.parse(spec.url)&.domain homebrew_curl_root_domains << domain if domain.present? end when Cask::Cask - return false unless package_or_resource.url.using == :homebrew_curl + return false unless formula_or_cask.url.using == :homebrew_curl - domain = Addressable::URI.parse(package_or_resource.url.to_s)&.domain + domain = Addressable::URI.parse(formula_or_cask.url.to_s)&.domain homebrew_curl_root_domains << domain if domain.present? end From 560680bfa3f60bcf7e5ec3800c043303277c2f3d Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Sun, 18 Sep 2022 21:36:22 +0200 Subject: [PATCH 112/138] Minor fix for `brew typecheck` --- Library/Homebrew/livecheck/livecheck.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index 60af738a6e..1b3ec421f4 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -640,7 +640,7 @@ module Homebrew json: T::Boolean, verbose: T::Boolean, debug: T::Boolean, - ).returns(T.nilable(Hash)) + ).returns(Hash) } def resource_version( resource, From 6d993fa642c9126e01662f0c1daa75b281371efa Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Sun, 25 Sep 2022 00:53:44 +0200 Subject: [PATCH 113/138] Fixed minor issues and applied suggestions --- Library/Homebrew/livecheck/livecheck.rb | 401 ++++++++++++------------ 1 file changed, 202 insertions(+), 199 deletions(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index 1b3ec421f4..e50aac01e0 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -259,8 +259,9 @@ module Homebrew res_version_info = resource_version( resource, json: json, - verbose: verbose, debug: debug, + quiet: quiet, + verbose: verbose, ) if res_version_info.empty? status_hash(resource, "error", ["Unable to get versions"], verbose: verbose) @@ -389,9 +390,9 @@ module Homebrew onoe "#{Tty.blue}#{name}#{Tty.reset}: #{e}" $stderr.puts e.backtrace if debug && !e.is_a?(Livecheck::Error) + print_resources_info(resource_version_info, verbose: verbose) if check_for_resources nil end - print_resources_info(resource_version_info, verbose: verbose) if check_for_resources end # rubocop:enable Metrics/BlockLength @@ -501,6 +502,7 @@ module Homebrew info.each do |r_info| if r_info[:status] && r_info[:messages] SkipConditions.print_skip_information(r_info) + Homebrew.failed = true else print_latest_version( r_info, @@ -539,8 +541,6 @@ module Homebrew urls = [] case package_or_resource - when Resource - urls << package_or_resource.url when Formula if package_or_resource.stable urls << package_or_resource.stable.url @@ -552,6 +552,8 @@ module Homebrew urls << package_or_resource.appcast.to_s if package_or_resource.appcast urls << package_or_resource.url.to_s if package_or_resource.url urls << package_or_resource.homepage if package_or_resource.homepage + when Resource + urls << package_or_resource.url else T.absurd(package_or_resource) end @@ -631,199 +633,6 @@ module Homebrew homebrew_curl_root_domains.include?(url_root_domain) end - # Identifies the latest version of the resource in a given Formulae and returns a Hash containing - # the version information for a resource. Returns a nil value if a latest version - # couldn't be found for a given resource. - sig { - params( - resource: Resource, - json: T::Boolean, - verbose: T::Boolean, - debug: T::Boolean, - ).returns(Hash) - } - def resource_version( - resource, - json: false, - verbose: false, - debug: false - ) - has_livecheckable = resource.livecheckable? - - if debug - puts "\n\n" - puts "Resource: #{resource.name}" - puts "Livecheckable?: #{has_livecheckable ? "Yes" : "No"}" - end - - resource_version_info = {} - - livecheck = resource.livecheck - livecheck_url = has_livecheckable ? livecheck.url : resource.url - livecheck_regex = livecheck&.regex - livecheck_strategy = livecheck&.strategy - livecheck_strategy_block = livecheck&.strategy_block - - livecheck_url_string = livecheck_url_to_string( - livecheck_url, - resource, - ) - - urls = [livecheck_url_string] if livecheck_url_string - urls ||= checkable_urls(resource) - - checked_urls = [] - - # rubocop:disable Metrics/BlockLength - urls.each_with_index do |original_url, i| - # Only preprocess the URL when it's appropriate - url = if STRATEGY_SYMBOLS_TO_SKIP_PREPROCESS_URL.include?(livecheck_strategy) - original_url - else - preprocess_url(original_url) - end - next if checked_urls.include?(url) - - strategies = Strategy.from_url( - url, - livecheck_strategy: livecheck_strategy, - url_provided: livecheck_url.present?, - regex_provided: livecheck_regex.present?, - block_provided: livecheck_strategy_block.present?, - ) - - strategy = Strategy.from_symbol(livecheck_strategy) || strategies.first - strategy_name = livecheck_strategy_names[strategy] - - if debug - puts - if livecheck_url.is_a?(Symbol) - # This assumes the URL symbol will fit within the available space - puts "URL (#{livecheck_url}):".ljust(18, " ") + original_url - else - puts "URL: #{original_url}" - end - puts "URL (processed): #{url}" if url != original_url - if strategies.present? && verbose - puts "Strategies: #{strategies.map { |s| livecheck_strategy_names[s] }.join(", ")}" - end - puts "Strategy: #{strategy.blank? ? "None" : strategy_name}" - puts "Regex: #{livecheck_regex.inspect}" if livecheck_regex.present? - end - - if livecheck_strategy.present? - if livecheck_url.blank? && strategy.method(:find_versions).parameters.include?([:keyreq, :url]) - odebug "#{strategy_name} strategy requires a URL" - next - elsif livecheck_strategy != :page_match && strategies.exclude?(strategy) - odebug "#{strategy_name} strategy does not apply to this URL" - next - end - end - puts if debug && strategy.blank? - next if strategy.blank? - - strategy_data = strategy.find_versions( - url: url, regex: livecheck_regex, - homebrew_curl: false, &livecheck_strategy_block - ) - match_version_map = strategy_data[:matches] - regex = strategy_data[:regex] - messages = strategy_data[:messages] - checked_urls << url - - if messages.is_a?(Array) && match_version_map.blank? - puts messages unless json - next if i + 1 < urls.length - - return status_hash(resource, "error", messages, verbose: verbose) - end - - if debug - if strategy_data[:url].present? && strategy_data[:url] != url - puts "URL (strategy): #{strategy_data[:url]}" - end - puts "URL (final): #{strategy_data[:final_url]}" if strategy_data[:final_url].present? - if strategy_data[:regex].present? && strategy_data[:regex] != livecheck_regex - puts "Regex (strategy): #{strategy_data[:regex].inspect}" - end - puts "Cached?: Yes" if strategy_data[:cached] == true - end - - match_version_map.delete_if do |_match, version| - next true if version.blank? - next false if has_livecheckable - - UNSTABLE_VERSION_KEYWORDS.any? do |rejection| - version.to_s.include?(rejection) - end - end - next if match_version_map.blank? - - if debug - puts - puts "Matched Versions:" - - if verbose - match_version_map.each do |match, version| - puts "#{match} => #{version.inspect}" - end - else - puts match_version_map.values.join(", ") - end - end - - res_current = 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.to_s.blank? - - is_newer_than_upstream = res_current > res_latest - is_outdated = (res_current != res_latest) && !is_newer_than_upstream - - resource_version_info = { - resource: resource.name, - version: { - current: res_current.to_s, - latest: res_latest.to_s, - newer_than_upstream: is_newer_than_upstream, - outdated: is_outdated, - }, - } - - resource_version_info[:meta] = { url: { original: original_url } } - resource_version_info[:meta][:url][:processed] = url if url != original_url - resource_version_info[:meta][:livecheckable] = has_livecheckable - next unless has_livecheckable - - res_livecheck = { url: { original: livecheck_url } } - res_livecheck[:url][:symbol] = livecheck_url if livecheck_url.is_a?(Symbol) && livecheck_url_string - if strategy_data[:url].present? && strategy_data[:url] != url - res_livecheck[:url][:strategy] = strategy_data[:url] - end - res_livecheck[:url][:final] = strategy_data[:final_url] if strategy_data[:final_url] - res_livecheck[:strategy] = strategy.present? ? strategy_name : nil - if strategies.present? - res_livecheck[:strategies] = strategies.map do |s| - livecheck_strategy_names[s] - end - end - res_livecheck[:regex] = regex.inspect if regex.present? - res_livecheck[:cached] = true if strategy_data[:cached] == true - resource_version_info[:meta][:livecheck] = res_livecheck - rescue => e - Homebrew.failed = true - if json - status_hash(resource, "error", [e.to_s], verbose: verbose) - elsif onoe "#{Tty.blue}#{resource.name}#{Tty.reset}: #{e}" - $stderr.puts e.backtrace if debug && !e.is_a?(Livecheck::Error) - nil - end - end - # rubocop:enable Metrics/BlockLength - resource_version_info - end - # Identifies the latest version of the formula/cask and returns a Hash containing # the version information. Returns nil if a latest version couldn't be found. # rubocop:disable Metrics/CyclomaticComplexity @@ -945,7 +754,6 @@ module Homebrew cask: cask, &livecheck_strategy_block ) - match_version_map = strategy_data[:matches] regex = strategy_data[:regex] messages = strategy_data[:messages] @@ -994,7 +802,6 @@ module Homebrew end version_info = { - # latest: {}, latest: Version.new(match_version_map.values.max_by { |v| LivecheckVersion.create(formula_or_cask, v) }), } @@ -1035,6 +842,202 @@ module Homebrew nil end # rubocop:enable Metrics/CyclomaticComplexity + + # Identifies the latest version of the resource in a given Formulae and returns a Hash containing + # the version information for a resource. Returns a nil value if a latest version + # couldn't be found for a given resource. + sig { + params( + resource: Resource, + json: T::Boolean, + debug: T::Boolean, + quiet: T::Boolean, + verbose: T::Boolean, + ).returns(Hash) + } + def resource_version( + resource, + json: false, + debug: false, + quiet: false, + verbose: false + ) + has_livecheckable = resource.livecheckable? + + if debug + puts "\n\n" + puts "Resource: #{resource.name}" + puts "Livecheckable?: #{has_livecheckable ? "Yes" : "No"}" + end + + resource_version_info = {} + + livecheck = resource.livecheck + livecheck_url = has_livecheckable ? livecheck.url : resource.url + livecheck_regex = livecheck.regex + livecheck_strategy = livecheck.strategy + livecheck_strategy_block = livecheck.strategy_block + + livecheck_url_string = livecheck_url_to_string( + livecheck_url, + resource, + ) + + urls = [livecheck_url_string] if livecheck_url_string + urls ||= checkable_urls(resource) + + checked_urls = [] + + # rubocop:disable Metrics/BlockLength + urls.each_with_index do |original_url, i| + # Only preprocess the URL when it's appropriate + url = if STRATEGY_SYMBOLS_TO_SKIP_PREPROCESS_URL.include?(livecheck_strategy) + original_url + else + preprocess_url(original_url) + end + next if checked_urls.include?(url) + + strategies = Strategy.from_url( + url, + livecheck_strategy: livecheck_strategy, + url_provided: livecheck_url.present?, + regex_provided: livecheck_regex.present?, + block_provided: livecheck_strategy_block.present?, + ) + + strategy = Strategy.from_symbol(livecheck_strategy) || strategies.first + strategy_name = livecheck_strategy_names[strategy] + + if debug + puts + if livecheck_url.is_a?(Symbol) + # This assumes the URL symbol will fit within the available space + puts "URL (#{livecheck_url}):".ljust(18, " ") + original_url + else + puts "URL: #{original_url}" + end + puts "URL (processed): #{url}" if url != original_url + if strategies.present? && verbose + puts "Strategies: #{strategies.map { |s| livecheck_strategy_names[s] }.join(", ")}" + end + puts "Strategy: #{strategy.blank? ? "None" : strategy_name}" + puts "Regex: #{livecheck_regex.inspect}" if livecheck_regex.present? + end + + if livecheck_strategy.present? + if livecheck_url.blank? && strategy.method(:find_versions).parameters.include?([:keyreq, :url]) + odebug "#{strategy_name} strategy requires a URL" + next + elsif livecheck_strategy != :page_match && strategies.exclude?(strategy) + odebug "#{strategy_name} strategy does not apply to this URL" + next + end + end + puts if debug && strategy.blank? + next if strategy.blank? + + strategy_data = strategy.find_versions( + url: url, regex: livecheck_regex, + homebrew_curl: false, &livecheck_strategy_block + ) + match_version_map = strategy_data[:matches] + regex = strategy_data[:regex] + messages = strategy_data[:messages] + checked_urls << url + + if messages.is_a?(Array) && match_version_map.blank? + puts messages unless json + next if i + 1 < urls.length + + return status_hash(resource, "error", messages, verbose: verbose) + end + + if debug + if strategy_data[:url].present? && strategy_data[:url] != url + puts "URL (strategy): #{strategy_data[:url]}" + end + puts "URL (final): #{strategy_data[:final_url]}" if strategy_data[:final_url].present? + if strategy_data[:regex].present? && strategy_data[:regex] != livecheck_regex + puts "Regex (strategy): #{strategy_data[:regex].inspect}" + end + puts "Cached?: Yes" if strategy_data[:cached] == true + end + + match_version_map.delete_if do |_match, version| + next true if version.blank? + next false if has_livecheckable + + UNSTABLE_VERSION_KEYWORDS.any? do |rejection| + version.to_s.include?(rejection) + end + end + next if match_version_map.blank? + + if debug + puts + puts "Matched Versions:" + + if verbose + match_version_map.each do |match, version| + puts "#{match} => #{version.inspect}" + end + else + puts match_version_map.values.join(", ") + end + end + + res_current = 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? + + is_outdated = res_current < res_latest + is_newer_than_upstream = res_current > res_latest + + resource_version_info = { + resource: resource.name, + version: { + current: res_current.to_s, + latest: res_latest.to_s, + outdated: is_outdated, + newer_than_upstream: is_newer_than_upstream, + }, + } + + resource_version_info[:meta] = { livecheckable: has_livecheckable, url: {} } + if livecheck_url.is_a?(Symbol) && livecheck_url_string + resource_version_info[:meta][:url][:symbol] = + livecheck_url + end + resource_version_info[:meta][:url][:original] = original_url + resource_version_info[:meta][:url][:processed] = url if url != original_url + if strategy_data[:url].present? && strategy_data[:url] != url + resource_version_info[:meta][:url][:strategy] = strategy_data[:url] + end + resource_version_info[:meta][:url][:final] = strategy_data[:final_url] if strategy_data[:final_url] + resource_version_info[:meta][:strategy] = strategy.present? ? strategy_name : nil + if strategies.present? + resource_version_info[:meta][:strategies] = strategies.map do |s| + livecheck_strategy_names[s] + end + end + resource_version_info[:meta][:regex] = regex.inspect if regex.present? + resource_version_info[:meta][:cached] = true if strategy_data[:cached] == true + + rescue => e + Homebrew.failed = true + if json + status_hash(resource, "error", [e.to_s], verbose: verbose) + elsif !quiet + onoe "#{Tty.blue}#{resource.name}#{Tty.reset}: #{e}" + $stderr.puts e.backtrace if debug && !e.is_a?(Livecheck::Error) + nil + end + end + # rubocop:enable Metrics/BlockLength + resource_version_info + end end # rubocop:enable Metrics/ModuleLength end From 03c372ef52fa2fffe6d8677f563ddbcf1f95c714 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Sun, 25 Sep 2022 02:06:23 +0200 Subject: [PATCH 114/138] Minor fixes --- Library/Homebrew/livecheck/skip_conditions.rb | 6 +++--- Library/Homebrew/test/livecheck/livecheck_spec.rb | 14 ++++---------- 2 files changed, 7 insertions(+), 13 deletions(-) diff --git a/Library/Homebrew/livecheck/skip_conditions.rb b/Library/Homebrew/livecheck/skip_conditions.rb index 7991f2d07d..3e1fefe3f6 100644 --- a/Library/Homebrew/livecheck/skip_conditions.rb +++ b/Library/Homebrew/livecheck/skip_conditions.rb @@ -33,7 +33,7 @@ module Homebrew stable_from_internet_archive = stable_url.match?(%r{https?://web\.archive\.org/}i) end - skip_message = if package_or_resource.livecheck&.skip_msg.present? + skip_message = if package_or_resource.livecheck.skip_msg.present? package_or_resource.livecheck.skip_msg elsif !livecheckable if stable_from_google_code_archive @@ -45,7 +45,7 @@ module Homebrew end end - return {} if !package_or_resource.livecheck&.skip? && skip_message.blank? + 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) @@ -172,7 +172,7 @@ module Homebrew :cask_url_unversioned, ].freeze - # Skip conditions for resource + # Skip conditions for resource. RESOURCE_CHECKS = [ :package_or_resource_skip, ].freeze diff --git a/Library/Homebrew/test/livecheck/livecheck_spec.rb b/Library/Homebrew/test/livecheck/livecheck_spec.rb index bb43d2b7da..fdc076dc47 100644 --- a/Library/Homebrew/test/livecheck/livecheck_spec.rb +++ b/Library/Homebrew/test/livecheck/livecheck_spec.rb @@ -11,6 +11,7 @@ describe Homebrew::Livecheck do let(:homepage_url) { "https://brew.sh" } let(:livecheck_url) { "https://formulae.brew.sh/api/formula/ruby.json" } let(:stable_url) { "https://brew.sh/test-0.0.1.tgz" } + let(:resource_url) { "https://brew.sh/foo-1.0.tar.gz" } let(:f) do formula("test") do @@ -116,6 +117,7 @@ describe Homebrew::Livecheck do homepage_url_s = homepage_url stable_url_s = stable_url head_url_s = head_url + resource_url_s = resource_url formula("test_livecheck_url") do desc "Test Livecheck URL formula" @@ -124,7 +126,7 @@ describe Homebrew::Livecheck do head head_url_s resource "foo" do - url "https://brew.sh/foo-1.0.tar.gz" + url resource_url_s sha256 "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef" livecheck do @@ -164,15 +166,7 @@ describe Homebrew::Livecheck do expect(livecheck.livecheck_url_to_string(:homepage, c_livecheck_url)).to eq(homepage_url) expect(livecheck.livecheck_url_to_string(:stable, f_livecheck_url)).to eq(stable_url) expect(livecheck.livecheck_url_to_string(:url, c_livecheck_url)).to eq(cask_url) - - r_livecheck_url.livecheck.url(:url) - expect(livecheck.livecheck_url_to_string(cask_url, r_livecheck_url)).to eq(cask_url) - - r_livecheck_url.livecheck.url(:head) - expect(livecheck.livecheck_url_to_string(head_url, r_livecheck_url)).to eq(head_url) - - r_livecheck_url.livecheck.url(:stable) - expect(livecheck.livecheck_url_to_string(stable_url, r_livecheck_url)).to eq(stable_url) + expect(livecheck.livecheck_url_to_string(:url, r_livecheck_url)).to eq(resource_url) end it "returns nil when not given a string or valid symbol" do From 2f74eb5b5b1172e8ecfb0fc03f3f3ddfc5e3ff8c Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Sun, 25 Sep 2022 22:21:04 +0500 Subject: [PATCH 115/138] Update Library/Homebrew/livecheck/livecheck.rb Co-authored-by: Sam Ford <1584702+samford@users.noreply.github.com> --- Library/Homebrew/livecheck/livecheck.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index e50aac01e0..cb29be0831 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -873,7 +873,7 @@ module Homebrew resource_version_info = {} livecheck = resource.livecheck - livecheck_url = has_livecheckable ? livecheck.url : resource.url + livecheck_url = livecheck.url livecheck_regex = livecheck.regex livecheck_strategy = livecheck.strategy livecheck_strategy_block = livecheck.strategy_block From ae031041a28d12ba7da987ed7ca7161a9b925a07 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Sun, 25 Sep 2022 20:48:44 +0200 Subject: [PATCH 116/138] Refactored code --- Library/Homebrew/livecheck/livecheck.rb | 54 ++++++++++++------------- 1 file changed, 25 insertions(+), 29 deletions(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index e50aac01e0..f49d9e0e7c 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -247,37 +247,11 @@ module Homebrew ) end - # Check current and latest resources (if "--resources" flag is given) - # Only check current and latest versions if we have resources to check against - 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) - if res_skip_info.present? - res_skip_info - else - res_version_info = resource_version( - resource, - json: json, - debug: debug, - quiet: quiet, - verbose: verbose, - ) - if res_version_info.empty? - status_hash(resource, "error", ["Unable to get versions"], verbose: verbose) - else - res_version_info - end - end - end.compact_blank - end - skip_info ||= SkipConditions.skip_information(formula_or_cask, full_name: use_full_name, verbose: verbose) if skip_info.present? next skip_info if json && !newer_only SkipConditions.print_skip_information(skip_info) if !newer_only && !quiet - print_resources_info(resource_version_info, verbose: verbose) if check_for_resources next end @@ -312,6 +286,31 @@ module Homebrew version_info[:latest] if version_info.present? end + # Check current and latest resources (if "--resources" flag is given) + # Only check current and latest versions if we have resources to check against + 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) + if res_skip_info.present? + res_skip_info + else + res_version_info = resource_version( + resource, + json: json, + debug: debug, + quiet: quiet, + verbose: verbose, + ) + if res_version_info.empty? + status_hash(resource, "error", ["Unable to get versions"], verbose: verbose) + else + res_version_info + end + end + end.compact_blank + end + if latest.blank? no_versions_msg = "Unable to get versions" raise Livecheck::Error, no_versions_msg unless json @@ -526,9 +525,6 @@ module Homebrew when :url package_or_resource.url&.to_s if package_or_resource.is_a?(Cask::Cask) || package_or_resource.is_a?(Resource) when :head, :stable - # Since resource's "url" is considered "stable" by default. - # And some resources may contain in "head" block as well - package_or_resource.send(:url)&.to_s if package_or_resource.is_a?(Resource) package_or_resource.send(livecheck_url)&.url if package_or_resource.is_a?(Formula) when :homepage package_or_resource.homepage unless package_or_resource.is_a?(Resource) From e3cab15e935233ea5de0420a76c16dae3f80ba2f Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Mon, 26 Sep 2022 19:37:46 +0200 Subject: [PATCH 117/138] Set `Homebrew.failed = true` to get correct status code --- Library/Homebrew/livecheck/livecheck.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index 4e6d346700..9c7c4131d3 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -309,6 +309,7 @@ module Homebrew end end end.compact_blank + Homebrew.failed = true if resource_version_info.any? { |info| info[:status] == "error" } end if latest.blank? @@ -501,7 +502,6 @@ module Homebrew info.each do |r_info| if r_info[:status] && r_info[:messages] SkipConditions.print_skip_information(r_info) - Homebrew.failed = true else print_latest_version( r_info, From 40b0070bebf6ef34435ebd521c14c5a3770fca34 Mon Sep 17 00:00:00 2001 From: Sam Ford <1584702+samford@users.noreply.github.com> Date: Tue, 27 Sep 2022 00:18:20 -0400 Subject: [PATCH 118/138] Modify comments and other text The `check_for_resources` code arguably speaks for itself, so it doesn't feel like a necessary addition. Besides that, this cleans up some other comments and text to better align with existing examples. --- Library/Homebrew/livecheck/livecheck.rb | 4 +--- Library/Homebrew/livecheck/skip_conditions.rb | 2 +- Library/Homebrew/test/livecheck/livecheck_spec.rb | 4 ++-- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index 9c7c4131d3..bacc7a638d 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -286,8 +286,6 @@ module Homebrew version_info[:latest] if version_info.present? end - # Check current and latest resources (if "--resources" flag is given) - # Only check current and latest versions if we have resources to check against 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| @@ -531,7 +529,7 @@ module Homebrew end end - # Returns an Array containing the formula/resource/cask URLs that can be used by livecheck. + # Returns an Array containing the formula/cask/resource URLs that can be used by livecheck. sig { params(package_or_resource: T.any(Formula, Cask::Cask, Resource)).returns(T::Array[String]) } def checkable_urls(package_or_resource) urls = [] diff --git a/Library/Homebrew/livecheck/skip_conditions.rb b/Library/Homebrew/livecheck/skip_conditions.rb index 3e1fefe3f6..be5159cb97 100644 --- a/Library/Homebrew/livecheck/skip_conditions.rb +++ b/Library/Homebrew/livecheck/skip_conditions.rb @@ -172,7 +172,7 @@ module Homebrew :cask_url_unversioned, ].freeze - # Skip conditions for resource. + # Skip conditions for resources. RESOURCE_CHECKS = [ :package_or_resource_skip, ].freeze diff --git a/Library/Homebrew/test/livecheck/livecheck_spec.rb b/Library/Homebrew/test/livecheck/livecheck_spec.rb index fdc076dc47..c23f2391b9 100644 --- a/Library/Homebrew/test/livecheck/livecheck_spec.rb +++ b/Library/Homebrew/test/livecheck/livecheck_spec.rb @@ -152,11 +152,11 @@ describe Homebrew::Livecheck do RUBY end - it "returns a URL string when given a livecheck_url string for formula" do + it "returns a URL string when given a livecheck_url string for a formula" do expect(livecheck.livecheck_url_to_string(livecheck_url, f_livecheck_url)).to eq(livecheck_url) end - it "returns a URL string when given a livecheck_url string for resource" do + it "returns a URL string when given a livecheck_url string for a resource" do expect(livecheck.livecheck_url_to_string(livecheck_url, r_livecheck_url)).to eq(livecheck_url) end From 7ffeba6380035e190efdf7eb7a003dd51e356cea Mon Sep 17 00:00:00 2001 From: Sam Ford <1584702+samford@users.noreply.github.com> Date: Tue, 27 Sep 2022 00:21:18 -0400 Subject: [PATCH 119/138] Convert some multiline code into a single line Using a multiline format in these areas isn't necessary and we can clean up these lines by converting them to a single line format. --- Library/Homebrew/livecheck/livecheck.rb | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index bacc7a638d..44e1a15f68 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -872,10 +872,7 @@ module Homebrew livecheck_strategy = livecheck.strategy livecheck_strategy_block = livecheck.strategy_block - livecheck_url_string = livecheck_url_to_string( - livecheck_url, - resource, - ) + livecheck_url_string = livecheck_url_to_string(livecheck_url, resource) urls = [livecheck_url_string] if livecheck_url_string urls ||= checkable_urls(resource) @@ -1001,8 +998,7 @@ module Homebrew resource_version_info[:meta] = { livecheckable: has_livecheckable, url: {} } if livecheck_url.is_a?(Symbol) && livecheck_url_string - resource_version_info[:meta][:url][:symbol] = - livecheck_url + resource_version_info[:meta][:url][:symbol] = livecheck_url end resource_version_info[:meta][:url][:original] = original_url resource_version_info[:meta][:url][:processed] = url if url != original_url From fb653c00d8152da765b56c0bb1ae7bba5bf7002d Mon Sep 17 00:00:00 2001 From: Sam Ford <1584702+samford@users.noreply.github.com> Date: Tue, 27 Sep 2022 00:27:26 -0400 Subject: [PATCH 120/138] Improve consistency of *_version methods Minimizing the differences between the `#resource_version` and `#latest_version` methods will help to ease the process of potentially merging them into one method in the future. --- Library/Homebrew/livecheck/livecheck.rb | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index 44e1a15f68..722297ddbb 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -779,7 +779,6 @@ module Homebrew version.to_s.include?(rejection) end end - next if match_version_map.blank? if debug @@ -878,7 +877,6 @@ module Homebrew urls ||= checkable_urls(resource) checked_urls = [] - # rubocop:disable Metrics/BlockLength urls.each_with_index do |original_url, i| # Only preprocess the URL when it's appropriate @@ -896,7 +894,6 @@ module Homebrew regex_provided: livecheck_regex.present?, block_provided: livecheck_strategy_block.present?, ) - strategy = Strategy.from_symbol(livecheck_strategy) || strategies.first strategy_name = livecheck_strategy_names[strategy] @@ -929,8 +926,10 @@ module Homebrew next if strategy.blank? strategy_data = strategy.find_versions( - url: url, regex: livecheck_regex, - homebrew_curl: false, &livecheck_strategy_block + url: url, + regex: livecheck_regex, + homebrew_curl: false, + &livecheck_strategy_block ) match_version_map = strategy_data[:matches] regex = strategy_data[:regex] @@ -1008,9 +1007,7 @@ module Homebrew resource_version_info[:meta][:url][:final] = strategy_data[:final_url] if strategy_data[:final_url] resource_version_info[:meta][:strategy] = strategy.present? ? strategy_name : nil if strategies.present? - resource_version_info[:meta][:strategies] = strategies.map do |s| - livecheck_strategy_names[s] - end + resource_version_info[:meta][:strategies] = strategies.map { |s| livecheck_strategy_names[s] } end resource_version_info[:meta][:regex] = regex.inspect if regex.present? resource_version_info[:meta][:cached] = true if strategy_data[:cached] == true From bd9c436d50c71eef58b3f9ba511e701cf27b377c Mon Sep 17 00:00:00 2001 From: Sam Ford <1584702+samford@users.noreply.github.com> Date: Tue, 27 Sep 2022 00:36:33 -0400 Subject: [PATCH 121/138] Remove unnecessary parameter from method A boolean `resource` parameter was added to `#print_latest_version` but its only purpose is to identify whether `info` corresponds to a resource. This can be achieved using `info[:resource].present?`, so this additional parameter isn't necessary and can be removed. --- Library/Homebrew/livecheck/livecheck.rb | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index 722297ddbb..086b4cfcd8 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -472,9 +472,9 @@ module Homebrew end # Formats and prints the livecheck result for a formula/cask/resource. - sig { params(info: Hash, verbose: T::Boolean, ambiguous_cask: T::Boolean, resource: T::Boolean).void } - def print_latest_version(info, verbose: false, ambiguous_cask: false, resource: false) - package_or_resource_s = resource ? " " : "" + sig { params(info: Hash, verbose: T::Boolean, ambiguous_cask: T::Boolean).void } + def print_latest_version(info, verbose: false, ambiguous_cask: false) + package_or_resource_s = info[:resource].present? ? " " : "" package_or_resource_s += "#{Tty.blue}#{info[:formula] || info[:cask] || info[:resource]}#{Tty.reset}" package_or_resource_s += " (cask)" if ambiguous_cask package_or_resource_s += " (guessed)" if verbose && !info[:meta][:livecheckable] @@ -501,11 +501,7 @@ module Homebrew if r_info[:status] && r_info[:messages] SkipConditions.print_skip_information(r_info) else - print_latest_version( - r_info, - verbose: verbose, - resource: true, - ) + print_latest_version(r_info, verbose: verbose) end end end From b5c88419808c82983869ed09ecedfae3656bfe17 Mon Sep 17 00:00:00 2001 From: Nanda H Krishna Date: Tue, 27 Sep 2022 00:59:37 -0700 Subject: [PATCH 122/138] Modified text in comments --- Library/Homebrew/livecheck/livecheck.rb | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/Library/Homebrew/livecheck/livecheck.rb b/Library/Homebrew/livecheck/livecheck.rb index 086b4cfcd8..f4ae28f06a 100644 --- a/Library/Homebrew/livecheck/livecheck.rb +++ b/Library/Homebrew/livecheck/livecheck.rb @@ -494,7 +494,7 @@ module Homebrew puts "#{package_or_resource_s}: #{current_s} ==> #{latest_s}" end - # Prints the livecheck result for a resources for a given Formula. + # Prints the livecheck result for the resources of a given Formula. sig { params(info: T::Array[Hash], verbose: T::Boolean).void } def print_resources_info(info, verbose: false) info.each do |r_info| @@ -832,9 +832,8 @@ module Homebrew end # rubocop:enable Metrics/CyclomaticComplexity - # Identifies the latest version of the resource in a given Formulae and returns a Hash containing - # the version information for a resource. Returns a nil value if a latest version - # couldn't be found for a given resource. + # Identifies the latest version of a resource and returns a Hash containing the + # version information. Returns nil if a latest version couldn't be found. sig { params( resource: Resource, From ad7561955401b051f716dcd2676ecbf99067b703 Mon Sep 17 00:00:00 2001 From: apainintheneck Date: Tue, 27 Sep 2022 21:14:37 -0700 Subject: [PATCH 123/138] Remove unused function from bump-cask-pr --- Library/Homebrew/dev-cmd/bump-cask-pr.rb | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/Library/Homebrew/dev-cmd/bump-cask-pr.rb b/Library/Homebrew/dev-cmd/bump-cask-pr.rb index 0bb1d7a821..dd697a490f 100644 --- a/Library/Homebrew/dev-cmd/bump-cask-pr.rb +++ b/Library/Homebrew/dev-cmd/bump-cask-pr.rb @@ -188,19 +188,6 @@ module Homebrew GitHub.create_bump_pr(pr_info, args: args) end - def fetch_cask(contents, config: nil) - cask = Cask::CaskLoader.load(contents) - cask.config = config if config.present? - old_hash = cask.sha256.to_s - - cask_download = Cask::Download.new(cask, quarantine: true) - download = cask_download.fetch(verify_download_integrity: false) - Utils::Tar.validate_file(download) - new_hash = download.sha256 - - [old_hash, new_hash] - end - def check_open_pull_requests(cask, args:) tap_remote_repo = cask.tap.remote_repo || cask.tap.full_name GitHub.check_for_duplicate_pull_requests(cask.token, tap_remote_repo, From 354852f8488b8acb5b2ce806bec8b4dde56a535a Mon Sep 17 00:00:00 2001 From: Michka Popoff Date: Thu, 8 Sep 2022 11:22:48 +0200 Subject: [PATCH 124/138] brew: remove HOMEBREW_ON_DEBIAN7 This is not used anymore, we are building on ubuntu 16.04 for our portable packages: https://github.com/Homebrew/homebrew-portable-ruby --- Library/Homebrew/brew.sh | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/Library/Homebrew/brew.sh b/Library/Homebrew/brew.sh index 86b0e855a6..e4ce548e7d 100644 --- a/Library/Homebrew/brew.sh +++ b/Library/Homebrew/brew.sh @@ -508,18 +508,9 @@ else : "${HOMEBREW_OS_VERSION:=$(uname -r)}" HOMEBREW_OS_USER_AGENT_VERSION="${HOMEBREW_OS_VERSION}" - # This is set by the user environment. - # shellcheck disable=SC2154 - if [[ -n "${HOMEBREW_ON_DEBIAN7}" ]] - then - # Special version for our debian 7 docker container used to build binutils - HOMEBREW_MINIMUM_CURL_VERSION="7.25.0" - HOMEBREW_SYSTEM_CA_CERTIFICATES_TOO_OLD="1" - HOMEBREW_FORCE_BREWED_CA_CERTIFICATES="1" - else - # Ensure the system Curl is a version that supports modern HTTPS certificates. - HOMEBREW_MINIMUM_CURL_VERSION="7.41.0" - fi + # Ensure the system Curl is a version that supports modern HTTPS certificates. + HOMEBREW_MINIMUM_CURL_VERSION="7.41.0" + curl_version_output="$(${HOMEBREW_CURL} --version 2>/dev/null)" curl_name_and_version="${curl_version_output%% (*}" # shellcheck disable=SC2248 From 4b560e11e7109480e2213509c0ac3b22e1adb788 Mon Sep 17 00:00:00 2001 From: Adrian Ho Date: Thu, 29 Sep 2022 16:33:44 +0800 Subject: [PATCH 125/138] Enable Linux AArch64 support Register system loader and arch tag for proper builds and bottling. --- Library/Homebrew/extend/os/linux/linkage_checker.rb | 1 + Library/Homebrew/hardware.rb | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/Library/Homebrew/extend/os/linux/linkage_checker.rb b/Library/Homebrew/extend/os/linux/linkage_checker.rb index b708cf23a9..2f672353d3 100644 --- a/Library/Homebrew/extend/os/linux/linkage_checker.rb +++ b/Library/Homebrew/extend/os/linux/linkage_checker.rb @@ -7,6 +7,7 @@ class LinkageChecker # Libraries provided by glibc and gcc. SYSTEM_LIBRARY_ALLOWLIST = %w[ ld-linux-x86-64.so.2 + ld-linux-aarch64.so.1 libanl.so.1 libatomic.so.1 libc.so.6 diff --git a/Library/Homebrew/hardware.rb b/Library/Homebrew/hardware.rb index 52bf2e5e88..804085f0e8 100644 --- a/Library/Homebrew/hardware.rb +++ b/Library/Homebrew/hardware.rb @@ -11,7 +11,7 @@ module Hardware INTEL_64BIT_ARCHS = [:x86_64].freeze PPC_32BIT_ARCHS = [:ppc, :ppc32, :ppc7400, :ppc7450, :ppc970].freeze PPC_64BIT_ARCHS = [:ppc64, :ppc64le, :ppc970].freeze - ARM_64BIT_ARCHS = [:arm64].freeze + ARM_64BIT_ARCHS = [:arm64, :aarch64].freeze ALL_ARCHS = [ *INTEL_32BIT_ARCHS, *INTEL_64BIT_ARCHS, From a49ad32a33e4328b973c778653ff19cf2834dd9c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 29 Sep 2022 18:04:29 +0000 Subject: [PATCH 126/138] build(deps): bump rspec_junit_formatter in /Library/Homebrew Bumps [rspec_junit_formatter](https://github.com/sj26/rspec_junit_formatter) from 0.5.1 to 0.6.0. - [Release notes](https://github.com/sj26/rspec_junit_formatter/releases) - [Changelog](https://github.com/sj26/rspec_junit_formatter/blob/main/CHANGELOG.md) - [Commits](https://github.com/sj26/rspec_junit_formatter/compare/v0.5.1...v0.6.0) --- updated-dependencies: - dependency-name: rspec_junit_formatter dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Library/Homebrew/Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Library/Homebrew/Gemfile.lock b/Library/Homebrew/Gemfile.lock index 277f233905..3193bd0b10 100644 --- a/Library/Homebrew/Gemfile.lock +++ b/Library/Homebrew/Gemfile.lock @@ -122,7 +122,7 @@ GEM rspec-support (3.11.1) rspec-wait (0.0.9) rspec (>= 3, < 4) - rspec_junit_formatter (0.5.1) + rspec_junit_formatter (0.6.0) rspec-core (>= 2, < 4, != 2.12.0) rubocop (1.35.1) json (~> 2.3) From ffc2d0eec6d08c7f073b4d96bb9f9295c02f6301 Mon Sep 17 00:00:00 2001 From: BrewTestBot <1589480+BrewTestBot@users.noreply.github.com> Date: Thu, 29 Sep 2022 18:21:40 +0000 Subject: [PATCH 127/138] brew vendor-gems: commit updates. --- Library/Homebrew/vendor/bundle/bundler/setup.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Library/Homebrew/vendor/bundle/bundler/setup.rb b/Library/Homebrew/vendor/bundle/bundler/setup.rb index f33815148b..5c15437c1c 100644 --- a/Library/Homebrew/vendor/bundle/bundler/setup.rb +++ b/Library/Homebrew/vendor/bundle/bundler/setup.rb @@ -82,7 +82,7 @@ $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rspec-its-1.3.0/lib" $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rspec-retry-0.6.2/lib" $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rspec-sorbet-1.9.0/lib" $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rspec-wait-0.0.9/lib" -$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rspec_junit_formatter-0.5.1/lib" +$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rspec_junit_formatter-0.6.0/lib" $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rubocop-ast-1.21.0/lib" $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/ruby-progressbar-1.11.0/lib" $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/unicode-display_width-2.3.0/lib" From f1e01d4ccd3a987c560b2345bcbd61a9664a726d Mon Sep 17 00:00:00 2001 From: BrewTestBot <1589480+BrewTestBot@users.noreply.github.com> Date: Thu, 29 Sep 2022 18:28:03 +0000 Subject: [PATCH 128/138] Update RBI files for rspec_junit_formatter. Autogenerated by the [vendor-gems](https://github.com/Homebrew/brew/blob/HEAD/.github/workflows/vendor-gemss.yml) workflow. --- ..._junit_formatter@0.5.1.rbi => rspec_junit_formatter@0.6.0.rbi} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename Library/Homebrew/sorbet/rbi/gems/{rspec_junit_formatter@0.5.1.rbi => rspec_junit_formatter@0.6.0.rbi} (100%) diff --git a/Library/Homebrew/sorbet/rbi/gems/rspec_junit_formatter@0.5.1.rbi b/Library/Homebrew/sorbet/rbi/gems/rspec_junit_formatter@0.6.0.rbi similarity index 100% rename from Library/Homebrew/sorbet/rbi/gems/rspec_junit_formatter@0.5.1.rbi rename to Library/Homebrew/sorbet/rbi/gems/rspec_junit_formatter@0.6.0.rbi From c9b77be505fc3ab0ee0eb28cabc9504286b8450c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 30 Sep 2022 18:05:26 +0000 Subject: [PATCH 129/138] build(deps): bump msgpack from 1.5.6 to 1.6.0 in /Library/Homebrew Bumps [msgpack](https://github.com/msgpack/msgpack-ruby) from 1.5.6 to 1.6.0. - [Release notes](https://github.com/msgpack/msgpack-ruby/releases) - [Changelog](https://github.com/msgpack/msgpack-ruby/blob/master/ChangeLog) - [Commits](https://github.com/msgpack/msgpack-ruby/compare/v1.5.6...v1.6.0) --- updated-dependencies: - dependency-name: msgpack dependency-type: indirect update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Library/Homebrew/Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Library/Homebrew/Gemfile.lock b/Library/Homebrew/Gemfile.lock index 3193bd0b10..93cb79cd4e 100644 --- a/Library/Homebrew/Gemfile.lock +++ b/Library/Homebrew/Gemfile.lock @@ -58,7 +58,7 @@ GEM mime-types-data (3.2022.0105) mini_portile2 (2.8.0) minitest (5.16.3) - msgpack (1.5.6) + msgpack (1.6.0) mustache (1.1.1) net-http-digest_auth (1.4.1) net-http-persistent (4.0.1) From e97ea3a0ec2b97c95b671edb6c1b18da64b2122d Mon Sep 17 00:00:00 2001 From: BrewTestBot <1589480+BrewTestBot@users.noreply.github.com> Date: Fri, 30 Sep 2022 18:09:23 +0000 Subject: [PATCH 130/138] brew vendor-gems: commit updates. --- Library/Homebrew/vendor/bundle/bundler/setup.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Library/Homebrew/vendor/bundle/bundler/setup.rb b/Library/Homebrew/vendor/bundle/bundler/setup.rb index 5c15437c1c..c8dded55b9 100644 --- a/Library/Homebrew/vendor/bundle/bundler/setup.rb +++ b/Library/Homebrew/vendor/bundle/bundler/setup.rb @@ -13,8 +13,8 @@ $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/public_suffix-5.0.0/l $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/addressable-2.8.1/lib" $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/ast-2.4.2/lib" $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/bindata-2.4.11/lib" -$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/extensions/universal-darwin-21/2.6.0/msgpack-1.5.6" -$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/msgpack-1.5.6/lib" +$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/extensions/universal-darwin-21/2.6.0/msgpack-1.6.0" +$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/msgpack-1.6.0/lib" $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/extensions/universal-darwin-21/2.6.0/bootsnap-1.13.0" $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/bootsnap-1.13.0/lib" $:.unshift "#{path}/" From 65fc3ca39a7e59a795fc8499cea1ca63b271643c Mon Sep 17 00:00:00 2001 From: BrewTestBot <1589480+BrewTestBot@users.noreply.github.com> Date: Fri, 30 Sep 2022 18:16:19 +0000 Subject: [PATCH 131/138] Update RBI files for msgpack. Autogenerated by the [vendor-gems](https://github.com/Homebrew/brew/blob/HEAD/.github/workflows/vendor-gemss.yml) workflow. --- .../sorbet/rbi/gems/{msgpack@1.5.6.rbi => msgpack@1.6.0.rbi} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename Library/Homebrew/sorbet/rbi/gems/{msgpack@1.5.6.rbi => msgpack@1.6.0.rbi} (100%) diff --git a/Library/Homebrew/sorbet/rbi/gems/msgpack@1.5.6.rbi b/Library/Homebrew/sorbet/rbi/gems/msgpack@1.6.0.rbi similarity index 100% rename from Library/Homebrew/sorbet/rbi/gems/msgpack@1.5.6.rbi rename to Library/Homebrew/sorbet/rbi/gems/msgpack@1.6.0.rbi From 1de0ecf4e14cc0f53e200f4e1fe73caf034ba578 Mon Sep 17 00:00:00 2001 From: BrewTestBot <1589480+BrewTestBot@users.noreply.github.com> Date: Sun, 2 Oct 2022 17:32:21 +0000 Subject: [PATCH 132/138] Update manpage and completions. Autogenerated by the [sponsors-maintainers-man-completions](https://github.com/Homebrew/brew/blob/HEAD/.github/workflows/sponsors-maintainers-man-completions.yml) workflow. --- completions/bash/brew | 2 ++ completions/fish/brew.fish | 2 ++ completions/zsh/_brew | 2 ++ docs/Manpage.md | 2 ++ manpages/brew.1 | 4 ++++ 5 files changed, 12 insertions(+) diff --git a/completions/bash/brew b/completions/bash/brew index 10cd747cb7..643ffb1817 100644 --- a/completions/bash/brew +++ b/completions/bash/brew @@ -1261,6 +1261,7 @@ _brew_lc() { --json --newer-only --quiet + --resources --tap --verbose " @@ -1375,6 +1376,7 @@ _brew_livecheck() { --json --newer-only --quiet + --resources --tap --verbose " diff --git a/completions/fish/brew.fish b/completions/fish/brew.fish index 4b54f2d4d4..216e0a1dcd 100644 --- a/completions/fish/brew.fish +++ b/completions/fish/brew.fish @@ -911,6 +911,7 @@ __fish_brew_complete_arg 'lc' -l installed -d 'Check formulae and casks that are __fish_brew_complete_arg 'lc' -l json -d 'Output information in JSON format' __fish_brew_complete_arg 'lc' -l newer-only -d 'Show the latest version only if it\'s newer than the formula/cask' __fish_brew_complete_arg 'lc' -l quiet -d 'Suppress warnings, don\'t print a progress bar for JSON output' +__fish_brew_complete_arg 'lc' -l resources -d 'Also check resources for formulae' __fish_brew_complete_arg 'lc' -l tap -d 'Check formulae and casks within the given tap, specified as user`/`repo' __fish_brew_complete_arg 'lc' -l verbose -d 'Make some output more verbose' __fish_brew_complete_arg 'lc; and not __fish_seen_argument -l cask -l casks' -a '(__fish_brew_suggest_formulae_all)' @@ -980,6 +981,7 @@ __fish_brew_complete_arg 'livecheck' -l installed -d 'Check formulae and casks t __fish_brew_complete_arg 'livecheck' -l json -d 'Output information in JSON format' __fish_brew_complete_arg 'livecheck' -l newer-only -d 'Show the latest version only if it\'s newer than the formula/cask' __fish_brew_complete_arg 'livecheck' -l quiet -d 'Suppress warnings, don\'t print a progress bar for JSON output' +__fish_brew_complete_arg 'livecheck' -l resources -d 'Also check resources for formulae' __fish_brew_complete_arg 'livecheck' -l tap -d 'Check formulae and casks within the given tap, specified as user`/`repo' __fish_brew_complete_arg 'livecheck' -l verbose -d 'Make some output more verbose' __fish_brew_complete_arg 'livecheck; and not __fish_seen_argument -l cask -l casks' -a '(__fish_brew_suggest_formulae_all)' diff --git a/completions/zsh/_brew b/completions/zsh/_brew index e219390246..5495214012 100644 --- a/completions/zsh/_brew +++ b/completions/zsh/_brew @@ -1107,6 +1107,7 @@ _brew_lc() { '(--debug)--json[Output information in JSON format]' \ '--newer-only[Show the latest version only if it'\''s newer than the formula/cask]' \ '--quiet[Suppress warnings, don'\''t print a progress bar for JSON output]' \ + '--resources[Also check resources for formulae]' \ '(--eval-all --installed)--tap[Check formulae and casks within the given tap, specified as user`/`repo]' \ '--verbose[Make some output more verbose]' \ - formula \ @@ -1192,6 +1193,7 @@ _brew_livecheck() { '(--debug)--json[Output information in JSON format]' \ '--newer-only[Show the latest version only if it'\''s newer than the formula/cask]' \ '--quiet[Suppress warnings, don'\''t print a progress bar for JSON output]' \ + '--resources[Also check resources for formulae]' \ '(--eval-all --installed)--tap[Check formulae and casks within the given tap, specified as user`/`repo]' \ '--verbose[Make some output more verbose]' \ - formula \ diff --git a/docs/Manpage.md b/docs/Manpage.md index cc87074b45..78aa6313e3 100644 --- a/docs/Manpage.md +++ b/docs/Manpage.md @@ -1267,6 +1267,8 @@ casks to check is taken from `HOMEBREW_LIVECHECK_WATCHLIST` or Show the latest version only if it's newer than the formula/cask. * `--json`: Output information in JSON format. +* `-r`, `--resources`: + Also check resources for formulae. * `-q`, `--quiet`: Suppress warnings, don't print a progress bar for JSON output. * `--formula`: diff --git a/manpages/brew.1 b/manpages/brew.1 index add3c39520..637a107031 100644 --- a/manpages/brew.1 +++ b/manpages/brew.1 @@ -1810,6 +1810,10 @@ Show the latest version only if it\'s newer than the formula/cask\. Output information in JSON format\. . .TP +\fB\-r\fR, \fB\-\-resources\fR +Also check resources for formulae\. +. +.TP \fB\-q\fR, \fB\-\-quiet\fR Suppress warnings, don\'t print a progress bar for JSON output\. . From 07ac5bf3b60278dbff15d13dbd798d342588347e Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Tue, 27 Sep 2022 14:45:49 +0200 Subject: [PATCH 133/138] Update doc for `brew livecheck` --- docs/Brew-Livecheck.md | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/docs/Brew-Livecheck.md b/docs/Brew-Livecheck.md index fbbef6c7dc..9e7951f117 100644 --- a/docs/Brew-Livecheck.md +++ b/docs/Brew-Livecheck.md @@ -1,27 +1,29 @@ # `brew livecheck` -The `brew livecheck` command finds the newest version of a formula or cask's software by checking upstream. Livecheck has [strategies](https://rubydoc.brew.sh/Homebrew/Livecheck/Strategy.html) to identify versions from various sources, such as Git repositories, websites, etc. +The `brew livecheck` command finds the newest version of a formula, cask or resource's software by checking upstream. Livecheck has [strategies](https://rubydoc.brew.sh/Homebrew/Livecheck/Strategy.html) to identify versions from various sources, such as Git repositories, websites, etc. ## Behavior When livecheck isn't given instructions for how to check for upstream versions, it does the following by default: -1. For formulae: Collect the `head`, `stable`, and `homepage` URLs, in that order. For casks: Collect the `url` and `homepage` URLs, in that order. -1. Determine if any strategies apply to the first URL. If not, try the next URL. -1. If a strategy can be applied, use it to check for new versions. -1. Return the newest version (or an error if versions could not be found at any available URLs). +1. For __formulae__: Collect the `stable`, `head` and `homepage` URLs, in that order. For __casks__: Collect the `appcast`, `url` and `homepage` URLs, in that order. For __resource__: Collect the `url` (since resource's url is considered `stable` by default) +2. Determine if any strategies apply to the first URL. If not, try the next URL. +3. If a strategy can be applied, use it to check for new versions. +4. Return the newest version (or an error if versions could not be found at any available URLs). It's sometimes necessary to override this default behavior to create a working check. If a source doesn't provide the newest version, we need to check a different one. If livecheck doesn't correctly match version text, we need to provide an appropriate regex or `strategy` block. -This can be accomplished by adding a `livecheck` block to the formula/cask. For more information on the available methods, please refer to the [`Livecheck` class documentation](https://rubydoc.brew.sh/Livecheck.html). +This can be accomplished by adding a `livecheck` block to the formula/cask/resource. For more information on the available methods, please refer to the [`Livecheck` class documentation](https://rubydoc.brew.sh/Livecheck.html). ## Creating a check -1. **Use the debug output to understand the situation**. `brew livecheck --debug |` provides information about which URLs livecheck tries, any strategies that apply, matched versions, etc. +1. **Use the debug output to understand the situation**. `brew livecheck --debug |` provides information about which URLs livecheck tries, any strategies that apply, matched versions, etc. `brew livecheck --debug --resources ` will provides livecheck's debug information about the resources as well. -1. **Research available sources to select a URL**. Try removing the file name from `stable`/`url`, to see if this is a directory listing page. If that doesn't work, try to find a page that links to the file (e.g. a download page). If it's not possible to find the newest version on the website, try checking other sources from the formula/cask. When necessary, search for other sources outside of the formula/cask. +> Note: `--resources` flag only works with Formulae. -1. **Create a regex, if necessary**. If the check works without a regex and wouldn't benefit from having one, it's usually fine to omit it. More information on creating regexes can be found in the [regex guidelines](#regex-guidelines) section. +2. **Research available sources to select a URL**. Try removing the file name from `stable`/`url`, to see if this is a directory listing page. If that doesn't work, try to find a page that links to the file (e.g. a download page). If it's not possible to find the newest version on the website, try checking other sources from the formula/cask. When necessary, search for other sources outside of the formula/cask. + +3. **Create a regex, if necessary**. If the check works without a regex and wouldn't benefit from having one, it's usually fine to omit it. More information on creating regexes can be found in the [regex guidelines](#regex-guidelines) section. ### General guidelines From de2972d8b5efae29328295504693ac45a6bf5ad9 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Wed, 28 Sep 2022 11:43:24 +0200 Subject: [PATCH 134/138] Reverted numbering from numbered lists to generic 1s --- docs/Brew-Livecheck.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/Brew-Livecheck.md b/docs/Brew-Livecheck.md index 9e7951f117..6ab088a6e6 100644 --- a/docs/Brew-Livecheck.md +++ b/docs/Brew-Livecheck.md @@ -7,9 +7,9 @@ The `brew livecheck` command finds the newest version of a formula, cask or reso When livecheck isn't given instructions for how to check for upstream versions, it does the following by default: 1. For __formulae__: Collect the `stable`, `head` and `homepage` URLs, in that order. For __casks__: Collect the `appcast`, `url` and `homepage` URLs, in that order. For __resource__: Collect the `url` (since resource's url is considered `stable` by default) -2. Determine if any strategies apply to the first URL. If not, try the next URL. -3. If a strategy can be applied, use it to check for new versions. -4. Return the newest version (or an error if versions could not be found at any available URLs). +1. Determine if any strategies apply to the first URL. If not, try the next URL. +1. If a strategy can be applied, use it to check for new versions. +1. Return the newest version (or an error if versions could not be found at any available URLs). It's sometimes necessary to override this default behavior to create a working check. If a source doesn't provide the newest version, we need to check a different one. If livecheck doesn't correctly match version text, we need to provide an appropriate regex or `strategy` block. @@ -21,9 +21,9 @@ This can be accomplished by adding a `livecheck` block to the formula/cask/resou > Note: `--resources` flag only works with Formulae. -2. **Research available sources to select a URL**. Try removing the file name from `stable`/`url`, to see if this is a directory listing page. If that doesn't work, try to find a page that links to the file (e.g. a download page). If it's not possible to find the newest version on the website, try checking other sources from the formula/cask. When necessary, search for other sources outside of the formula/cask. +1. **Research available sources to select a URL**. Try removing the file name from `stable`/`url`, to see if this is a directory listing page. If that doesn't work, try to find a page that links to the file (e.g. a download page). If it's not possible to find the newest version on the website, try checking other sources from the formula/cask. When necessary, search for other sources outside of the formula/cask. -3. **Create a regex, if necessary**. If the check works without a regex and wouldn't benefit from having one, it's usually fine to omit it. More information on creating regexes can be found in the [regex guidelines](#regex-guidelines) section. +1. **Create a regex, if necessary**. If the check works without a regex and wouldn't benefit from having one, it's usually fine to omit it. More information on creating regexes can be found in the [regex guidelines](#regex-guidelines) section. ### General guidelines From 50ccb96d7702dd5190ca6310d005f93b641029c8 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Sun, 2 Oct 2022 16:53:51 +0200 Subject: [PATCH 135/138] Reverted back changes --- docs/Brew-Livecheck.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/docs/Brew-Livecheck.md b/docs/Brew-Livecheck.md index 6ab088a6e6..976098b75c 100644 --- a/docs/Brew-Livecheck.md +++ b/docs/Brew-Livecheck.md @@ -1,6 +1,6 @@ # `brew livecheck` -The `brew livecheck` command finds the newest version of a formula, cask or resource's software by checking upstream. Livecheck has [strategies](https://rubydoc.brew.sh/Homebrew/Livecheck/Strategy.html) to identify versions from various sources, such as Git repositories, websites, etc. +The `brew livecheck` command finds the newest version of a formula or cask's software software by checking upstream. Livecheck has [strategies](https://rubydoc.brew.sh/Homebrew/Livecheck/Strategy.html) to identify versions from various sources, such as Git repositories, websites, etc. ## Behavior @@ -17,9 +17,7 @@ This can be accomplished by adding a `livecheck` block to the formula/cask/resou ## Creating a check -1. **Use the debug output to understand the situation**. `brew livecheck --debug |` provides information about which URLs livecheck tries, any strategies that apply, matched versions, etc. `brew livecheck --debug --resources ` will provides livecheck's debug information about the resources as well. - -> Note: `--resources` flag only works with Formulae. +1. **Use the debug output to understand the situation**. `brew livecheck --debug |` provides information about which URLs livecheck tries, any strategies that apply, matched versions, etc. 1. **Research available sources to select a URL**. Try removing the file name from `stable`/`url`, to see if this is a directory listing page. If that doesn't work, try to find a page that links to the file (e.g. a download page). If it's not possible to find the newest version on the website, try checking other sources from the formula/cask. When necessary, search for other sources outside of the formula/cask. From d66104f182eb90edc975676fa9b9d994a6021d00 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Sun, 2 Oct 2022 19:55:27 +0500 Subject: [PATCH 136/138] Update docs/Brew-Livecheck.md Co-authored-by: Sam Ford <1584702+samford@users.noreply.github.com> --- docs/Brew-Livecheck.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Brew-Livecheck.md b/docs/Brew-Livecheck.md index 976098b75c..54dbfd86e5 100644 --- a/docs/Brew-Livecheck.md +++ b/docs/Brew-Livecheck.md @@ -6,7 +6,7 @@ The `brew livecheck` command finds the newest version of a formula or cask's sof When livecheck isn't given instructions for how to check for upstream versions, it does the following by default: -1. For __formulae__: Collect the `stable`, `head` and `homepage` URLs, in that order. For __casks__: Collect the `appcast`, `url` and `homepage` URLs, in that order. For __resource__: Collect the `url` (since resource's url is considered `stable` by default) +1. For formulae: Collect the `stable`, `head`, and `homepage` URLs, in that order (resources simply use their `url`). For casks: Collect the `url` and `homepage` URLs, in that order. 1. Determine if any strategies apply to the first URL. If not, try the next URL. 1. If a strategy can be applied, use it to check for new versions. 1. Return the newest version (or an error if versions could not be found at any available URLs). From bd4a4e3254152ea07b74e6419595ca8b8b291139 Mon Sep 17 00:00:00 2001 From: Mohammad Zain Abbas Date: Mon, 3 Oct 2022 03:10:34 +0500 Subject: [PATCH 137/138] Update docs/Brew-Livecheck.md Co-authored-by: Eric Knibbe --- docs/Brew-Livecheck.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Brew-Livecheck.md b/docs/Brew-Livecheck.md index 54dbfd86e5..89bbf46a06 100644 --- a/docs/Brew-Livecheck.md +++ b/docs/Brew-Livecheck.md @@ -1,6 +1,6 @@ # `brew livecheck` -The `brew livecheck` command finds the newest version of a formula or cask's software software by checking upstream. Livecheck has [strategies](https://rubydoc.brew.sh/Homebrew/Livecheck/Strategy.html) to identify versions from various sources, such as Git repositories, websites, etc. +The `brew livecheck` command finds the newest version of a formula or cask's software by checking upstream. Livecheck has [strategies](https://rubydoc.brew.sh/Homebrew/Livecheck/Strategy.html) to identify versions from various sources, such as Git repositories, websites, etc. ## Behavior From 9701dc8ec0f8afa4b5337e561727b33842a63556 Mon Sep 17 00:00:00 2001 From: BrewTestBot <1589480+BrewTestBot@users.noreply.github.com> Date: Mon, 3 Oct 2022 09:41:20 +0000 Subject: [PATCH 138/138] Update manpage and completions. Autogenerated by the [sponsors-maintainers-man-completions](https://github.com/Homebrew/brew/blob/HEAD/.github/workflows/sponsors-maintainers-man-completions.yml) workflow. --- completions/bash/brew | 2 ++ completions/fish/brew.fish | 2 ++ completions/zsh/_brew | 2 ++ docs/Manpage.md | 2 ++ manpages/brew.1 | 4 ++++ 5 files changed, 12 insertions(+) diff --git a/completions/bash/brew b/completions/bash/brew index 643ffb1817..7c789ac9b0 100644 --- a/completions/bash/brew +++ b/completions/bash/brew @@ -1112,6 +1112,7 @@ _brew_instal() { --debug-symbols --dictionarydir --display-times + --dry-run --fetch-HEAD --fontdir --force @@ -1171,6 +1172,7 @@ _brew_install() { --debug-symbols --dictionarydir --display-times + --dry-run --fetch-HEAD --fontdir --force diff --git a/completions/fish/brew.fish b/completions/fish/brew.fish index 216e0a1dcd..15ce52a09d 100644 --- a/completions/fish/brew.fish +++ b/completions/fish/brew.fish @@ -798,6 +798,7 @@ __fish_brew_complete_arg 'instal' -l debug -d 'If brewing fails, open an interac __fish_brew_complete_arg 'instal' -l debug-symbols -d 'Generate debug symbols on build. Source will be retained in a cache directory. ' __fish_brew_complete_arg 'instal' -l dictionarydir -d 'Target location for Dictionaries (default: `~/Library/Dictionaries`)' __fish_brew_complete_arg 'instal' -l display-times -d 'Print install times for each package at the end of the run' +__fish_brew_complete_arg 'instal' -l dry-run -d 'Show what would be installed, but do not actually install anything' __fish_brew_complete_arg 'instal' -l fetch-HEAD -d 'Fetch the upstream repository to detect if the HEAD installation of the formula is outdated. Otherwise, the repository\'s HEAD will only be checked for updates when a new stable or development version has been released' __fish_brew_complete_arg 'instal' -l fontdir -d 'Target location for Fonts (default: `~/Library/Fonts`)' __fish_brew_complete_arg 'instal' -l force -d 'Install formulae without checking for previously installed keg-only or non-migrated versions. When installing casks, overwrite existing files (binaries and symlinks are excluded, unless originally from the same cask)' @@ -848,6 +849,7 @@ __fish_brew_complete_arg 'install' -l debug -d 'If brewing fails, open an intera __fish_brew_complete_arg 'install' -l debug-symbols -d 'Generate debug symbols on build. Source will be retained in a cache directory. ' __fish_brew_complete_arg 'install' -l dictionarydir -d 'Target location for Dictionaries (default: `~/Library/Dictionaries`)' __fish_brew_complete_arg 'install' -l display-times -d 'Print install times for each package at the end of the run' +__fish_brew_complete_arg 'install' -l dry-run -d 'Show what would be installed, but do not actually install anything' __fish_brew_complete_arg 'install' -l fetch-HEAD -d 'Fetch the upstream repository to detect if the HEAD installation of the formula is outdated. Otherwise, the repository\'s HEAD will only be checked for updates when a new stable or development version has been released' __fish_brew_complete_arg 'install' -l fontdir -d 'Target location for Fonts (default: `~/Library/Fonts`)' __fish_brew_complete_arg 'install' -l force -d 'Install formulae without checking for previously installed keg-only or non-migrated versions. When installing casks, overwrite existing files (binaries and symlinks are excluded, unless originally from the same cask)' diff --git a/completions/zsh/_brew b/completions/zsh/_brew index 5495214012..933a44e42a 100644 --- a/completions/zsh/_brew +++ b/completions/zsh/_brew @@ -983,6 +983,7 @@ _brew_instal() { '(--cask)--debug-symbols[Generate debug symbols on build. Source will be retained in a cache directory. ]' \ '(--formula)--dictionarydir[Target location for Dictionaries (default: `~/Library/Dictionaries`)]' \ '(--cask)--display-times[Print install times for each package at the end of the run]' \ + '--dry-run[Show what would be installed, but do not actually install anything]' \ '(--cask)--fetch-HEAD[Fetch the upstream repository to detect if the HEAD installation of the formula is outdated. Otherwise, the repository'\''s HEAD will only be checked for updates when a new stable or development version has been released]' \ '(--formula)--fontdir[Target location for Fonts (default: `~/Library/Fonts`)]' \ '--force[Install formulae without checking for previously installed keg-only or non-migrated versions. When installing casks, overwrite existing files (binaries and symlinks are excluded, unless originally from the same cask)]' \ @@ -1037,6 +1038,7 @@ _brew_install() { '(--cask)--debug-symbols[Generate debug symbols on build. Source will be retained in a cache directory. ]' \ '(--formula)--dictionarydir[Target location for Dictionaries (default: `~/Library/Dictionaries`)]' \ '(--cask)--display-times[Print install times for each package at the end of the run]' \ + '--dry-run[Show what would be installed, but do not actually install anything]' \ '(--cask)--fetch-HEAD[Fetch the upstream repository to detect if the HEAD installation of the formula is outdated. Otherwise, the repository'\''s HEAD will only be checked for updates when a new stable or development version has been released]' \ '(--formula)--fontdir[Target location for Fonts (default: `~/Library/Fonts`)]' \ '--force[Install formulae without checking for previously installed keg-only or non-migrated versions. When installing casks, overwrite existing files (binaries and symlinks are excluded, unless originally from the same cask)]' \ diff --git a/docs/Manpage.md b/docs/Manpage.md index 78aa6313e3..1f49c87d84 100644 --- a/docs/Manpage.md +++ b/docs/Manpage.md @@ -329,6 +329,8 @@ is already installed but outdated. Install formulae without checking for previously installed keg-only or non-migrated versions. When installing casks, overwrite existing files (binaries and symlinks are excluded, unless originally from the same cask). * `-v`, `--verbose`: Print the verification and postinstall steps. +* `-n`, `--dry-run`: + Show what would be installed, but do not actually install anything. * `--formula`: Treat all named arguments as formulae. * `--ignore-dependencies`: diff --git a/manpages/brew.1 b/manpages/brew.1 index 637a107031..0806010f50 100644 --- a/manpages/brew.1 +++ b/manpages/brew.1 @@ -432,6 +432,10 @@ Install formulae without checking for previously installed keg\-only or non\-mig Print the verification and postinstall steps\. . .TP +\fB\-n\fR, \fB\-\-dry\-run\fR +Show what would be installed, but do not actually install anything\. +. +.TP \fB\-\-formula\fR Treat all named arguments as formulae\. .