diff --git a/Library/.rubocop.yml b/Library/.rubocop.yml index 4b579cd488..927bbd4bab 100644 --- a/Library/.rubocop.yml +++ b/Library/.rubocop.yml @@ -423,9 +423,13 @@ Style/NumericLiterals: Exclude: - "**/Brewfile" -# OpenStruct is a nice helper. +# TODO: These are pre-existing violations and should be corrected +# to define methods so that call sites can be type-checked. Style/OpenStructUse: - Enabled: false + Exclude: + - "Homebrew/cli/args.rb" + - "Homebrew/tab.rb" + - "Taps/**/*.rb" # Rescuing `StandardError` is an understood default. Style/RescueStandardError: diff --git a/Library/Homebrew/cmd/uses.rb b/Library/Homebrew/cmd/uses.rb index 0b4e6b0f73..e1d0c8830c 100644 --- a/Library/Homebrew/cmd/uses.rb +++ b/Library/Homebrew/cmd/uses.rb @@ -67,7 +67,10 @@ module Homebrew opoo e used_formulae_missing = true # If the formula doesn't exist: fake the needed formula object name. + # This is a legacy use of OpenStruct that should be refactored. + # rubocop:disable Style/OpenStructUse args.named.map { |name| OpenStruct.new name: name, full_name: name } + # rubocop:enable Style/OpenStructUse end use_runtime_dependents = args.installed? && diff --git a/Library/Homebrew/completions.rb b/Library/Homebrew/completions.rb index f1ce56475c..e7fca41fc7 100644 --- a/Library/Homebrew/completions.rb +++ b/Library/Homebrew/completions.rb @@ -12,6 +12,14 @@ module Homebrew module Completions extend T::Sig + Variables = Struct.new( + :aliases, + :builtin_command_descriptions, + :completion_functions, + :function_mappings, + keyword_init: true, + ) + module_function COMPLETIONS_DIR = (HOMEBREW_REPOSITORY/"completions").freeze @@ -195,17 +203,16 @@ module Homebrew sig { params(commands: T::Array[String]).returns(String) } def generate_bash_completion_file(commands) - variables = OpenStruct.new + variables = Variables.new( + completion_functions: commands.map do |command| + generate_bash_subcommand_completion command + end.compact, + function_mappings: commands.map do |command| + next unless command_gets_completions? command - variables[:completion_functions] = commands.map do |command| - generate_bash_subcommand_completion command - end.compact - - variables[:function_mappings] = commands.map do |command| - next unless command_gets_completions? command - - "#{command}) _brew_#{Commands.method_name command} ;;" - end.compact + "#{command}) _brew_#{Commands.method_name command} ;;" + end.compact, + ) ERB.new((TEMPLATE_DIR/"bash.erb").read, trim_mode: ">").result(variables.instance_eval { binding }) end @@ -272,27 +279,27 @@ module Homebrew sig { params(commands: T::Array[String]).returns(String) } def generate_zsh_completion_file(commands) - variables = OpenStruct.new + variables = Variables.new( + aliases: Commands::HOMEBREW_INTERNAL_COMMAND_ALIASES.map do |alias_command, command| + alias_command = "'#{alias_command}'" if alias_command.start_with? "-" + command = "'#{command}'" if command.start_with? "-" + "#{alias_command} #{command}" + end.compact, - variables[:aliases] = Commands::HOMEBREW_INTERNAL_COMMAND_ALIASES.map do |alias_command, command| - alias_command = "'#{alias_command}'" if alias_command.start_with? "-" - command = "'#{command}'" if command.start_with? "-" - "#{alias_command} #{command}" - end.compact + builtin_command_descriptions: commands.map do |command| + next if Commands::HOMEBREW_INTERNAL_COMMAND_ALIASES.key? command - variables[:builtin_command_descriptions] = commands.map do |command| - next if Commands::HOMEBREW_INTERNAL_COMMAND_ALIASES.key? command + description = Commands.command_description(command, short: true) + next if description.blank? - description = Commands.command_description(command, short: true) - next if description.blank? + description = format_description description + "'#{command}:#{description}'" + end.compact, - description = format_description description - "'#{command}:#{description}'" - end.compact - - variables[:completion_functions] = commands.map do |command| - generate_zsh_subcommand_completion command - end.compact + completion_functions: commands.map do |command| + generate_zsh_subcommand_completion command + end.compact, + ) ERB.new((TEMPLATE_DIR/"zsh.erb").read, trim_mode: ">").result(variables.instance_eval { binding }) end @@ -346,11 +353,11 @@ module Homebrew sig { params(commands: T::Array[String]).returns(String) } def generate_fish_completion_file(commands) - variables = OpenStruct.new - - variables[:completion_functions] = commands.map do |command| - generate_fish_subcommand_completion command - end.compact + variables = Variables.new( + completion_functions: commands.map do |command| + generate_fish_subcommand_completion command + end.compact, + ) ERB.new((TEMPLATE_DIR/"fish.erb").read, trim_mode: ">").result(variables.instance_eval { binding }) end diff --git a/Library/Homebrew/manpages.rb b/Library/Homebrew/manpages.rb index e410587c56..c08c000ee4 100644 --- a/Library/Homebrew/manpages.rb +++ b/Library/Homebrew/manpages.rb @@ -14,6 +14,21 @@ module Homebrew module Manpages extend T::Sig + Variables = Struct.new( + :alumni, + :commands, + :developer_commands, + :environment_variables, + :global_cask_options, + :global_options, + :lead, + :maintainers, + :official_external_commands, + :plc, + :tsc, + keyword_init: true, + ) + module_function def regenerate_man_pages(quiet:) @@ -27,32 +42,25 @@ module Homebrew def build_man_page(quiet:) template = (SOURCE_PATH/"brew.1.md.erb").read - variables = OpenStruct.new - - variables[:commands] = generate_cmd_manpages(Commands.internal_commands_paths) - variables[:developer_commands] = generate_cmd_manpages(Commands.internal_developer_commands_paths) - variables[:official_external_commands] = - generate_cmd_manpages(Commands.official_external_commands_paths(quiet: quiet)) - variables[:global_cask_options] = global_cask_options_manpage - variables[:global_options] = global_options_manpage - variables[:environment_variables] = env_vars_manpage - readme = HOMEBREW_REPOSITORY/"README.md" - variables[:lead] = - readme.read[/(Homebrew's \[Project Leader.*\.)/, 1] - .gsub(/\[([^\]]+)\]\([^)]+\)/, '\1') - variables[:plc] = - readme.read[/(Homebrew's \[Project Leadership Committee.*\.)/, 1] - .gsub(/\[([^\]]+)\]\([^)]+\)/, '\1') - variables[:tsc] = - readme.read[/(Homebrew's \[Technical Steering Committee.*\.)/, 1] - .gsub(/\[([^\]]+)\]\([^)]+\)/, '\1') - variables[:maintainers] = - readme.read[/(Homebrew's maintainers .*\.)/, 1] - .gsub(/\[([^\]]+)\]\([^)]+\)/, '\1') - variables[:alumni] = - readme.read[/(Former maintainers .*\.)/, 1] - .gsub(/\[([^\]]+)\]\([^)]+\)/, '\1') + variables = Variables.new( + commands: generate_cmd_manpages(Commands.internal_commands_paths), + developer_commands: generate_cmd_manpages(Commands.internal_developer_commands_paths), + official_external_commands: generate_cmd_manpages(Commands.official_external_commands_paths(quiet: quiet)), + global_cask_options: global_cask_options_manpage, + global_options: global_options_manpage, + environment_variables: env_vars_manpage, + lead: readme.read[/(Homebrew's \[Project Leader.*\.)/, 1] + .gsub(/\[([^\]]+)\]\([^)]+\)/, '\1'), + plc: readme.read[/(Homebrew's \[Project Leadership Committee.*\.)/, 1] + .gsub(/\[([^\]]+)\]\([^)]+\)/, '\1'), + tsc: readme.read[/(Homebrew's \[Technical Steering Committee.*\.)/, 1] + .gsub(/\[([^\]]+)\]\([^)]+\)/, '\1'), + maintainers: readme.read[/(Homebrew's maintainers .*\.)/, 1] + .gsub(/\[([^\]]+)\]\([^)]+\)/, '\1'), + alumni: readme.read[/(Former maintainers .*\.)/, 1] + .gsub(/\[([^\]]+)\]\([^)]+\)/, '\1'), + ) ERB.new(template, trim_mode: ">").result(variables.instance_eval { binding }) end diff --git a/Library/Homebrew/test/api/cask_spec.rb b/Library/Homebrew/test/api/cask_spec.rb index b1380216b6..001e4ba0e3 100644 --- a/Library/Homebrew/test/api/cask_spec.rb +++ b/Library/Homebrew/test/api/cask_spec.rb @@ -49,7 +49,7 @@ describe Homebrew::API::Cask do describe "::fetch_source" do it "fetches the source of a cask (defaulting to master when no `git_head` is passed)" do - curl_output = OpenStruct.new(stdout: "foo", success?: true) + curl_output = instance_double(SystemCommand::Result, stdout: "foo", success?: true) expect(Utils::Curl).to receive(:curl_output) .with("--fail", "https://raw.githubusercontent.com/Homebrew/homebrew-cask/master/Casks/foo.rb") .and_return(curl_output) diff --git a/Library/Homebrew/test/api_spec.rb b/Library/Homebrew/test/api_spec.rb index bc09640624..f0d7ce426f 100644 --- a/Library/Homebrew/test/api_spec.rb +++ b/Library/Homebrew/test/api_spec.rb @@ -14,7 +14,7 @@ describe Homebrew::API do end def mock_curl_output(stdout: "", success: true) - curl_output = OpenStruct.new(stdout: stdout, success?: success) + curl_output = instance_double(SystemCommand::Result, stdout: stdout, success?: success) allow(Utils::Curl).to receive(:curl_output).and_return curl_output end