| 
									
										
										
										
											2024-03-03 15:32:30 -08:00
										 |  |  | # typed: strong | 
					
						
							|  |  |  | # frozen_string_literal: true | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-29 16:19:34 -07:00
										 |  |  | require "cli/parser" | 
					
						
							| 
									
										
										
										
											2024-08-13 10:34:40 -04:00
										 |  |  | require "shell_command" | 
					
						
							| 
									
										
										
										
											2024-03-29 16:19:34 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-03 15:32:30 -08:00
										 |  |  | module Homebrew | 
					
						
							| 
									
										
										
										
											2024-03-05 10:40:02 -08:00
										 |  |  |   # Subclass this to implement a `brew` command. This is preferred to declaring a named function in the `Homebrew` | 
					
						
							|  |  |  |   # module, because: | 
					
						
							| 
									
										
										
										
											2024-04-30 11:10:23 +02:00
										 |  |  |   # | 
					
						
							| 
									
										
										
										
											2024-03-05 10:40:02 -08:00
										 |  |  |   # - Each Command lives in an isolated namespace. | 
					
						
							|  |  |  |   # - Each Command implements a defined interface. | 
					
						
							| 
									
										
										
										
											2024-04-30 11:10:23 +02:00
										 |  |  |   # - `args` is available as an instance method and thus does not need to be passed as an argument to helper methods. | 
					
						
							| 
									
										
										
										
											2024-03-30 16:16:52 -07:00
										 |  |  |   # - Subclasses no longer need to reference `CLI::Parser` or parse args explicitly. | 
					
						
							| 
									
										
										
										
											2024-03-05 10:40:02 -08:00
										 |  |  |   # | 
					
						
							|  |  |  |   # To subclass, implement a `run` method and provide a `cmd_args` block to document the command and its allowed args. | 
					
						
							| 
									
										
										
										
											2024-03-15 12:51:03 -07:00
										 |  |  |   # To generate method signatures for command args, run `brew typecheck --update`. | 
					
						
							| 
									
										
										
										
											2024-08-13 13:37:28 -07:00
										 |  |  |   # | 
					
						
							|  |  |  |   # @api public | 
					
						
							| 
									
										
										
										
											2024-03-03 15:32:30 -08:00
										 |  |  |   class AbstractCommand | 
					
						
							|  |  |  |     extend T::Helpers | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     abstract! | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     class << self | 
					
						
							| 
									
										
										
										
											2024-04-21 16:15:57 -07:00
										 |  |  |       sig { returns(T.nilable(T.class_of(CLI::Args))) } | 
					
						
							|  |  |  |       attr_reader :args_class | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-05 10:40:02 -08:00
										 |  |  |       sig { returns(String) } | 
					
						
							| 
									
										
										
										
											2024-07-14 08:49:39 -04:00
										 |  |  |       def command_name | 
					
						
							|  |  |  |         require "utils" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         Utils.underscore(T.must(name).split("::").fetch(-1)) | 
					
						
							|  |  |  |              .tr("_", "-") | 
					
						
							|  |  |  |              .delete_suffix("-cmd") | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2024-03-05 10:40:02 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-06 14:49:13 -08:00
										 |  |  |       # @return the AbstractCommand subclass associated with the brew CLI command name. | 
					
						
							|  |  |  |       sig { params(name: String).returns(T.nilable(T.class_of(AbstractCommand))) } | 
					
						
							|  |  |  |       def command(name) = subclasses.find { _1.command_name == name } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-03 20:17:02 -07:00
										 |  |  |       sig { returns(T::Boolean) } | 
					
						
							|  |  |  |       def dev_cmd? = T.must(name).start_with?("Homebrew::DevCmd") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-13 10:34:40 -04:00
										 |  |  |       sig { returns(T::Boolean) } | 
					
						
							|  |  |  |       def ruby_cmd? = !include?(Homebrew::ShellCommand) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-18 15:50:50 -07:00
										 |  |  |       sig { returns(CLI::Parser) } | 
					
						
							|  |  |  |       def parser = CLI::Parser.new(self, &@parser_block) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-05 10:40:02 -08:00
										 |  |  |       private | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-13 13:37:28 -07:00
										 |  |  |       # The description and arguments of the command should be defined within this block. | 
					
						
							|  |  |  |       # | 
					
						
							|  |  |  |       # @api public | 
					
						
							| 
									
										
										
										
											2024-03-15 15:56:01 -07:00
										 |  |  |       sig { params(block: T.proc.bind(CLI::Parser).void).void } | 
					
						
							| 
									
										
										
										
											2024-03-05 10:40:02 -08:00
										 |  |  |       def cmd_args(&block) | 
					
						
							| 
									
										
										
										
											2024-03-18 15:50:50 -07:00
										 |  |  |         @parser_block = T.let(block, T.nilable(T.proc.void)) | 
					
						
							| 
									
										
										
										
											2024-04-21 16:15:57 -07:00
										 |  |  |         @args_class = T.let(const_set(:Args, Class.new(CLI::Args)), T.nilable(T.class_of(CLI::Args))) | 
					
						
							| 
									
										
										
										
											2024-03-05 10:40:02 -08:00
										 |  |  |       end | 
					
						
							| 
									
										
										
										
											2024-03-03 15:32:30 -08:00
										 |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-05 10:40:02 -08:00
										 |  |  |     sig { returns(CLI::Args) } | 
					
						
							| 
									
										
										
										
											2024-03-03 15:32:30 -08:00
										 |  |  |     attr_reader :args | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-06 21:12:17 -08:00
										 |  |  |     sig { params(argv: T::Array[String]).void } | 
					
						
							|  |  |  |     def initialize(argv = ARGV.freeze) | 
					
						
							| 
									
										
										
										
											2024-03-18 15:50:50 -07:00
										 |  |  |       @args = T.let(self.class.parser.parse(argv), CLI::Args) | 
					
						
							| 
									
										
										
										
											2024-03-03 15:32:30 -08:00
										 |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-13 13:37:28 -07:00
										 |  |  |     # This method will be invoked when the command is run. | 
					
						
							|  |  |  |     # | 
					
						
							|  |  |  |     # @api public | 
					
						
							| 
									
										
										
										
											2024-03-03 15:32:30 -08:00
										 |  |  |     sig { abstract.void } | 
					
						
							|  |  |  |     def run; end | 
					
						
							|  |  |  |   end | 
					
						
							| 
									
										
										
										
											2024-08-10 09:22:12 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |   module Cmd | 
					
						
							|  |  |  |     # The command class for `brew` itself, allowing its args to be parsed. | 
					
						
							|  |  |  |     class Brew < AbstractCommand; end | 
					
						
							|  |  |  |   end | 
					
						
							| 
									
										
										
										
											2024-03-03 15:32:30 -08:00
										 |  |  | end |