Fix internal formula json v3 frozen hash parsing bug
This caused formulae with uses from macos bounds to not load correctly
because they tried to modify a frozen hash. It wasn't obvious from
the tests because I didn't replicate the real world JSON parsing
conditions closely enough. I also had to modify `Cachable#clear_cache`
so that it can clear frozen hashes.
Error:
```
Error: can't modify frozen Hash: {"since"=>"catalina"}
Warning: Removed Sorbet lines from backtrace!
Rerun with `--verbose` to see the original backtrace
/usr/local/Homebrew/Library/Homebrew/extend/hash/keys.rb:123:in `delete'
/usr/local/Homebrew/Library/Homebrew/extend/hash/keys.rb:123:in `block in _deep_transform_keys_in_object!'
/usr/local/Homebrew/Library/Homebrew/extend/hash/keys.rb:122:in `each'
/usr/local/Homebrew/Library/Homebrew/extend/hash/keys.rb:122:in `_deep_transform_keys_in_object!'
/usr/local/Homebrew/Library/Homebrew/extend/hash/keys.rb:48:in `deep_transform_keys!'
/usr/local/Homebrew/Library/Homebrew/formulary.rb:230:in `block (2 levels) in load_formula_from_api'
/usr/local/Homebrew/Library/Homebrew/formulary.rb:218:in `each'
/usr/local/Homebrew/Library/Homebrew/formulary.rb:218:in `block in load_formula_from_api'
/usr/local/Homebrew/Library/Homebrew/formulary.rb:304:in `instance_exec'
/usr/local/Homebrew/Library/Homebrew/formulary.rb:304:in `block (2 levels) in load_formula_from_api'
/usr/local/Homebrew/Library/Homebrew/formula.rb:3664:in `instance_eval'
/usr/local/Homebrew/Library/Homebrew/formula.rb:3664:in `stable'
/usr/local/Homebrew/Library/Homebrew/formulary.rb:293:in `block in load_formula_from_api'
/usr/local/Homebrew/Library/Homebrew/formulary.rb:283:in `initialize'
/usr/local/Homebrew/Library/Homebrew/formulary.rb:283:in `new'
/usr/local/Homebrew/Library/Homebrew/formulary.rb:283:in `load_formula_from_api'
/usr/local/Homebrew/Library/Homebrew/formulary.rb:962:in `load_from_api'
/usr/local/Homebrew/Library/Homebrew/formulary.rb:955:in `klass'
/usr/local/Homebrew/Library/Homebrew/formulary.rb:569:in `get_formula'
/usr/local/Homebrew/Library/Homebrew/formulary.rb:1009:in `factory'
/usr/local/Homebrew/Library/Homebrew/dependency.rb:41:in `to_formula'
/usr/local/Homebrew/Library/Homebrew/utils/autoremove.rb:46:in `block (2 levels) in formulae_with_no_formula_dependents'
/usr/local/Homebrew/Library/Homebrew/utils/autoremove.rb:45:in `each'
/usr/local/Homebrew/Library/Homebrew/utils/autoremove.rb:45:in `block in formulae_with_no_formula_dependents'
/usr/local/Homebrew/Library/Homebrew/utils/autoremove.rb:39:in `each'
/usr/local/Homebrew/Library/Homebrew/utils/autoremove.rb:39:in `formulae_with_no_formula_dependents'
/usr/local/Homebrew/Library/Homebrew/utils/autoremove.rb:59:in `unused_formulae_with_no_formula_dependents'
/usr/local/Homebrew/Library/Homebrew/utils/autoremove.rb:16:in `removable_formulae'
/usr/local/Homebrew/Library/Homebrew/cleanup.rb:693:in `autoremove'
/usr/local/Homebrew/Library/Homebrew/cleanup.rb:291:in `clean!'
/usr/local/Homebrew/Library/Homebrew/cmd/cleanup.rb:52:in `run'
/usr/local/Homebrew/Library/Homebrew/brew.rb:92:in `<main>'
```
This commit is contained in:
parent
e60e035731
commit
37cbfc40bf
@ -7,9 +7,10 @@ module Cachable
|
||||
@cache ||= T.let({}, T.nilable(T::Hash[T.untyped, T.untyped]))
|
||||
end
|
||||
|
||||
# NOTE: We overwrite here instead of using `Hash#clear` to handle frozen hashes.
|
||||
sig { void }
|
||||
def clear_cache
|
||||
cache.clear
|
||||
overwrite_cache!({})
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
@ -226,7 +226,7 @@ module Formulary
|
||||
end
|
||||
|
||||
if info&.key?("uses_from_macos")
|
||||
bounds = info["uses_from_macos"] || {}
|
||||
bounds = info["uses_from_macos"].dup || {}
|
||||
bounds.deep_transform_keys!(&:to_sym)
|
||||
bounds.deep_transform_values!(&:to_sym)
|
||||
|
||||
|
||||
@ -33,7 +33,7 @@ RSpec.describe "Internal Tap JSON -- Formula", type: :system do
|
||||
|
||||
allow(Homebrew::API).to receive(:fetch_json_api_file)
|
||||
.with("internal/v3/homebrew-core.jws.json")
|
||||
.and_return([JSON.parse(internal_tap_json), false])
|
||||
.and_return([JSON.parse(internal_tap_json, freeze: true), false])
|
||||
|
||||
# `Tap.tap_migration_oldnames` looks for renames in every
|
||||
# tap so `CoreCaskTap.tap_migrations` gets called and tries to
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user