File: puppet_option_parser.rb

package info (click to toggle)
puppet-agent 8.10.0-6
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 27,404 kB
  • sloc: ruby: 286,820; sh: 492; xml: 116; makefile: 88; cs: 68
file content (89 lines) | stat: -rw-r--r-- 3,186 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# frozen_string_literal: true

require_relative '../../../puppet/util/command_line/trollop'

module Puppet
  module Util
    class CommandLine
      class PuppetOptionError < Puppet::Error
      end

      class TrollopCommandlineError < Puppet::Util::CommandLine::Trollop::CommandlineError; end

      # This is a command line option parser.  It is intended to have an API that is very similar to
      #  the ruby stdlib 'OptionParser' API, for ease of integration into our existing code... however,
      #  However, we've removed the OptionParser-based implementation and are only maintaining the
      #  it's implemented based on the third-party "trollop" library.  This was done because there
      #  are places where the stdlib OptionParser is not flexible enough to meet our needs.

      class PuppetOptionParser
        def initialize(usage_msg = nil)
          require_relative '../../../puppet/util/command_line/trollop'

          @create_default_short_options = false

          @parser = Trollop::Parser.new do
            banner usage_msg
          end
        end

        # This parameter, if set, will tell the underlying option parser not to throw an
        #  exception if we pass it options that weren't explicitly registered.  We need this
        #  capability because we need to be able to pass all of the command-line options before
        #  we know which application/face they are going to be running, but the app/face
        #  may specify additional command-line arguments that are valid for that app/face.
        attr_reader :ignore_invalid_options

        def ignore_invalid_options=(value)
          @parser.ignore_invalid_options = value
        end

        def on(*args, &block)
          # The 2nd element is an optional "short" representation.
          case args.length
          when 3
            long, desc, type = args
          when 4
            long, short, desc, type = args
          else
            raise ArgumentError, _("this method only takes 3 or 4 arguments. Given: %{args}") % { args: args.inspect }
          end

          options = {
            :long => long,
            :short => short,
            :required => false,
            :callback => pass_only_last_value_on_to(block),
            :multi => true,
          }

          case type
          when :REQUIRED
            options[:type] = :string
          when :NONE
            options[:type] = :flag
          else
            raise PuppetOptionError, _("Unsupported type: '%{type}'") % { type: type }
          end

          @parser.opt long.sub("^--", "").intern, desc, options
        end

        def parse(*args)
          args = args[0] if args.size == 1 and args[0].is_a?(Array)
          args_copy = args.dup
          begin
            @parser.parse args_copy
          rescue Puppet::Util::CommandLine::Trollop::CommandlineError => err
            raise PuppetOptionError.new(_("Error parsing arguments"), err)
          end
        end

        def pass_only_last_value_on_to(block)
          ->(values) { block.call(values.is_a?(Array) ? values.last : values) }
        end
        private :pass_only_last_value_on_to
      end
    end
  end
end