From 6c663837c7601425b80be9393472c8a8a9710123 Mon Sep 17 00:00:00 2001 From: Ruoyu Zhong Date: Thu, 21 Aug 2025 01:47:56 +0800 Subject: [PATCH] manpages: `typed: strict` Co-authored-by: Mike McQuaid --- Library/Homebrew/manpages.rb | 44 +++++++++++++++++++++++++++--------- 1 file changed, 33 insertions(+), 11 deletions(-) diff --git a/Library/Homebrew/manpages.rb b/Library/Homebrew/manpages.rb index e2d79bf1f8..f2ccd27852 100644 --- a/Library/Homebrew/manpages.rb +++ b/Library/Homebrew/manpages.rb @@ -1,4 +1,4 @@ -# typed: true # rubocop:todo Sorbet/StrictSigil +# typed: strict # frozen_string_literal: true require "cli/parser" @@ -22,10 +22,11 @@ module Homebrew keyword_init: true, ) - SOURCE_PATH = (HOMEBREW_LIBRARY_PATH/"manpages").freeze - TARGET_MAN_PATH = (HOMEBREW_REPOSITORY/"manpages").freeze - TARGET_DOC_PATH = (HOMEBREW_REPOSITORY/"docs").freeze + SOURCE_PATH = T.let((HOMEBREW_LIBRARY_PATH/"manpages").freeze, Pathname) + TARGET_MAN_PATH = T.let((HOMEBREW_REPOSITORY/"manpages").freeze, Pathname) + TARGET_DOC_PATH = T.let((HOMEBREW_REPOSITORY/"docs").freeze, Pathname) + sig { params(quiet: T::Boolean).void } def self.regenerate_man_pages(quiet:) require "kramdown" require "manpages/parser/ronn" @@ -45,6 +46,7 @@ module Homebrew File.write(TARGET_MAN_PATH/"brew.1", roff) end + sig { params(quiet: T::Boolean).void } def self.build_man_page(quiet:) template = (SOURCE_PATH/"brew.1.md.erb").read readme = HOMEBREW_REPOSITORY/"README.md" @@ -70,11 +72,13 @@ module Homebrew ERB.new(template, trim_mode: ">").result(variables.instance_eval { binding }) end + sig { params(path: Pathname).returns(String) } def self.sort_key_for_path(path) # Options after regular commands (`~` comes after `z` in ASCII table). path.basename.to_s.sub(/\.(rb|sh)$/, "").sub(/^--/, "~~") end + sig { params(cmd_paths: T::Array[Pathname]).returns(String) } def self.generate_cmd_manpages(cmd_paths) man_page_lines = [] @@ -99,7 +103,9 @@ module Homebrew sig { params(cmd_parser: CLI::Parser).returns(T::Array[String]) } def self.cmd_parser_manpage_lines(cmd_parser) - lines = [format_usage_banner(cmd_parser.usage_banner_text)] + lines = [] + usage_banner_text = cmd_parser.usage_banner_text + lines << format_usage_banner(usage_banner_text) if usage_banner_text lines += cmd_parser.processed_options.filter_map do |short, long, desc, hidden| next if hidden @@ -115,14 +121,21 @@ module Homebrew lines end + sig { params(cmd_path: Pathname).returns(T.nilable(T::Array[String])) } def self.cmd_comment_manpage_lines(cmd_path) comment_lines = cmd_path.read.lines.grep(/^#:/) return if comment_lines.empty? - return if comment_lines.first.include?("@hide_from_man_page") - lines = [format_usage_banner(comment_lines.first).chomp] - comment_lines.slice(1..-1) - .each do |line| + first_comment_line = comment_lines.first + return unless first_comment_line + return if first_comment_line.include?("@hide_from_man_page") + + lines = [format_usage_banner(first_comment_line).chomp] + all_but_first_comment_lines = comment_lines.slice(1..-1) + return unless all_but_first_comment_lines + return if all_but_first_comment_lines.empty? + + all_but_first_comment_lines.each do |line| line = line.slice(4..-2) unless line lines.last << "\n" @@ -174,10 +187,18 @@ module Homebrew lines.join("\n") end + sig { params(opt: T.nilable(String)).returns(T.nilable(String)) } def self.format_opt(opt) "`#{opt}`" unless opt.nil? end + sig { + params( + short: T.nilable(String), + long: T.nilable(String), + desc: String, + ).returns(String) + } def self.generate_option_doc(short, long, desc) comma = (short && long) ? ", " : "" <<~EOS @@ -188,9 +209,10 @@ module Homebrew EOS end + sig { params(usage_banner: String).returns(String) } def self.format_usage_banner(usage_banner) - usage_banner&.sub(/^(#: *\* )?/, "### ") - &.gsub(/(?