| 
									
										
										
										
											2024-08-12 10:30:59 +01:00
										 |  |  | # typed: true # rubocop:todo Sorbet/StrictSigil | 
					
						
							| 
									
										
										
										
											2019-04-19 15:38:03 +09:00
										 |  |  | # frozen_string_literal: true | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-14 08:49:39 -04:00
										 |  |  | require "context" | 
					
						
							| 
									
										
										
										
											2009-10-15 14:42:19 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-13 09:00:51 +00:00
										 |  |  | module Homebrew | 
					
						
							| 
									
										
										
										
											2020-08-02 14:32:31 +02:00
										 |  |  |   extend Context | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-06 09:49:53 -08:00
										 |  |  |   def self._system(cmd, *args, **options) | 
					
						
							| 
									
										
										
										
											2014-03-29 02:24:01 -05:00
										 |  |  |     pid = fork do | 
					
						
							| 
									
										
										
										
											2010-01-13 09:00:51 +00:00
										 |  |  |       yield if block_given? | 
					
						
							| 
									
										
										
										
											2018-09-02 20:14:54 +01:00
										 |  |  |       args.map!(&:to_s) | 
					
						
							| 
									
										
										
										
											2016-09-11 17:47:04 +01:00
										 |  |  |       begin | 
					
						
							| 
									
										
										
										
											2018-05-21 01:43:42 +02:00
										 |  |  |         exec(cmd, *args, **options) | 
					
						
							| 
									
										
										
										
											2016-09-11 17:47:04 +01:00
										 |  |  |       rescue | 
					
						
							|  |  |  |         nil | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2010-01-13 09:00:51 +00:00
										 |  |  |       exit! 1 # never gets here unless exec failed | 
					
						
							|  |  |  |     end | 
					
						
							| 
									
										
										
										
											2020-11-23 18:15:48 +01:00
										 |  |  |     Process.wait(T.must(pid)) | 
					
						
							| 
									
										
										
										
											2017-06-10 20:12:55 +03:00
										 |  |  |     $CHILD_STATUS.success? | 
					
						
							| 
									
										
										
										
											2010-01-13 09:00:51 +00:00
										 |  |  |   end | 
					
						
							| 
									
										
										
										
											2014-06-30 19:15:03 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-06 09:49:53 -08:00
										 |  |  |   def self.system(cmd, *args, **options) | 
					
						
							| 
									
										
										
										
											2020-08-02 14:32:31 +02:00
										 |  |  |     if verbose? | 
					
						
							| 
									
										
										
										
											2023-10-28 23:41:01 -07:00
										 |  |  |       out = (options[:out] == :err) ? $stderr : $stdout | 
					
						
							|  |  |  |       out.puts "#{cmd} #{args * " "}".gsub(RUBY_PATH, "ruby") | 
					
						
							|  |  |  |                                      .gsub($LOAD_PATH.join(File::PATH_SEPARATOR).to_s, "$LOAD_PATH") | 
					
						
							| 
									
										
										
										
											2019-11-06 14:59:27 +00:00
										 |  |  |     end | 
					
						
							| 
									
										
										
										
											2018-05-21 01:43:42 +02:00
										 |  |  |     _system(cmd, *args, **options) | 
					
						
							| 
									
										
										
										
											2015-09-08 16:06:39 +08:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-07 00:31:28 +02:00
										 |  |  |   # rubocop:disable Style/GlobalVars | 
					
						
							| 
									
										
										
										
											2023-02-27 11:43:16 -08:00
										 |  |  |   sig { params(the_module: Module, pattern: Regexp).void } | 
					
						
							| 
									
										
										
										
											2023-03-06 09:49:53 -08:00
										 |  |  |   def self.inject_dump_stats!(the_module, pattern) | 
					
						
							| 
									
										
										
										
											2017-10-07 00:31:28 +02:00
										 |  |  |     @injected_dump_stat_modules ||= {} | 
					
						
							| 
									
										
										
										
											2016-09-26 01:44:51 +02:00
										 |  |  |     @injected_dump_stat_modules[the_module] ||= [] | 
					
						
							|  |  |  |     injected_methods = @injected_dump_stat_modules[the_module] | 
					
						
							| 
									
										
										
										
											2016-04-18 17:39:21 -04:00
										 |  |  |     the_module.module_eval do | 
					
						
							|  |  |  |       instance_methods.grep(pattern).each do |name| | 
					
						
							|  |  |  |         next if injected_methods.include? name | 
					
						
							| 
									
										
										
										
											2018-09-17 02:45:00 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-18 17:39:21 -04:00
										 |  |  |         method = instance_method(name) | 
					
						
							|  |  |  |         define_method(name) do |*args, &block| | 
					
						
							| 
									
										
										
										
											2024-07-14 08:49:39 -04:00
										 |  |  |           require "time" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-13 10:03:26 +01:00
										 |  |  |           time = Time.now | 
					
						
							| 
									
										
										
										
											2020-11-23 18:15:48 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |           begin | 
					
						
							| 
									
										
										
										
											2024-02-22 23:52:46 +00:00
										 |  |  |             method.bind_call(self, *args, &block) | 
					
						
							| 
									
										
										
										
											2020-11-23 18:15:48 +01:00
										 |  |  |           ensure | 
					
						
							|  |  |  |             $times[name] ||= 0
 | 
					
						
							|  |  |  |             $times[name] += Time.now - time | 
					
						
							|  |  |  |           end | 
					
						
							| 
									
										
										
										
											2016-04-18 17:39:21 -04:00
										 |  |  |         end | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-23 22:02:23 +02:00
										 |  |  |     return unless $times.nil? | 
					
						
							| 
									
										
										
										
											2018-09-17 02:45:00 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-23 22:02:23 +02:00
										 |  |  |     $times = {} | 
					
						
							|  |  |  |     at_exit do | 
					
						
							| 
									
										
										
										
											2019-01-22 14:20:24 +00:00
										 |  |  |       col_width = [$times.keys.map(&:size).max.to_i + 2, 15].max | 
					
						
							| 
									
										
										
										
											2016-09-23 22:02:23 +02:00
										 |  |  |       $times.sort_by { |_k, v| v }.each do |method, time| | 
					
						
							| 
									
										
										
										
											2024-03-07 16:20:20 +00:00
										 |  |  |         puts format("%<method>-#{col_width}s %<time>0.4f sec", method: "#{method}:", time:) | 
					
						
							| 
									
										
										
										
											2016-04-18 17:39:21 -04:00
										 |  |  |       end | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							| 
									
										
										
										
											2017-10-07 00:31:28 +02:00
										 |  |  |   # rubocop:enable Style/GlobalVars | 
					
						
							| 
									
										
										
										
											2010-01-13 09:00:51 +00:00
										 |  |  | end | 
					
						
							| 
									
										
										
										
											2023-02-27 20:20:56 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  | module Utils | 
					
						
							|  |  |  |   # Removes the rightmost segment from the constant expression in the string. | 
					
						
							|  |  |  |   # | 
					
						
							|  |  |  |   #   deconstantize('Net::HTTP')   # => "Net" | 
					
						
							|  |  |  |   #   deconstantize('::Net::HTTP') # => "::Net" | 
					
						
							|  |  |  |   #   deconstantize('String')      # => "" | 
					
						
							|  |  |  |   #   deconstantize('::String')    # => "" | 
					
						
							|  |  |  |   #   deconstantize('')            # => "" | 
					
						
							|  |  |  |   # | 
					
						
							|  |  |  |   # See also #demodulize. | 
					
						
							|  |  |  |   # @see https://github.com/rails/rails/blob/b0dd7c7/activesupport/lib/active_support/inflector/methods.rb#L247-L258 | 
					
						
							|  |  |  |   #   `ActiveSupport::Inflector.deconstantize` | 
					
						
							|  |  |  |   sig { params(path: String).returns(String) } | 
					
						
							|  |  |  |   def self.deconstantize(path) | 
					
						
							|  |  |  |     T.must(path[0, path.rindex("::") || 0]) # implementation based on the one in facets' Module#spacename | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   # Removes the module part from the expression in the string. | 
					
						
							|  |  |  |   # | 
					
						
							|  |  |  |   #   demodulize('ActiveSupport::Inflector::Inflections') # => "Inflections" | 
					
						
							|  |  |  |   #   demodulize('Inflections')                           # => "Inflections" | 
					
						
							|  |  |  |   #   demodulize('::Inflections')                         # => "Inflections" | 
					
						
							|  |  |  |   #   demodulize('')                                      # => "" | 
					
						
							|  |  |  |   # | 
					
						
							|  |  |  |   # See also #deconstantize. | 
					
						
							|  |  |  |   # @see https://github.com/rails/rails/blob/b0dd7c7/activesupport/lib/active_support/inflector/methods.rb#L230-L245 | 
					
						
							|  |  |  |   #   `ActiveSupport::Inflector.demodulize` | 
					
						
							|  |  |  |   sig { params(path: String).returns(String) } | 
					
						
							|  |  |  |   def self.demodulize(path) | 
					
						
							|  |  |  |     if (i = path.rindex("::")) | 
					
						
							|  |  |  |       T.must(path[(i + 2)..]) | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |       path | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   # A lightweight alternative to `ActiveSupport::Inflector.pluralize`: | 
					
						
							|  |  |  |   # Combines `stem` with the `singular` or `plural` suffix based on `count`. | 
					
						
							| 
									
										
										
										
											2023-03-20 07:23:17 -04:00
										 |  |  |   # Adds a prefix of the count value if `include_count` is set to true. | 
					
						
							| 
									
										
										
										
											2023-03-19 23:10:47 -04:00
										 |  |  |   sig { | 
					
						
							| 
									
										
										
										
											2023-03-20 07:23:17 -04:00
										 |  |  |     params(stem: String, count: Integer, plural: String, singular: String, include_count: T::Boolean).returns(String) | 
					
						
							| 
									
										
										
										
											2023-03-19 23:10:47 -04:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2023-03-20 07:23:17 -04:00
										 |  |  |   def self.pluralize(stem, count, plural: "s", singular: "", include_count: false) | 
					
						
							|  |  |  |     prefix = include_count ? "#{count} " : "" | 
					
						
							| 
									
										
										
										
											2023-02-27 20:20:56 -08:00
										 |  |  |     suffix = (count == 1) ? singular : plural | 
					
						
							| 
									
										
										
										
											2023-03-19 23:10:47 -04:00
										 |  |  |     "#{prefix}#{stem}#{suffix}" | 
					
						
							| 
									
										
										
										
											2023-02-27 20:20:56 -08:00
										 |  |  |   end | 
					
						
							| 
									
										
										
										
											2023-03-07 10:11:59 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-14 10:23:29 -07:00
										 |  |  |   sig { params(author: String).returns({ email: String, name: String }) } | 
					
						
							|  |  |  |   def self.parse_author!(author) | 
					
						
							|  |  |  |     match_data = /^(?<name>[^<]+?)[ \t]*<(?<email>[^>]+?)>$/.match(author) | 
					
						
							|  |  |  |     if match_data | 
					
						
							|  |  |  |       name = match_data[:name] | 
					
						
							|  |  |  |       email = match_data[:email] | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |     raise UsageError, "Unable to parse name and email." if name.blank? && email.blank? | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     { name: T.must(name), email: T.must(email) } | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-07 10:11:59 -08:00
										 |  |  |   # Makes an underscored, lowercase form from the expression in the string. | 
					
						
							|  |  |  |   # | 
					
						
							|  |  |  |   # Changes '::' to '/' to convert namespaces to paths. | 
					
						
							|  |  |  |   # | 
					
						
							|  |  |  |   #   underscore('ActiveModel')         # => "active_model" | 
					
						
							|  |  |  |   #   underscore('ActiveModel::Errors') # => "active_model/errors" | 
					
						
							|  |  |  |   # | 
					
						
							|  |  |  |   # @see https://github.com/rails/rails/blob/v6.1.7.2/activesupport/lib/active_support/inflector/methods.rb#L81-L100 | 
					
						
							|  |  |  |   #   `ActiveSupport::Inflector.underscore` | 
					
						
							|  |  |  |   sig { params(camel_cased_word: T.any(String, Symbol)).returns(String) } | 
					
						
							|  |  |  |   def self.underscore(camel_cased_word) | 
					
						
							| 
									
										
										
										
											2023-03-07 10:45:53 -08:00
										 |  |  |     return camel_cased_word.to_s unless /[A-Z-]|::/.match?(camel_cased_word) | 
					
						
							| 
									
										
										
										
											2023-03-07 10:14:57 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-07 10:11:59 -08:00
										 |  |  |     word = camel_cased_word.to_s.gsub("::", "/") | 
					
						
							| 
									
										
										
										
											2023-03-07 10:14:57 -08:00
										 |  |  |     word.gsub!(/([A-Z])(?=[A-Z][a-z])|([a-z\d])(?=[A-Z])/) do | 
					
						
							| 
									
										
										
										
											2023-03-07 10:45:53 -08:00
										 |  |  |       T.must(::Regexp.last_match(1) || ::Regexp.last_match(2)) << "_" | 
					
						
							| 
									
										
										
										
											2023-03-07 10:14:57 -08:00
										 |  |  |     end | 
					
						
							| 
									
										
										
										
											2023-03-07 10:11:59 -08:00
										 |  |  |     word.tr!("-", "_") | 
					
						
							|  |  |  |     word.downcase! | 
					
						
							|  |  |  |     word | 
					
						
							|  |  |  |   end | 
					
						
							| 
									
										
										
										
											2024-01-01 17:46:48 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   SAFE_FILENAME_REGEX = /[[:cntrl:]#{Regexp.escape("#{File::SEPARATOR}#{File::ALT_SEPARATOR}")}]/o | 
					
						
							|  |  |  |   private_constant :SAFE_FILENAME_REGEX | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   sig { params(basename: String).returns(T::Boolean) } | 
					
						
							|  |  |  |   def self.safe_filename?(basename) | 
					
						
							|  |  |  |     !SAFE_FILENAME_REGEX.match?(basename) | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   sig { params(basename: String).returns(String) } | 
					
						
							|  |  |  |   def self.safe_filename(basename) | 
					
						
							|  |  |  |     basename.gsub(SAFE_FILENAME_REGEX, "") | 
					
						
							|  |  |  |   end | 
					
						
							| 
									
										
										
										
											2023-02-27 20:20:56 -08:00
										 |  |  | end |