cli/parser: allow options to be hidden
This commit is contained in:
		
							parent
							
								
									76cda750d5
								
							
						
					
					
						commit
						08b44afcdf
					
				@ -10,6 +10,7 @@ require "utils/tty"
 | 
			
		||||
 | 
			
		||||
COMMAND_DESC_WIDTH = 80
 | 
			
		||||
OPTION_DESC_WIDTH = 43
 | 
			
		||||
HIDDEN_DESC_PLACEHOLDER = "@@HIDDEN@@"
 | 
			
		||||
 | 
			
		||||
module Homebrew
 | 
			
		||||
  module CLI
 | 
			
		||||
@ -148,13 +149,13 @@ module Homebrew
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def switch(*names, description: nil, replacement: nil, env: nil, required_for: nil, depends_on: nil,
 | 
			
		||||
                 method: :on)
 | 
			
		||||
                 method: :on, hidden: false)
 | 
			
		||||
        global_switch = names.first.is_a?(Symbol)
 | 
			
		||||
        return if global_switch
 | 
			
		||||
 | 
			
		||||
        description = option_to_description(*names) if description.nil?
 | 
			
		||||
        description = option_description(description, *names, hidden: hidden)
 | 
			
		||||
        if replacement.nil?
 | 
			
		||||
          process_option(*names, description, type: :switch)
 | 
			
		||||
          process_option(*names, description, type: :switch, hidden: hidden)
 | 
			
		||||
        else
 | 
			
		||||
          description += " (disabled#{"; replaced by #{replacement}" if replacement.present?})"
 | 
			
		||||
        end
 | 
			
		||||
@ -198,10 +199,10 @@ module Homebrew
 | 
			
		||||
        @parser.banner
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def comma_array(name, description: nil)
 | 
			
		||||
      def comma_array(name, description: nil, hidden: false)
 | 
			
		||||
        name = name.chomp "="
 | 
			
		||||
        description = option_to_description(name) if description.nil?
 | 
			
		||||
        process_option(name, description, type: :comma_array)
 | 
			
		||||
        description = option_description(description, name, hidden: hidden)
 | 
			
		||||
        process_option(name, description, type: :comma_array, hidden: hidden)
 | 
			
		||||
        @parser.on(name, OptionParser::REQUIRED_ARGUMENT, Array, *wrap_option_desc(description)) do |list|
 | 
			
		||||
          @args[option_to_name(name)] = list
 | 
			
		||||
        end
 | 
			
		||||
@ -215,7 +216,7 @@ module Homebrew
 | 
			
		||||
          [OptionParser::OPTIONAL_ARGUMENT, :optional_flag]
 | 
			
		||||
        end
 | 
			
		||||
        names.map! { |name| name.chomp "=" }
 | 
			
		||||
        description = option_to_description(*names) if description.nil?
 | 
			
		||||
        description = option_description(description, *names, hidden: hidden)
 | 
			
		||||
        if replacement.nil?
 | 
			
		||||
          process_option(*names, description, type: flag_type, hidden: hidden)
 | 
			
		||||
        else
 | 
			
		||||
@ -255,6 +256,13 @@ module Homebrew
 | 
			
		||||
        names.map { |name| name.to_s.sub(/\A--?/, "").tr("-", " ") }.max
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def option_description(description, *names, hidden: false)
 | 
			
		||||
        return HIDDEN_DESC_PLACEHOLDER if hidden
 | 
			
		||||
        return description if description.present?
 | 
			
		||||
 | 
			
		||||
        option_to_description(*names)
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def parse_remaining(argv, ignore_invalid_options: false)
 | 
			
		||||
        i = 0
 | 
			
		||||
        remaining = []
 | 
			
		||||
@ -347,6 +355,7 @@ module Homebrew
 | 
			
		||||
 | 
			
		||||
      def generate_help_text
 | 
			
		||||
        Formatter.wrap(@parser.to_s, COMMAND_DESC_WIDTH)
 | 
			
		||||
                 .gsub(/\n.*?@@HIDDEN@@.*?(?=\n)/, "")
 | 
			
		||||
                 .sub(/^/, "#{Tty.bold}Usage: brew#{Tty.reset} ")
 | 
			
		||||
                 .gsub(/`(.*?)`/m, "#{Tty.bold}\\1#{Tty.reset}")
 | 
			
		||||
                 .gsub(%r{<([^\s]+?://[^\s]+?)>}) { |url| Formatter.url(url) }
 | 
			
		||||
@ -597,7 +606,7 @@ module Homebrew
 | 
			
		||||
      def process_option(*args, type:, hidden: false)
 | 
			
		||||
        option, = @parser.make_switch(args)
 | 
			
		||||
        @processed_options.reject! { |existing| existing.second == option.long.first } if option.long.first.present?
 | 
			
		||||
        @processed_options << [option.short.first, option.long.first, option.arg, option.desc.first]
 | 
			
		||||
        @processed_options << [option.short.first, option.long.first, option.arg, option.desc.first, hidden]
 | 
			
		||||
 | 
			
		||||
        if type == :switch
 | 
			
		||||
          disable_switch(*args)
 | 
			
		||||
@ -607,6 +616,7 @@ module Homebrew
 | 
			
		||||
          end
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        return if hidden
 | 
			
		||||
        return if self.class.global_options.include? [option.short.first, option.long.first, option.desc.first]
 | 
			
		||||
 | 
			
		||||
        @non_global_processed_options << [option.long.first || option.short.first, type]
 | 
			
		||||
 | 
			
		||||
@ -52,7 +52,8 @@ module Homebrew
 | 
			
		||||
                          "JSON output: <https://docs.brew.sh/Querying-Brew>"
 | 
			
		||||
      switch "--bottle",
 | 
			
		||||
             depends_on:  "--json",
 | 
			
		||||
             description: "Output information about the bottles for <formula> and its dependencies."
 | 
			
		||||
             description: "Output information about the bottles for <formula> and its dependencies.",
 | 
			
		||||
             hidden:      true
 | 
			
		||||
      switch "--installed",
 | 
			
		||||
             depends_on:  "--json",
 | 
			
		||||
             description: "Print JSON of formulae that are currently installed."
 | 
			
		||||
 | 
			
		||||
@ -176,9 +176,11 @@ module Commands
 | 
			
		||||
    return if path.blank?
 | 
			
		||||
 | 
			
		||||
    if (cmd_parser = Homebrew::CLI::Parser.from_cmd_path(path))
 | 
			
		||||
      cmd_parser.processed_options.map do |short, long, _, desc|
 | 
			
		||||
      cmd_parser.processed_options.map do |short, long, _, desc, hidden|
 | 
			
		||||
        next if hidden
 | 
			
		||||
 | 
			
		||||
        [long || short, desc]
 | 
			
		||||
      end
 | 
			
		||||
      end.compact
 | 
			
		||||
    else
 | 
			
		||||
      options = []
 | 
			
		||||
      comment_lines = path.read.lines.grep(/^#:/)
 | 
			
		||||
 | 
			
		||||
@ -172,7 +172,9 @@ module Homebrew
 | 
			
		||||
 | 
			
		||||
  def cmd_parser_manpage_lines(cmd_parser)
 | 
			
		||||
    lines = [format_usage_banner(cmd_parser.usage_banner_text)]
 | 
			
		||||
    lines += cmd_parser.processed_options.map do |short, long, _, desc|
 | 
			
		||||
    lines += cmd_parser.processed_options.map do |short, long, _, desc, hidden|
 | 
			
		||||
      next if hidden
 | 
			
		||||
 | 
			
		||||
      if long.present?
 | 
			
		||||
        next if Homebrew::CLI::Parser.global_options.include?([short, long, desc])
 | 
			
		||||
        next if Homebrew::CLI::Parser.global_cask_options.any? do |_, option, description:, **|
 | 
			
		||||
@ -181,7 +183,7 @@ module Homebrew
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      generate_option_doc(short, long, desc)
 | 
			
		||||
    end.reject(&:blank?)
 | 
			
		||||
    end.compact
 | 
			
		||||
    lines
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -9,6 +9,7 @@ describe Homebrew::CLI::Parser do
 | 
			
		||||
      described_class.new do
 | 
			
		||||
        switch "--more-verbose", description: "Flag for higher verbosity"
 | 
			
		||||
        switch "--pry", env: :pry
 | 
			
		||||
        switch "--hidden", hidden: true
 | 
			
		||||
      end
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -98,6 +99,11 @@ describe Homebrew::CLI::Parser do
 | 
			
		||||
      expect(args.more_verbose?).to be false
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "sets the correct value for a hidden switch" do
 | 
			
		||||
      args = parser.parse([])
 | 
			
		||||
      expect(args.hidden?).to be false
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "raises an exception and outputs help text when an invalid option is passed" do
 | 
			
		||||
      expect { parser.parse(["--random"]) }.to raise_error(OptionParser::InvalidOption, /--random/)
 | 
			
		||||
                                           .and output(/Usage: brew/).to_stderr
 | 
			
		||||
@ -114,6 +120,8 @@ describe Homebrew::CLI::Parser do
 | 
			
		||||
      described_class.new do
 | 
			
		||||
        flag        "--filename=", description: "Name of the file"
 | 
			
		||||
        comma_array "--files",     description: "Comma separated filenames"
 | 
			
		||||
        flag        "--hidden=",      hidden: true
 | 
			
		||||
        comma_array "--hidden-array", hidden: true
 | 
			
		||||
      end
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -130,6 +138,12 @@ describe Homebrew::CLI::Parser do
 | 
			
		||||
      args = parser.parse(["--files=random1.txt,random2.txt"])
 | 
			
		||||
      expect(args.files).to eq %w[random1.txt random2.txt]
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "sets the correct value for hidden flags" do
 | 
			
		||||
      args = parser.parse(["--hidden=foo", "--hidden-array=bar,baz"])
 | 
			
		||||
      expect(args.hidden).to eq "foo"
 | 
			
		||||
      expect(args.hidden_array).to eq %w[bar baz]
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  describe "test short flag options" do
 | 
			
		||||
@ -361,6 +375,13 @@ describe Homebrew::CLI::Parser do
 | 
			
		||||
      expect(parser.generate_help_text).to match(/\[--foo=\]/)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "does not include hidden options" do
 | 
			
		||||
      parser = described_class.new do
 | 
			
		||||
        switch "--foo", hidden: true
 | 
			
		||||
      end
 | 
			
		||||
      expect(parser.generate_help_text).not_to match(/\[--foo\]/)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "doesn't include `[options]` if non non-global options are available" do
 | 
			
		||||
      parser = described_class.new
 | 
			
		||||
      expect(parser.generate_help_text).not_to match(/\[options\]/)
 | 
			
		||||
 | 
			
		||||
@ -298,7 +298,6 @@ _brew_abv() {
 | 
			
		||||
      __brewcomp "
 | 
			
		||||
      --all
 | 
			
		||||
      --analytics
 | 
			
		||||
      --bottle
 | 
			
		||||
      --cask
 | 
			
		||||
      --category
 | 
			
		||||
      --days
 | 
			
		||||
@ -996,7 +995,6 @@ _brew_info() {
 | 
			
		||||
      __brewcomp "
 | 
			
		||||
      --all
 | 
			
		||||
      --analytics
 | 
			
		||||
      --bottle
 | 
			
		||||
      --cask
 | 
			
		||||
      --category
 | 
			
		||||
      --days
 | 
			
		||||
 | 
			
		||||
@ -293,7 +293,6 @@ __fish_brew_complete_arg '-S' -l verbose -d 'Make some output more verbose'
 | 
			
		||||
__fish_brew_complete_cmd 'abv' 'Display brief statistics for your Homebrew installation'
 | 
			
		||||
__fish_brew_complete_arg 'abv' -l all -d 'Print JSON of all available formulae'
 | 
			
		||||
__fish_brew_complete_arg 'abv' -l analytics -d 'List global Homebrew analytics data or, if specified, installation and build error data for formula (provided neither `HOMEBREW_NO_ANALYTICS` nor `HOMEBREW_NO_GITHUB_API` are set)'
 | 
			
		||||
__fish_brew_complete_arg 'abv' -l bottle -d 'Output information about the bottles for formula and its dependencies'
 | 
			
		||||
__fish_brew_complete_arg 'abv' -l cask -d 'Treat all named arguments as casks'
 | 
			
		||||
__fish_brew_complete_arg 'abv' -l category -d 'Which type of analytics data to retrieve. The value for category must be `install`, `install-on-request` or `build-error`; `cask-install` or `os-version` may be specified if formula is not. The default is `install`'
 | 
			
		||||
__fish_brew_complete_arg 'abv' -l days -d 'How many days of analytics data to retrieve. The value for days must be `30`, `90` or `365`. The default is `30`'
 | 
			
		||||
@ -716,7 +715,6 @@ __fish_brew_complete_arg 'homepage; and not __fish_seen_argument -l formula -l f
 | 
			
		||||
__fish_brew_complete_cmd 'info' 'Display brief statistics for your Homebrew installation'
 | 
			
		||||
__fish_brew_complete_arg 'info' -l all -d 'Print JSON of all available formulae'
 | 
			
		||||
__fish_brew_complete_arg 'info' -l analytics -d 'List global Homebrew analytics data or, if specified, installation and build error data for formula (provided neither `HOMEBREW_NO_ANALYTICS` nor `HOMEBREW_NO_GITHUB_API` are set)'
 | 
			
		||||
__fish_brew_complete_arg 'info' -l bottle -d 'Output information about the bottles for formula and its dependencies'
 | 
			
		||||
__fish_brew_complete_arg 'info' -l cask -d 'Treat all named arguments as casks'
 | 
			
		||||
__fish_brew_complete_arg 'info' -l category -d 'Which type of analytics data to retrieve. The value for category must be `install`, `install-on-request` or `build-error`; `cask-install` or `os-version` may be specified if formula is not. The default is `install`'
 | 
			
		||||
__fish_brew_complete_arg 'info' -l days -d 'How many days of analytics data to retrieve. The value for days must be `30`, `90` or `365`. The default is `30`'
 | 
			
		||||
 | 
			
		||||
@ -372,7 +372,6 @@ _brew_abv() {
 | 
			
		||||
  _arguments \
 | 
			
		||||
    '(--installed)--all[Print JSON of all available formulae]' \
 | 
			
		||||
    '(--bottle)--analytics[List global Homebrew analytics data or, if specified, installation and build error data for formula (provided neither `HOMEBREW_NO_ANALYTICS` nor `HOMEBREW_NO_GITHUB_API` are set)]' \
 | 
			
		||||
    '(--cask --analytics --github)--bottle[Output information about the bottles for formula and its dependencies]' \
 | 
			
		||||
    '--category[Which type of analytics data to retrieve. The value for category must be `install`, `install-on-request` or `build-error`; `cask-install` or `os-version` may be specified if formula is not. The default is `install`]' \
 | 
			
		||||
    '--days[How many days of analytics data to retrieve. The value for days must be `30`, `90` or `365`. The default is `30`]' \
 | 
			
		||||
    '--debug[Display any debugging information]' \
 | 
			
		||||
@ -892,7 +891,6 @@ _brew_info() {
 | 
			
		||||
  _arguments \
 | 
			
		||||
    '(--installed)--all[Print JSON of all available formulae]' \
 | 
			
		||||
    '(--bottle)--analytics[List global Homebrew analytics data or, if specified, installation and build error data for formula (provided neither `HOMEBREW_NO_ANALYTICS` nor `HOMEBREW_NO_GITHUB_API` are set)]' \
 | 
			
		||||
    '(--cask --analytics --github)--bottle[Output information about the bottles for formula and its dependencies]' \
 | 
			
		||||
    '--category[Which type of analytics data to retrieve. The value for category must be `install`, `install-on-request` or `build-error`; `cask-install` or `os-version` may be specified if formula is not. The default is `install`]' \
 | 
			
		||||
    '--days[How many days of analytics data to retrieve. The value for days must be `30`, `90` or `365`. The default is `30`]' \
 | 
			
		||||
    '--debug[Display any debugging information]' \
 | 
			
		||||
 | 
			
		||||
@ -267,8 +267,6 @@ If a *`formula`* or *`cask`* is provided, show summary of information about it.
 | 
			
		||||
  Open the GitHub source page for *`formula`* in a browser. To view formula history locally: `brew log -p` *`formula`*
 | 
			
		||||
* `--json`:
 | 
			
		||||
  Print a JSON representation. Currently the default value for *`version`* is `v1` for *`formula`*. For *`formula`* and *`cask`* use `v2`. See the docs for examples of using the JSON output: <https://docs.brew.sh/Querying-Brew>
 | 
			
		||||
* `--bottle`:
 | 
			
		||||
  Output information about the bottles for *`formula`* and its dependencies.
 | 
			
		||||
* `--installed`:
 | 
			
		||||
  Print JSON of formulae that are currently installed.
 | 
			
		||||
* `--all`:
 | 
			
		||||
 | 
			
		||||
@ -343,10 +343,6 @@ Open the GitHub source page for \fIformula\fR in a browser\. To view formula his
 | 
			
		||||
Print a JSON representation\. Currently the default value for \fIversion\fR is \fBv1\fR for \fIformula\fR\. For \fIformula\fR and \fIcask\fR use \fBv2\fR\. See the docs for examples of using the JSON output: \fIhttps://docs\.brew\.sh/Querying\-Brew\fR
 | 
			
		||||
.
 | 
			
		||||
.TP
 | 
			
		||||
\fB\-\-bottle\fR
 | 
			
		||||
Output information about the bottles for \fIformula\fR and its dependencies\.
 | 
			
		||||
.
 | 
			
		||||
.TP
 | 
			
		||||
\fB\-\-installed\fR
 | 
			
		||||
Print JSON of formulae that are currently installed\.
 | 
			
		||||
.
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user