| 
									
										
										
										
											2020-10-10 14:16:11 +02:00
										 |  |  | # typed: true | 
					
						
							| 
									
										
										
										
											2019-04-19 15:38:03 +09:00
										 |  |  | # frozen_string_literal: true | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 19:42:27 +09:00
										 |  |  | require "ostruct" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | module Homebrew | 
					
						
							|  |  |  |   module CLI | 
					
						
							|  |  |  |     class Args < OpenStruct | 
					
						
							| 
									
										
										
										
											2020-05-10 15:12:25 +01:00
										 |  |  |       attr_reader :options_only, :flags_only | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 19:42:27 +09:00
										 |  |  |       # undefine tap to allow --tap argument | 
					
						
							|  |  |  |       undef tap | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-20 12:03:48 +02:00
										 |  |  |       sig { void } | 
					
						
							| 
									
										
										
										
											2020-07-31 17:37:36 +02:00
										 |  |  |       def initialize | 
					
						
							| 
									
										
										
										
											2020-11-29 21:23:44 +01:00
										 |  |  |         require "cli/named_args" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-05 12:50:41 +01:00
										 |  |  |         super() | 
					
						
							| 
									
										
										
										
											2020-04-18 21:14:35 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-22 20:13:11 +05:30
										 |  |  |         @processed_options = [] | 
					
						
							| 
									
										
										
										
											2020-07-31 17:37:36 +02:00
										 |  |  |         @options_only = [] | 
					
						
							|  |  |  |         @flags_only = [] | 
					
						
							| 
									
										
										
										
											2021-03-18 14:46:48 +00:00
										 |  |  |         @cask_options = false | 
					
						
							| 
									
										
										
										
											2019-09-22 20:13:11 +05:30
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-07 10:33:02 +01:00
										 |  |  |         # Can set these because they will be overwritten by freeze_named_args! | 
					
						
							|  |  |  |         # (whereas other values below will only be overwritten if passed). | 
					
						
							| 
									
										
										
										
											2020-11-16 01:52:57 +01:00
										 |  |  |         self[:named] = NamedArgs.new(parent: self) | 
					
						
							| 
									
										
										
										
											2020-07-31 15:07:08 +02:00
										 |  |  |         self[:remaining] = [] | 
					
						
							| 
									
										
										
										
											2019-09-22 20:13:11 +05:30
										 |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-31 15:07:08 +02:00
										 |  |  |       def freeze_remaining_args!(remaining_args) | 
					
						
							| 
									
										
										
										
											2020-07-31 17:37:36 +02:00
										 |  |  |         self[:remaining] = remaining_args.freeze | 
					
						
							| 
									
										
										
										
											2020-07-31 15:07:08 +02:00
										 |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-19 03:57:52 +01:00
										 |  |  |       def freeze_named_args!(named_args, cask_options:, without_api:) | 
					
						
							| 
									
										
										
										
											2023-04-14 15:33:40 +02:00
										 |  |  |         options = {} | 
					
						
							|  |  |  |         options[:force_bottle] = true if self[:force_bottle?] | 
					
						
							|  |  |  |         options[:override_spec] = :head if self[:HEAD?] | 
					
						
							|  |  |  |         options[:flags] = flags_only unless flags_only.empty? | 
					
						
							| 
									
										
										
										
											2020-11-16 01:52:57 +01:00
										 |  |  |         self[:named] = NamedArgs.new( | 
					
						
							| 
									
										
										
										
											2020-08-13 08:55:55 -04:00
										 |  |  |           *named_args.freeze, | 
					
						
							| 
									
										
										
										
											2023-04-14 15:33:40 +02:00
										 |  |  |           parent:       self, | 
					
						
							|  |  |  |           cask_options: cask_options, | 
					
						
							| 
									
										
										
										
											2023-06-19 03:57:52 +01:00
										 |  |  |           without_api:  without_api, | 
					
						
							| 
									
										
										
										
											2023-04-14 15:33:40 +02:00
										 |  |  |           **options, | 
					
						
							| 
									
										
										
										
											2020-08-13 08:55:55 -04:00
										 |  |  |         ) | 
					
						
							| 
									
										
										
										
											2020-05-05 12:50:41 +01:00
										 |  |  |       end | 
					
						
							| 
									
										
										
										
											2019-09-22 20:13:11 +05:30
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-05 12:50:41 +01:00
										 |  |  |       def freeze_processed_options!(processed_options) | 
					
						
							| 
									
										
										
										
											2020-05-07 10:33:02 +01:00
										 |  |  |         # Reset cache values reliant on processed_options | 
					
						
							|  |  |  |         @cli_args = nil | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-05 12:50:41 +01:00
										 |  |  |         @processed_options += processed_options | 
					
						
							|  |  |  |         @processed_options.freeze | 
					
						
							| 
									
										
										
										
											2019-09-22 20:13:11 +05:30
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-31 17:37:36 +02:00
										 |  |  |         @options_only = cli_args.select { |a| a.start_with?("-") }.freeze | 
					
						
							|  |  |  |         @flags_only = cli_args.select { |a| a.start_with?("--") }.freeze | 
					
						
							| 
									
										
										
										
											2019-04-17 19:42:27 +09:00
										 |  |  |       end | 
					
						
							| 
									
										
										
										
											2019-09-25 14:21:06 +05:30
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-16 01:52:57 +01:00
										 |  |  |       sig { returns(NamedArgs) } | 
					
						
							| 
									
										
										
										
											2019-09-08 19:56:24 +05:30
										 |  |  |       def named | 
					
						
							| 
									
										
										
										
											2020-11-30 04:18:23 +01:00
										 |  |  |         require "formula" | 
					
						
							| 
									
										
										
										
											2020-11-16 01:52:57 +01:00
										 |  |  |         self[:named] | 
					
						
							| 
									
										
										
										
											2019-09-08 19:56:24 +05:30
										 |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-04 17:23:20 +00:00
										 |  |  |       def no_named? | 
					
						
							|  |  |  |         named.blank? | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-28 14:08:40 +02:00
										 |  |  |       def build_from_source_formulae | 
					
						
							| 
									
										
										
										
											2021-03-18 14:46:48 +00:00
										 |  |  |         if build_from_source? || self[:HEAD?] || self[:build_bottle?] | 
					
						
							| 
									
										
										
										
											2021-07-27 05:12:15 +01:00
										 |  |  |           named.to_formulae.map(&:full_name) | 
					
						
							| 
									
										
										
										
											2020-07-28 14:08:40 +02:00
										 |  |  |         else | 
					
						
							|  |  |  |           [] | 
					
						
							|  |  |  |         end | 
					
						
							| 
									
										
										
										
											2020-04-11 18:50:24 +05:30
										 |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-28 14:08:40 +02:00
										 |  |  |       def include_test_formulae | 
					
						
							|  |  |  |         if include_test? | 
					
						
							| 
									
										
										
										
											2020-09-03 10:34:22 +01:00
										 |  |  |           named.to_formulae.map(&:full_name) | 
					
						
							| 
									
										
										
										
											2020-07-28 14:08:40 +02:00
										 |  |  |         else | 
					
						
							|  |  |  |           [] | 
					
						
							|  |  |  |         end | 
					
						
							| 
									
										
										
										
											2020-05-19 19:12:47 +01:00
										 |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-23 19:39:11 +01:00
										 |  |  |       def value(name) | 
					
						
							|  |  |  |         arg_prefix = "--#{name}=" | 
					
						
							|  |  |  |         flag_with_value = flags_only.find { |arg| arg.start_with?(arg_prefix) } | 
					
						
							|  |  |  |         return unless flag_with_value | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         flag_with_value.delete_prefix(arg_prefix) | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-20 12:03:48 +02:00
										 |  |  |       sig { returns(Context::ContextStruct) } | 
					
						
							| 
									
										
										
										
											2020-08-02 14:32:31 +02:00
										 |  |  |       def context | 
					
						
							|  |  |  |         Context::ContextStruct.new(debug: debug?, quiet: quiet?, verbose: verbose?) | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-16 20:46:47 +09:00
										 |  |  |       def only_formula_or_cask | 
					
						
							| 
									
										
										
										
											2020-12-15 23:43:46 +09:00
										 |  |  |         return :formula if formula? && !cask? | 
					
						
							|  |  |  |         return :cask if cask? && !formula? | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-14 15:33:40 +02:00
										 |  |  |       sig { returns(T::Array[[Symbol, Symbol]]) } | 
					
						
							|  |  |  |       def os_arch_combinations | 
					
						
							|  |  |  |         skip_invalid_combinations = false | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         oses = case (os_sym = os&.to_sym) | 
					
						
							|  |  |  |         when nil | 
					
						
							|  |  |  |           [SimulateSystem.current_os] | 
					
						
							|  |  |  |         when :all | 
					
						
							|  |  |  |           skip_invalid_combinations = true | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-19 21:33:13 -07:00
										 |  |  |           OnSystem::ALL_OS_OPTIONS | 
					
						
							| 
									
										
										
										
											2023-04-14 15:33:40 +02:00
										 |  |  |         else | 
					
						
							|  |  |  |           [os_sym] | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         arches = case (arch_sym = arch&.to_sym) | 
					
						
							|  |  |  |         when nil | 
					
						
							|  |  |  |           [SimulateSystem.current_arch] | 
					
						
							|  |  |  |         when :all | 
					
						
							|  |  |  |           skip_invalid_combinations = true | 
					
						
							|  |  |  |           OnSystem::ARCH_OPTIONS | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |           [arch_sym] | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         oses.product(arches).select do |os, arch| | 
					
						
							|  |  |  |           if skip_invalid_combinations | 
					
						
							|  |  |  |             bottle_tag = Utils::Bottles::Tag.new(system: os, arch: arch) | 
					
						
							|  |  |  |             bottle_tag.valid_combination? | 
					
						
							|  |  |  |           else | 
					
						
							|  |  |  |             true | 
					
						
							|  |  |  |           end | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-05 12:50:41 +01:00
										 |  |  |       private | 
					
						
							| 
									
										
										
										
											2020-04-25 21:57:21 +05:30
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-05 12:50:41 +01:00
										 |  |  |       def option_to_name(option) | 
					
						
							|  |  |  |         option.sub(/\A--?/, "") | 
					
						
							|  |  |  |               .tr("-", "_") | 
					
						
							| 
									
										
										
										
											2020-04-25 21:57:21 +05:30
										 |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-05 12:50:41 +01:00
										 |  |  |       def cli_args | 
					
						
							|  |  |  |         return @cli_args if @cli_args | 
					
						
							| 
									
										
										
										
											2020-04-05 17:39:30 +05:30
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-05 12:50:41 +01:00
										 |  |  |         @cli_args = [] | 
					
						
							|  |  |  |         @processed_options.each do |short, long| | 
					
						
							|  |  |  |           option = long || short | 
					
						
							|  |  |  |           switch = "#{option_to_name(option)}?".to_sym | 
					
						
							|  |  |  |           flag = option_to_name(option).to_sym | 
					
						
							|  |  |  |           if @table[switch] == true || @table[flag] == true | 
					
						
							|  |  |  |             @cli_args << option | 
					
						
							|  |  |  |           elsif @table[flag].instance_of? String | 
					
						
							| 
									
										
										
										
											2020-08-19 17:12:32 +01:00
										 |  |  |             @cli_args << "#{option}=#{@table[flag]}" | 
					
						
							| 
									
										
										
										
											2020-05-05 12:50:41 +01:00
										 |  |  |           elsif @table[flag].instance_of? Array | 
					
						
							| 
									
										
										
										
											2020-08-19 17:12:32 +01:00
										 |  |  |             @cli_args << "#{option}=#{@table[flag].join(",")}" | 
					
						
							| 
									
										
										
										
											2020-05-05 12:50:41 +01:00
										 |  |  |           end | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  |         @cli_args.freeze | 
					
						
							| 
									
										
										
										
											2020-04-05 17:39:30 +05:30
										 |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-18 01:32:55 +01:00
										 |  |  |       def respond_to_missing?(method_name, *) | 
					
						
							| 
									
										
										
										
											2022-12-04 22:15:12 -08:00
										 |  |  |         @table.key?(method_name) | 
					
						
							| 
									
										
										
										
											2021-03-18 14:46:48 +00:00
										 |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       def method_missing(method_name, *args) | 
					
						
							|  |  |  |         return_value = super | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # Once we are frozen, verify any arg method calls are already defined in the table. | 
					
						
							|  |  |  |         # The default OpenStruct behaviour is to return nil for anything unknown. | 
					
						
							|  |  |  |         if frozen? && args.empty? && !@table.key?(method_name) | 
					
						
							|  |  |  |           raise NoMethodError, "CLI arg for `#{method_name}` is not declared for this command" | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return_value | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2019-04-17 19:42:27 +09:00
										 |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | end |