Module: Cask::CaskLoader Private
- Extended by:
- Context, Utils::Output::Mixin
- Defined in:
- cask/cask_loader.rb
Overview
This module is part of a private API. This module may only be used in the Homebrew/brew repository. Third parties should avoid using this module if possible, as it may be removed or changed without warning.
Loads a cask from various sources.
Defined Under Namespace
Modules: ILoader Classes: AbstractContentLoader, FromAPILoader, FromContentLoader, FromInstalledPathLoader, FromInstanceLoader, FromNameLoader, FromPathLoader, FromTapLoader, FromURILoader, NullLoader
Class Method Summary collapse
- .default_path(token) ⇒ Pathname private
- .find_cask_in_tap(token, tap) ⇒ Pathname private
-
.for(ref, need_path: false, warn: true) ⇒ ILoader
private
which would interfere with RSpec mocking of this class method.
-
.installed_json_caskfile?(path) ⇒ Boolean
private
Legacy
.internal.jsonfiles contain full API data rather than the compact installed JSON format. -
.load(ref, config: nil, warn: true) ⇒ Cask
private
which would interfere with RSpec mocking of this class method.
- .load_from_installed_caskfile(path, config: nil, warn: true, api_fallback: true) ⇒ Cask private
- .load_installed_json(path) ⇒ Hash{String => T.untyped}? private
- .load_installed_tab(cask_or_token) ⇒ Tab private
- .load_prefer_installed(ref, config: nil, warn: true) ⇒ Cask private
-
.path(ref) ⇒ Pathname
private
which would interfere with RSpec mocking of this class method.
- .recover_from_installed_caskfile(path, tab: nil, fallback_cask: nil, config: nil) ⇒ Cask? private
- .resolve_installed_artifacts(token, artifacts, tap: nil, api_fallback: true) ⇒ Array<Hash{String, Symbol => T.anything}> private
- .tap_cask_token_type(tapped_token, warn:) ⇒ Array<(String, Tap, [Symbol, nil])>? private
- .token_from_path(path) ⇒ String private
Methods included from Context
current, current=, debug?, deferred_environment_expansion?, quiet?, verbose?, with_context
Methods included from Utils::Output::Mixin
issue_reporting_message, odebug, odeprecated, odie, odisabled, ofail, oh1, oh1_title, ohai, ohai_title, onoe, opoo, opoo_outside_github_actions, opoo_without_github_actions_annotation, pretty_deprecated, pretty_disabled, pretty_duration, pretty_install_status, pretty_installed, pretty_uninstalled, pretty_unmarked, pretty_upgradable, pretty_warning
Class Method Details
.default_path(token) ⇒ Pathname
This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.
932 933 934 |
# File 'cask/cask_loader.rb', line 932 def self.default_path(token) find_cask_in_tap(token.to_s.downcase, CoreCaskTap.instance) end |
.find_cask_in_tap(token, tap) ⇒ Pathname
This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.
937 938 939 940 941 |
# File 'cask/cask_loader.rb', line 937 def self.find_cask_in_tap(token, tap) filename = "#{token}.rb" tap.cask_files_by_name.fetch(token, tap.cask_dir/filename) end |
.for(ref, need_path: false, warn: true) ⇒ ILoader
This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.
Using WithoutRuntime to avoid Sorbet wrapping this method,
which would interfere with RSpec mocking of this class method.
755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 |
# File 'cask/cask_loader.rb', line 755 def self.for(ref, need_path: false, warn: true) [ FromInstanceLoader, FromContentLoader, FromURILoader, FromAPILoader, FromTapLoader, FromNameLoader, FromPathLoader, FromInstalledPathLoader, NullLoader, ].each do |loader_class| if (loader = loader_class.try_new(ref, warn:)) $stderr.puts "#{$PROGRAM_NAME} (#{loader.class}): loading #{ref}" if verbose? && debug? return loader end end raise CaskError, "No cask loader found for #{ref.inspect}" end |
.installed_json_caskfile?(path) ⇒ Boolean
This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.
Legacy .internal.json files contain full API data rather than the compact installed JSON format.
812 813 814 |
# File 'cask/cask_loader.rb', line 812 def self.installed_json_caskfile?(path) path.extname == ".json" && !path.basename.to_s.end_with?(".internal.json") end |
.load(ref, config: nil, warn: true) ⇒ Cask
This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.
Using WithoutRuntime to avoid Sorbet wrapping this method,
which would interfere with RSpec mocking of this class method.
698 699 700 701 |
# File 'cask/cask_loader.rb', line 698 def self.load(ref, config: nil, warn: true) normalized_ref = ref.is_a?(Symbol) ? ref.to_s : ref self.for(normalized_ref, warn:).load(config:) end |
.load_from_installed_caskfile(path, config: nil, warn: true, api_fallback: true) ⇒ Cask
This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.
798 799 800 801 802 803 |
# File 'cask/cask_loader.rb', line 798 def self.load_from_installed_caskfile(path, config: nil, warn: true, api_fallback: true) loader = FromInstalledPathLoader.try_new(path, warn:, api_fallback:) loader ||= NullLoader.new(path) loader.load(config:) end |
.load_installed_json(path) ⇒ Hash{String => T.untyped}?
This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.
817 818 819 820 821 822 823 824 |
# File 'cask/cask_loader.rb', line 817 def self.load_installed_json(path) return unless installed_json_caskfile?(path) json = JSON.parse(path.read) json if json.is_a?(Hash) rescue JSON::ParserError nil end |
.load_installed_tab(cask_or_token) ⇒ Tab
This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.
827 828 829 830 831 832 833 834 835 836 |
# File 'cask/cask_loader.rb', line 827 def self.load_installed_tab(cask_or_token) cask = if cask_or_token.is_a?(Cask) cask_or_token else Cask.new(cask_or_token) end cask.tab rescue JSON::ParserError, NoMethodError, TypeError Tab.empty end |
.load_prefer_installed(ref, config: nil, warn: true) ⇒ Cask
This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.
777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 |
# File 'cask/cask_loader.rb', line 777 def self.load_prefer_installed(ref, config: nil, warn: true) tap, token = Tap.with_cask_token(ref) token ||= ref tap ||= Cask.new(ref).tab.tap if tap.nil? self.load(token, config:, warn:) else begin self.load("#{tap}/#{token}", config:, warn:) rescue CaskUnavailableError # cask may be migrated to different tap. Try to search in all taps. self.load(token, config:, warn:) end end end |
.path(ref) ⇒ Pathname
This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.
Using WithoutRuntime to avoid Sorbet wrapping this method,
which would interfere with RSpec mocking of this class method.
688 689 690 |
# File 'cask/cask_loader.rb', line 688 def self.path(ref) T.cast(self.for(ref, need_path: true), T.any(FromAPILoader, FromPathLoader)).path end |
.recover_from_installed_caskfile(path, tab: nil, fallback_cask: nil, config: nil) ⇒ Cask?
This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.
888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 |
# File 'cask/cask_loader.rb', line 888 def self.recover_from_installed_caskfile(path, tab: nil, fallback_cask: nil, config: nil) # Only installed metadata has the versioned path layout used to rebuild the cask below. return if path.dirname.basename.to_s != "Casks" # Read any usable receipt, while retaining the current cask as a fallback for missing receipt data. token = token_from_path(path) tab ||= load_installed_tab(fallback_cask || token) # Ruby uninstall flight blocks cannot be represented by installed JSON and must not be approximated. return if tab.uninstall_flight_blocks return if fallback_cask&.uninstall_flight_blocks? # Prefer exact receipt artifacts, then the current cask and finally the current source definition. artifacts = tab.uninstall_artifacts.presence artifacts ||= fallback_cask.artifacts_list(uninstall_only: true) if fallback_cask artifacts ||= resolve_installed_artifacts(token, nil, tap: tab.tap) # Rebuild the installed version from its metadata directory and retain current source path information. api_source = { "version" => path.dirname.dirname.dirname.basename.to_s, "artifacts" => artifacts, } api_source["url_specs"] ||= fallback_cask.to_installed_json_hash["url_specs"] if fallback_cask # Prefer the installed JSON's source path because it belongs to the installed version. if (source_json = load_installed_json(path)) source_url_specs = source_json["url_specs"] api_source["url_specs"] = source_url_specs if source_url_specs.is_a?(Hash) end # Load through the installed-JSON path so reconstructed artifacts have normal installed paths and behaviour. recovered_cask = FromAPILoader.new( token, from_json: api_source, path:, from_installed_caskfile: true, ).load(config:) recovered_cask unless recovered_cask.uninstall_flight_blocks? rescue CaskInvalidError, CaskUnavailableError, MethodDeprecatedError, JSON::ParserError # Recovery is best effort; callers treat nil as an unavailable installed cask and use their existing fallback. nil end |
.resolve_installed_artifacts(token, artifacts, tap: nil, api_fallback: true) ⇒ Array<Hash{String, Symbol => T.anything}>
This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.
846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 |
# File 'cask/cask_loader.rb', line 846 def self.resolve_installed_artifacts(token, artifacts, tap: nil, api_fallback: true) artifacts = artifacts.presence return artifacts if artifacts return [] unless api_fallback artifacts ||= begin tap_loader = (FromNameLoader.try_new(token, warn: false) if tap.nil? && FromAPILoader.try_new(token).nil?) if tap && !tap.core_cask_tap? load("#{tap}/#{token}", warn: false).artifacts_list(uninstall_only: true) elsif tap_loader tap_loader.load(config: nil).artifacts_list(uninstall_only: true) end rescue CaskError, MethodDeprecatedError, JSON::ParserError, ErrorDuringExecution, SystemExit nil end # API fetch failures must not abort best-effort installed metadata recovery. Skip the # per-cask endpoint only when the token is definitively absent from the current API; # a membership-check failure is treated as unknown so recovery still tries the endpoint. artifacts ||= begin definitely_absent = begin !Homebrew::API.cask_token?(token) rescue ErrorDuringExecution, SystemExit false end Homebrew::API::Cask.cask_json(token)["artifacts"] unless definitely_absent rescue ErrorDuringExecution, SystemExit nil end artifacts ||= [] artifacts end |
.tap_cask_token_type(tapped_token, warn:) ⇒ Array<(String, Tap, [Symbol, nil])>?
This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.
704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 |
# File 'cask/cask_loader.rb', line 704 def self.tap_cask_token_type(tapped_token, warn:) return unless (tap_with_token = Tap.with_cask_token(tapped_token)) tap, token = tap_with_token type = nil if (new_token = tap.cask_renames[token].presence) old_token = tap.core_cask_tap? ? token : tapped_token token = new_token new_token = tap.core_cask_tap? ? token : "#{tap}/#{token}" type = :rename elsif (new_tap_name = tap.tap_migrations[token].presence) new_tap, new_token = Tap.with_cask_token(new_tap_name) unless new_tap if new_tap_name.include?("/") new_tap = Tap.fetch(new_tap_name) new_token = token else new_tap = tap new_token = new_tap_name end end new_tapped_token = "#{new_tap}/#{new_token}" if tapped_token != new_tapped_token old_token = tap.core_cask_tap? ? token : tapped_token return unless (token_tap_type = tap_cask_token_type(new_tapped_token, warn: false)) token, tap, = token_tap_type new_token = new_tap.core_cask_tap? ? token : "#{tap}/#{token}" type = :migration end end if warn && old_token && new_token destination_exists = find_cask_in_tap(token, tap).exist? || (tap.core_cask_tap? && !Homebrew::EnvConfig.no_install_from_api? && Homebrew::API.cask_token?(token)) opoo "Cask #{old_token} was renamed to #{new_token}." if destination_exists end [token, tap, type] end |
.token_from_path(path) ⇒ String
This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.
806 807 808 |
# File 'cask/cask_loader.rb', line 806 def self.token_from_path(path) path.basename(path.extname).basename(".internal").to_s end |