| 
									
										
										
										
											2021-01-12 16:05:06 +01:00
										 |  |  | # typed: true | 
					
						
							| 
									
										
										
										
											2019-04-19 15:38:03 +09:00
										 |  |  | # frozen_string_literal: true | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-02 17:11:37 +01:00
										 |  |  | require "json" | 
					
						
							| 
									
										
										
										
											2017-12-03 09:06:23 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-21 21:28:58 +02:00
										 |  |  | require "lazy_object" | 
					
						
							|  |  |  | require "locale" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-03 02:40:27 +01:00
										 |  |  | require "extend/hash_validator" | 
					
						
							|  |  |  | using HashValidator | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-02 17:11:37 +01:00
										 |  |  | module Cask | 
					
						
							| 
									
										
										
										
											2020-08-24 22:51:23 +02:00
										 |  |  |   # Configuration for installing casks. | 
					
						
							|  |  |  |   # | 
					
						
							|  |  |  |   # @api private | 
					
						
							| 
									
										
										
										
											2019-02-03 02:40:27 +01:00
										 |  |  |   class Config | 
					
						
							| 
									
										
										
										
											2021-01-12 16:05:06 +01:00
										 |  |  |     extend T::Sig | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-02 17:11:37 +01:00
										 |  |  |     DEFAULT_DIRS = { | 
					
						
							| 
									
										
										
										
											2019-02-05 16:08:29 +01:00
										 |  |  |       appdir:               "/Applications", | 
					
						
							| 
									
										
										
										
											2020-08-01 02:30:46 +02:00
										 |  |  |       colorpickerdir:       "~/Library/ColorPickers", | 
					
						
							| 
									
										
										
										
											2019-02-05 16:08:29 +01:00
										 |  |  |       prefpanedir:          "~/Library/PreferencePanes", | 
					
						
							|  |  |  |       qlplugindir:          "~/Library/QuickLook", | 
					
						
							| 
									
										
										
										
											2020-04-05 15:30:37 +02:00
										 |  |  |       mdimporterdir:        "~/Library/Spotlight", | 
					
						
							| 
									
										
										
										
											2019-02-05 16:08:29 +01:00
										 |  |  |       dictionarydir:        "~/Library/Dictionaries", | 
					
						
							|  |  |  |       fontdir:              "~/Library/Fonts", | 
					
						
							|  |  |  |       servicedir:           "~/Library/Services", | 
					
						
							|  |  |  |       input_methoddir:      "~/Library/Input Methods", | 
					
						
							|  |  |  |       internet_plugindir:   "~/Library/Internet Plug-Ins", | 
					
						
							|  |  |  |       audio_unit_plugindir: "~/Library/Audio/Plug-Ins/Components", | 
					
						
							|  |  |  |       vst_plugindir:        "~/Library/Audio/Plug-Ins/VST", | 
					
						
							|  |  |  |       vst3_plugindir:       "~/Library/Audio/Plug-Ins/VST3", | 
					
						
							|  |  |  |       screen_saverdir:      "~/Library/Screen Savers", | 
					
						
							| 
									
										
										
										
											2019-02-02 17:11:37 +01:00
										 |  |  |     }.freeze | 
					
						
							| 
									
										
										
										
											2017-12-03 09:06:23 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-21 21:28:58 +02:00
										 |  |  |     def self.defaults | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  |         languages: LazyObject.new { MacOS.languages }, | 
					
						
							|  |  |  |       }.merge(DEFAULT_DIRS).freeze | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-12 16:05:06 +01:00
										 |  |  |     sig { params(args: Homebrew::CLI::Args).returns(T.attached_class) } | 
					
						
							| 
									
										
										
										
											2020-09-29 23:46:30 +02:00
										 |  |  |     def self.from_args(args) | 
					
						
							|  |  |  |       new(explicit: { | 
					
						
							|  |  |  |         appdir:               args.appdir, | 
					
						
							|  |  |  |         colorpickerdir:       args.colorpickerdir, | 
					
						
							|  |  |  |         prefpanedir:          args.prefpanedir, | 
					
						
							|  |  |  |         qlplugindir:          args.qlplugindir, | 
					
						
							|  |  |  |         mdimporterdir:        args.mdimporterdir, | 
					
						
							|  |  |  |         dictionarydir:        args.dictionarydir, | 
					
						
							|  |  |  |         fontdir:              args.fontdir, | 
					
						
							|  |  |  |         servicedir:           args.servicedir, | 
					
						
							|  |  |  |         input_methoddir:      args.input_methoddir, | 
					
						
							|  |  |  |         internet_plugindir:   args.internet_plugindir, | 
					
						
							|  |  |  |         audio_unit_plugindir: args.audio_unit_plugindir, | 
					
						
							|  |  |  |         vst_plugindir:        args.vst_plugindir, | 
					
						
							|  |  |  |         vst3_plugindir:       args.vst3_plugindir, | 
					
						
							|  |  |  |         screen_saverdir:      args.screen_saverdir, | 
					
						
							|  |  |  |         languages:            args.language, | 
					
						
							|  |  |  |       }.compact) | 
					
						
							| 
									
										
										
										
											2017-12-03 09:06:23 +01:00
										 |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-12 16:05:06 +01:00
										 |  |  |     sig { params(json: String, ignore_invalid_keys: T::Boolean).returns(T.attached_class) } | 
					
						
							|  |  |  |     def self.from_json(json, ignore_invalid_keys: false) | 
					
						
							|  |  |  |       config = JSON.parse(json) | 
					
						
							| 
									
										
										
										
											2019-02-02 17:11:37 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-03 02:40:27 +01:00
										 |  |  |       new( | 
					
						
							| 
									
										
										
										
											2021-01-12 16:05:06 +01:00
										 |  |  |         default:             config.fetch("default",  {}), | 
					
						
							|  |  |  |         env:                 config.fetch("env",      {}), | 
					
						
							|  |  |  |         explicit:            config.fetch("explicit", {}), | 
					
						
							|  |  |  |         ignore_invalid_keys: ignore_invalid_keys, | 
					
						
							| 
									
										
										
										
											2019-02-03 02:40:27 +01:00
										 |  |  |       ) | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-17 22:45:55 -08:00
										 |  |  |     sig { | 
					
						
							| 
									
										
										
										
											2021-01-12 16:05:06 +01:00
										 |  |  |       params(config: T::Enumerable[[T.any(String, Symbol), T.any(String, Pathname, T::Array[String])]]) | 
					
						
							|  |  |  |         .returns(T::Hash[Symbol, T.any(String, Pathname, T::Array[String])]) | 
					
						
							| 
									
										
										
										
											2021-01-17 22:45:55 -08:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-02-05 16:08:29 +01:00
										 |  |  |     def self.canonicalize(config) | 
					
						
							| 
									
										
										
										
											2019-07-01 13:34:41 +02:00
										 |  |  |       config.map do |k, v| | 
					
						
							|  |  |  |         key = k.to_sym | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if DEFAULT_DIRS.key?(key) | 
					
						
							|  |  |  |           [key, Pathname(v).expand_path] | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |           [key, v] | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  |       end.to_h | 
					
						
							| 
									
										
										
										
											2019-02-05 16:08:29 +01:00
										 |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-12 16:05:06 +01:00
										 |  |  |     sig { returns(T::Hash[Symbol, T.any(String, Pathname, T::Array[String])]) } | 
					
						
							| 
									
										
										
										
											2019-02-03 02:40:27 +01:00
										 |  |  |     attr_accessor :explicit | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-17 22:45:55 -08:00
										 |  |  |     sig { | 
					
						
							| 
									
										
										
										
											2021-01-12 16:05:06 +01:00
										 |  |  |       params( | 
					
						
							|  |  |  |         default:             T.nilable(T::Hash[Symbol, T.any(String, Pathname, T::Array[String])]), | 
					
						
							|  |  |  |         env:                 T.nilable(T::Hash[Symbol, T.any(String, Pathname, T::Array[String])]), | 
					
						
							|  |  |  |         explicit:            T::Hash[Symbol, T.any(String, Pathname, T::Array[String])], | 
					
						
							|  |  |  |         ignore_invalid_keys: T::Boolean, | 
					
						
							|  |  |  |       ).void | 
					
						
							| 
									
										
										
										
											2021-01-17 22:45:55 -08:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-01-12 16:05:06 +01:00
										 |  |  |     def initialize(default: nil, env: nil, explicit: {}, ignore_invalid_keys: false) | 
					
						
							| 
									
										
										
										
											2020-07-21 21:28:58 +02:00
										 |  |  |       @default = self.class.canonicalize(self.class.defaults.merge(default)) if default | 
					
						
							| 
									
										
										
										
											2019-02-05 16:08:29 +01:00
										 |  |  |       @env = self.class.canonicalize(env) if env | 
					
						
							|  |  |  |       @explicit = self.class.canonicalize(explicit) | 
					
						
							| 
									
										
										
										
											2019-02-03 02:40:27 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-12 16:05:06 +01:00
										 |  |  |       if ignore_invalid_keys | 
					
						
							|  |  |  |         @env&.delete_if { |key, _| self.class.defaults.keys.exclude?(key) } | 
					
						
							|  |  |  |         @explicit.delete_if { |key, _| self.class.defaults.keys.exclude?(key) } | 
					
						
							|  |  |  |         return | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-21 21:28:58 +02:00
										 |  |  |       @env&.assert_valid_keys!(*self.class.defaults.keys) | 
					
						
							|  |  |  |       @explicit.assert_valid_keys!(*self.class.defaults.keys) | 
					
						
							| 
									
										
										
										
											2019-02-02 17:11:37 +01:00
										 |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-12 16:05:06 +01:00
										 |  |  |     sig { returns(T::Hash[Symbol, T.any(String, Pathname, T::Array[String])]) } | 
					
						
							| 
									
										
										
										
											2019-02-03 02:40:27 +01:00
										 |  |  |     def default | 
					
						
							| 
									
										
										
										
											2020-07-21 21:28:58 +02:00
										 |  |  |       @default ||= self.class.canonicalize(self.class.defaults) | 
					
						
							| 
									
										
										
										
											2019-02-03 02:40:27 +01:00
										 |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-12 16:05:06 +01:00
										 |  |  |     sig { returns(T::Hash[Symbol, T.any(String, Pathname, T::Array[String])]) } | 
					
						
							| 
									
										
										
										
											2019-02-03 02:40:27 +01:00
										 |  |  |     def env | 
					
						
							| 
									
										
										
										
											2019-02-05 16:08:29 +01:00
										 |  |  |       @env ||= self.class.canonicalize( | 
					
						
							| 
									
										
										
										
											2020-09-29 23:46:30 +02:00
										 |  |  |         Homebrew::EnvConfig.cask_opts | 
					
						
							|  |  |  |           .select { |arg| arg.include?("=") } | 
					
						
							| 
									
										
										
										
											2021-01-12 16:05:06 +01:00
										 |  |  |           .map { |arg| T.cast(arg.split("=", 2), [String, String]) } | 
					
						
							| 
									
										
										
										
											2020-09-29 23:46:30 +02:00
										 |  |  |           .map do |(flag, value)| | 
					
						
							|  |  |  |             key = flag.sub(/^--/, "") | 
					
						
							| 
									
										
										
										
											2021-01-29 17:11:14 -05:00
										 |  |  |             # converts --language flag to :languages config key | 
					
						
							| 
									
										
										
										
											2020-09-29 23:46:30 +02:00
										 |  |  |             if key == "language" | 
					
						
							|  |  |  |               key = "languages" | 
					
						
							|  |  |  |               value = value.split(",") | 
					
						
							|  |  |  |             end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             [key, value] | 
					
						
							|  |  |  |           end, | 
					
						
							| 
									
										
										
										
											2019-02-05 16:08:29 +01:00
										 |  |  |       ) | 
					
						
							| 
									
										
										
										
											2019-02-02 17:11:37 +01:00
										 |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-12 16:05:06 +01:00
										 |  |  |     sig { returns(Pathname) } | 
					
						
							| 
									
										
										
										
											2019-02-02 17:11:37 +01:00
										 |  |  |     def binarydir | 
					
						
							|  |  |  |       @binarydir ||= HOMEBREW_PREFIX/"bin" | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-12 16:05:06 +01:00
										 |  |  |     sig { returns(Pathname) } | 
					
						
							| 
									
										
										
										
											2019-10-22 15:19:40 +03:00
										 |  |  |     def manpagedir | 
					
						
							|  |  |  |       @manpagedir ||= HOMEBREW_PREFIX/"share/man" | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-12 16:05:06 +01:00
										 |  |  |     sig { returns(T::Array[String]) } | 
					
						
							| 
									
										
										
										
											2020-07-21 21:28:58 +02:00
										 |  |  |     def languages | 
					
						
							|  |  |  |       [ | 
					
						
							| 
									
										
										
										
											2021-01-12 16:05:06 +01:00
										 |  |  |         *T.cast(explicit.fetch(:languages, []), T::Array[String]), | 
					
						
							|  |  |  |         *T.cast(env.fetch(:languages, []), T::Array[String]), | 
					
						
							|  |  |  |         *T.cast(default.fetch(:languages, []), T::Array[String]), | 
					
						
							| 
									
										
										
										
											2020-07-21 21:28:58 +02:00
										 |  |  |       ].uniq.select do |lang| | 
					
						
							|  |  |  |         # Ensure all languages are valid. | 
					
						
							|  |  |  |         Locale.parse(lang) | 
					
						
							|  |  |  |         true | 
					
						
							|  |  |  |       rescue Locale::ParserError | 
					
						
							|  |  |  |         false | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def languages=(languages) | 
					
						
							|  |  |  |       explicit[:languages] = languages | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-19 11:18:40 +00:00
										 |  |  |     DEFAULT_DIRS.each_key do |dir| | 
					
						
							| 
									
										
										
										
											2019-02-02 17:11:37 +01:00
										 |  |  |       define_method(dir) do | 
					
						
							| 
									
										
										
										
											2019-02-03 02:40:27 +01:00
										 |  |  |         explicit.fetch(dir, env.fetch(dir, default.fetch(dir))) | 
					
						
							| 
									
										
										
										
											2019-02-02 17:11:37 +01:00
										 |  |  |       end | 
					
						
							| 
									
										
										
										
											2017-12-03 09:06:23 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |       define_method(:"#{dir}=") do |path| | 
					
						
							| 
									
										
										
										
											2019-02-03 02:40:27 +01:00
										 |  |  |         explicit[dir] = Pathname(path).expand_path | 
					
						
							| 
									
										
										
										
											2017-12-03 09:06:23 +01:00
										 |  |  |       end | 
					
						
							|  |  |  |     end | 
					
						
							| 
									
										
										
										
											2019-02-02 17:11:37 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-12 16:05:06 +01:00
										 |  |  |     sig { params(other: Config).returns(T.self_type) } | 
					
						
							| 
									
										
										
										
											2019-02-03 02:40:27 +01:00
										 |  |  |     def merge(other) | 
					
						
							| 
									
										
										
										
											2019-02-03 13:03:16 +01:00
										 |  |  |       self.class.new(explicit: other.explicit.merge(explicit)) | 
					
						
							| 
									
										
										
										
											2019-02-03 02:40:27 +01:00
										 |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-29 17:11:14 -05:00
										 |  |  |     sig { returns(String) } | 
					
						
							|  |  |  |     def explicit_s | 
					
						
							|  |  |  |       explicit.map do |key, value| | 
					
						
							|  |  |  |         # inverse of #env - converts :languages config key back to --language flag | 
					
						
							|  |  |  |         if key == :languages | 
					
						
							|  |  |  |           key = "language" | 
					
						
							| 
									
										
										
										
											2021-02-03 13:15:48 +05:30
										 |  |  |           value = T.cast(explicit.fetch(:languages, []), T::Array[String]).join(",") | 
					
						
							| 
									
										
										
										
											2021-01-29 17:11:14 -05:00
										 |  |  |         end | 
					
						
							|  |  |  |         "#{key}: \"#{value.to_s.sub(/^#{ENV['HOME']}/, "~")}\"" | 
					
						
							|  |  |  |       end.join(", ") | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-12 16:05:06 +01:00
										 |  |  |     sig { params(options: T.untyped).returns(String) } | 
					
						
							|  |  |  |     def to_json(**options) | 
					
						
							| 
									
										
										
										
											2019-02-03 02:40:27 +01:00
										 |  |  |       { | 
					
						
							|  |  |  |         default:  default, | 
					
						
							|  |  |  |         env:      env, | 
					
						
							|  |  |  |         explicit: explicit, | 
					
						
							| 
									
										
										
										
											2021-01-12 16:05:06 +01:00
										 |  |  |       }.to_json(**options) | 
					
						
							| 
									
										
										
										
											2019-02-03 02:40:27 +01:00
										 |  |  |     end | 
					
						
							| 
									
										
										
										
											2017-12-03 09:06:23 +01:00
										 |  |  |   end | 
					
						
							|  |  |  | end |