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-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
|
2019-02-02 17:11:37 +01:00
|
|
|
DEFAULT_DIRS = {
|
2019-02-05 16:08:29 +01:00
|
|
|
appdir: "/Applications",
|
2023-03-26 08:10:40 +02:00
|
|
|
keyboard_layoutdir: "/Library/Keyboard Layouts",
|
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,
|
2023-03-26 08:10:40 +02:00
|
|
|
keyboard_layoutdir: args.keyboard_layoutdir,
|
2020-09-29 23:46:30 +02:00
|
|
|
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)
|
2021-12-23 14:49:05 -05:00
|
|
|
config.to_h do |k, v|
|
2019-07-01 13:34:41 +02:00
|
|
|
key = k.to_sym
|
|
|
|
|
|
|
|
if DEFAULT_DIRS.key?(key)
|
|
|
|
[key, Pathname(v).expand_path]
|
|
|
|
else
|
|
|
|
[key, v]
|
|
|
|
end
|
2021-12-23 14:49:05 -05:00
|
|
|
end
|
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
|
|
|
|
|
2023-03-19 17:31:51 -07: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
|
2023-03-19 19:37:28 -07:00
|
|
|
T.bind(self, Config)
|
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|
|
2023-03-19 19:37:28 -07:00
|
|
|
T.bind(self, Config)
|
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
|
2022-05-30 04:48:54 +01:00
|
|
|
"#{key}: \"#{value.to_s.sub(/^#{Dir.home}/, "~")}\""
|
2021-01-29 17:11:14 -05:00
|
|
|
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
|