ame 0.1.1 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (90) hide show
  1. checksums.yaml +7 -0
  2. data/README +541 -3
  3. data/Rakefile +15 -6
  4. data/lib/ame-1.0.rb +31 -0
  5. data/lib/ame-1.0/argument.rb +63 -0
  6. data/lib/ame-1.0/arguments.rb +44 -0
  7. data/lib/ame-1.0/arguments/complete.rb +37 -0
  8. data/lib/ame-1.0/arguments/optional.rb +34 -0
  9. data/lib/ame-1.0/arguments/undefined.rb +71 -0
  10. data/lib/ame-1.0/class.rb +436 -0
  11. data/lib/ame-1.0/flag.rb +101 -0
  12. data/lib/{ame → ame-1.0}/help.rb +1 -1
  13. data/lib/ame-1.0/help/delegate.rb +19 -0
  14. data/lib/ame-1.0/help/terminal.rb +132 -0
  15. data/lib/ame-1.0/method.rb +75 -0
  16. data/lib/ame-1.0/method/undefined.rb +184 -0
  17. data/lib/ame-1.0/methods.rb +40 -0
  18. data/lib/ame-1.0/multioption.rb +36 -0
  19. data/lib/ame-1.0/option.rb +37 -0
  20. data/lib/ame-1.0/optional.rb +31 -0
  21. data/lib/ame-1.0/options.rb +68 -0
  22. data/lib/ame-1.0/options/undefined.rb +114 -0
  23. data/lib/ame-1.0/root.rb +174 -0
  24. data/lib/ame-1.0/splat.rb +16 -0
  25. data/lib/ame-1.0/splus.rb +22 -0
  26. data/lib/ame-1.0/switch.rb +39 -0
  27. data/lib/ame-1.0/types.rb +60 -0
  28. data/lib/ame-1.0/types/boolean.rb +13 -0
  29. data/lib/ame-1.0/types/enumeration.rb +40 -0
  30. data/lib/ame-1.0/types/float.rb +11 -0
  31. data/lib/{ame → ame-1.0}/types/integer.rb +3 -3
  32. data/lib/{ame → ame-1.0}/types/string.rb +2 -2
  33. data/lib/ame-1.0/types/symbol.rb +9 -0
  34. data/lib/ame-1.0/version.rb +62 -0
  35. data/test/unit/ame-1.0.rb +4 -0
  36. data/test/unit/ame-1.0/argument.rb +46 -0
  37. data/test/unit/ame-1.0/arguments.rb +63 -0
  38. data/test/unit/ame-1.0/arguments/complete.rb +4 -0
  39. data/test/unit/ame-1.0/arguments/optional.rb +4 -0
  40. data/test/unit/ame-1.0/arguments/undefined.rb +63 -0
  41. data/test/unit/ame-1.0/class.rb +4 -0
  42. data/test/unit/ame-1.0/flag.rb +31 -0
  43. data/test/unit/ame-1.0/help.rb +4 -0
  44. data/test/unit/ame-1.0/help/delegate.rb +4 -0
  45. data/test/unit/{ame/help/console.rb → ame-1.0/help/terminal.rb} +34 -23
  46. data/test/unit/ame-1.0/method.rb +4 -0
  47. data/test/unit/ame-1.0/method/undefined.rb +33 -0
  48. data/test/unit/ame-1.0/methods.rb +9 -0
  49. data/test/unit/ame-1.0/multioption.rb +4 -0
  50. data/test/unit/ame-1.0/option.rb +11 -0
  51. data/test/unit/ame-1.0/optional.rb +9 -0
  52. data/test/unit/ame-1.0/options.rb +149 -0
  53. data/test/unit/ame-1.0/options/undefined.rb +33 -0
  54. data/test/unit/ame-1.0/root.rb +4 -0
  55. data/test/unit/ame-1.0/splat.rb +9 -0
  56. data/test/unit/ame-1.0/splus.rb +4 -0
  57. data/test/unit/ame-1.0/switch.rb +15 -0
  58. data/test/unit/ame-1.0/types.rb +4 -0
  59. data/test/{ame → unit/ame-1.0}/types/boolean.rb +0 -0
  60. data/test/unit/ame-1.0/types/enumeration.rb +4 -0
  61. data/test/unit/ame-1.0/types/float.rb +7 -0
  62. data/test/{ame → unit/ame-1.0}/types/integer.rb +0 -0
  63. data/test/{ame → unit/ame-1.0}/types/string.rb +0 -0
  64. data/test/unit/ame-1.0/types/symbol.rb +5 -0
  65. data/test/unit/ame-1.0/version.rb +4 -0
  66. metadata +690 -60
  67. data/lib/ame.rb +0 -26
  68. data/lib/ame/argument.rb +0 -56
  69. data/lib/ame/arguments.rb +0 -65
  70. data/lib/ame/class.rb +0 -117
  71. data/lib/ame/help/console.rb +0 -96
  72. data/lib/ame/method.rb +0 -94
  73. data/lib/ame/methods.rb +0 -30
  74. data/lib/ame/option.rb +0 -50
  75. data/lib/ame/options.rb +0 -102
  76. data/lib/ame/root.rb +0 -57
  77. data/lib/ame/splat.rb +0 -12
  78. data/lib/ame/types.rb +0 -29
  79. data/lib/ame/types/array.rb +0 -16
  80. data/lib/ame/types/boolean.rb +0 -16
  81. data/lib/ame/version.rb +0 -5
  82. data/test/ame/types/array.rb +0 -13
  83. data/test/unit/ame/argument.rb +0 -66
  84. data/test/unit/ame/arguments.rb +0 -106
  85. data/test/unit/ame/method.rb +0 -40
  86. data/test/unit/ame/methods.rb +0 -10
  87. data/test/unit/ame/option.rb +0 -75
  88. data/test/unit/ame/options.rb +0 -136
  89. data/test/unit/ame/root.rb +0 -15
  90. data/test/unit/ame/splat.rb +0 -11
@@ -0,0 +1,40 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ # Stores {Methods#each #each} {Method} defined on a {Class}.
4
+ # @api developer
5
+ class Ame::Methods
6
+ include Enumerable
7
+
8
+ def initialize
9
+ @methods = {}
10
+ end
11
+
12
+ # Adds METHOD to the receiver
13
+ # @param [Method] method
14
+ # @return [self]
15
+ def <<(method)
16
+ @methods[method.name] = method
17
+ self
18
+ end
19
+
20
+ # @return [Method] The method NAME in the receiver
21
+ # @raise [UnrecognizedMethod] If NAME isn’t a method in the receiver
22
+ def [](name)
23
+ @methods[name] or
24
+ raise Ame::UnrecognizedMethod, 'unrecognized method: %s' % name
25
+ end
26
+
27
+ # @overload
28
+ # Enumerates the methods.
29
+ #
30
+ # @yieldparam [Method] option
31
+ # @overload
32
+ # @return [Enumerator<Method>] An Enumerator over the methods
33
+ def each
34
+ return enum_for(__method__) unless block_given?
35
+ @methods.each_value do |method|
36
+ yield method
37
+ end
38
+ self
39
+ end
40
+ end
@@ -0,0 +1,36 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ # Represents an option to a {Method} that takes an argument that can be given
4
+ # any number of times. If an explicit (‘=’-separated) argument is given, it’ll
5
+ # be used, otherwise the following argument will be used.
6
+ # @api developer
7
+ class Ame::Multioption < Ame::Option
8
+ # @api internal
9
+ # @param (see Option#initialize)
10
+ # @param [::Class] type
11
+ # @yield (see Option#initialize)
12
+ # @yieldparam (see Option#initialize)
13
+ # @raise (see Flag#initialize)
14
+ # @raise [ArgumentError] If TYPE isn’t one that Ame knows how to parse
15
+ def initialize(short, long, argument, type, description, &validate)
16
+ super short, long, argument, nil, description, &validate
17
+ @type = Ame::Types[type]
18
+ @ignored = true
19
+ end
20
+
21
+ # Invokes {super} and adds it to an Array added to OPTIONS before returning
22
+ # it.
23
+ # @api internal
24
+ # @param (see Flag#process)
25
+ # @raise (see Flag#process)
26
+ # @return [Object]
27
+ def process(options, arguments, name, explicit)
28
+ @ignored = false
29
+ (options[self.name] ||= []) << super
30
+ end
31
+
32
+ # @return True if the receiver hasn’t been asked to process any options yet
33
+ def ignored?
34
+ @ignored
35
+ end
36
+ end
@@ -0,0 +1,37 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ # Represents an option to a {Method} that takes an argument. If an explicit
4
+ # (‘=’-separated) argument is given, it’ll be used, otherwise the following
5
+ # argument will be used.
6
+ # @api developer
7
+ class Ame::Option < Ame::Switch
8
+ # @api internal
9
+ # @param (see Switch#initialize)
10
+ # @yield (see Switch#initialize)
11
+ # @yieldparam (see Switch#initialize)
12
+ # @raise (see Flag#initialize)
13
+ # @raise [ArgumentError] If the type of DEFAULT isn’t one that Ame knows how
14
+ # to parse
15
+ def initialize(short, long, argument, default, description, &validate)
16
+ super short, long, argument, default, nil, description, &validate
17
+ end
18
+
19
+ # Invokes {Flag#process} with REMAINDER as the explicit argument if it’s
20
+ # non-empty.
21
+ # @api internal
22
+ # @param (see Flag#process_combined)
23
+ # @return [[Boolean, '']]
24
+ def process_combined(options, arguments, name, remainder)
25
+ [process(options, arguments, name, remainder.empty? ? nil : remainder), '']
26
+ end
27
+
28
+ private
29
+
30
+ # @api internal
31
+ # @param (see Flag#parse)
32
+ # @return [Object] The parsed value of EXPLICIT, if non-nil, the next argument otherwise
33
+ # @raise [MissingArgument] If EXPLICIT is nil and there are no more arguments
34
+ def parse(arguments, explicit)
35
+ @type.parse(explicit || arguments.shift || raise(Ame::MissingArgument, 'missing argument: %s' % self))
36
+ end
37
+ end
@@ -0,0 +1,31 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ # Represents an optional argument to a {Method}. It has a {#default} value
4
+ # that will be used if no more arguments are available when it gets called upon
5
+ # to process an argument before the method this argument is associated with
6
+ # gets called.
7
+ # @api developer
8
+ class Ame::Optional < Ame::Argument
9
+ # @api internal
10
+ # @param (see Argument#initialize)
11
+ # @param [Object] default
12
+ # @yield (see Argument#initialize)
13
+ # @yieldparam (see Argument#initialize)
14
+ # @raise [ArgumentError] If the type of DEFAULT isn’t one that Ame knows how
15
+ # to parse
16
+ def initialize(name, default, description, &validate)
17
+ @default = default
18
+ super
19
+ end
20
+
21
+ # @return [Object, nil] The default value of the receiver
22
+ attr_reader :default
23
+
24
+ private
25
+
26
+ # @api internal
27
+ # @return [Object] {#default} if ARGUMENTS#empty?, {super} otherwise
28
+ def parse(arguments)
29
+ arguments.empty? ? default : super
30
+ end
31
+ end
@@ -0,0 +1,68 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ # The options to a method in its {Method defined state}. Does the processing
4
+ # of options to the method and also enumerates {#each} of the options to the
5
+ # method for, for example, help output.
6
+ # @api developer
7
+ class Ame::Options
8
+ include Enumerable
9
+
10
+ def initialize(options, ordered, options_must_precede_arguments)
11
+ @options, @ordered, @options_must_precede_arguments =
12
+ options, ordered, options_must_precede_arguments
13
+ end
14
+
15
+ # @api internal
16
+ # @param [Array<String>] arguments
17
+ # @raise [UnrecognizedOption] If an unrecognized option has been given
18
+ # @raise (see Flag#process)
19
+ # @return [[Hash<String,Object>, Array<String>]] The {Flag#process}ed options
20
+ # as a Hash mapping the {Flag#name} to the parsed value or the option’s
21
+ # default after filtering out any {Flag#ignored?} options and the remaining
22
+ # non-option arguments
23
+ def process(arguments)
24
+ arguments = arguments.dup
25
+ results = @ordered.reduce({}){ |d, o| d[o.name] = o.default; d }
26
+ remainder = []
27
+ until arguments.empty?
28
+ case first = arguments.shift
29
+ when '--'
30
+ break
31
+ when /\A-([^=-]{2,})\z/
32
+ combined = $1
33
+ until combined.empty?
34
+ option = self['-' + combined[0].chr]
35
+ results[option.name], combined = option.process_combined(results, arguments, $1, combined[1..-1])
36
+ end
37
+ when /\A(--[^=]+|-[^-])(?:=(.*))?\z/
38
+ option = self[$1]
39
+ results[option.name] = option.process(results, arguments, $1, $2)
40
+ else
41
+ remainder << first
42
+ break if @options_must_precede_arguments
43
+ end
44
+ end
45
+ [results.reject{ |n, _| self[n].ignored? }, remainder.concat(arguments)]
46
+ end
47
+
48
+ # @overload
49
+ # Enumerates the options.
50
+ #
51
+ # @yieldparam [Option] option
52
+ # @overload
53
+ # @return [Enumerator<Option>] An Enumerator over the options
54
+ def each
55
+ return enum_for(__method__) unless block_given?
56
+ @ordered.each do |option|
57
+ yield option
58
+ end
59
+ self
60
+ end
61
+
62
+ private
63
+
64
+ def [](name)
65
+ @options[name.sub(/\A-+/, '')] or
66
+ raise Ame::UnrecognizedOption, 'unrecognized option: %s' % name
67
+ end
68
+ end
@@ -0,0 +1,114 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ # The options to a method in its {Method::Undefined undefined state}.
4
+ # @api internal
5
+ class Ame::Options::Undefined
6
+ def initialize
7
+ @options = {}
8
+ @ordered = []
9
+ @options_must_precede_arguments = ENV.include? 'POSIXLY_CORRECT'
10
+ end
11
+
12
+ # Forces options to the method about to be defined to precede any arguments,
13
+ # lest they be seen as arguments. If not given, the behaviour will depend on
14
+ # whether `ENV['POSIXLY_CORRECT']` has been set or not.
15
+ # @return [self]
16
+ def options_must_precede_arguments
17
+ @options_must_precede_arguments = true
18
+ self
19
+ end
20
+
21
+ # Adds a new {Flag} to the receiver.
22
+ # @param (see Flag#initialize)
23
+ # @yield (see Flag#initialize)
24
+ # @yieldparam (see Flag#initialize)
25
+ # @raise (see Flag#initialize)
26
+ # @raise [ArgumentError] If SHORT or LONG have already been defined
27
+ # @return [self]
28
+ def flag(short, long, default, description, &validate)
29
+ self << Ame::Flag.new(short, long, default, description, &validate)
30
+ end
31
+
32
+ # Adds a new {Flag} to the receiver. Also adds a `--no-LONG` flag that’s the
33
+ # inverse of this flag.
34
+ # @param (see Flag#initialize)
35
+ # @yield (see Flag#initialize)
36
+ # @yieldparam (see Flag#initialize)
37
+ # @raise (see Flag#initialize)
38
+ # @raise [ArgumentError] If LONG is #strip#empty?
39
+ # @raise [ArgumentError] If SHORT or LONG have already been defined
40
+ # @return [self]
41
+ def toggle(short, long, default, description, &validate)
42
+ flag = Ame::Flag.new(short, long, default, description, &validate)
43
+ raise ArgumentError, 'long can’t be empty' if flag.long.empty?
44
+ self << flag
45
+ add(Ame::Flag.new('', 'no-%s' % flag.long, nil, description){ |options, argument|
46
+ options[flag.name] = validate ? validate.call(options, !argument) : !argument
47
+ })
48
+ end
49
+
50
+ # Adds a new {Switch} to the receiver.
51
+ # @param (see Switch#initialize)
52
+ # @yield (see Switch#initialize)
53
+ # @yieldparam (see Switch#initialize)
54
+ # @raise (see Switch#initialize)
55
+ # @raise [ArgumentError] If SHORT or LONG have already been defined
56
+ # @return [self]
57
+ def switch(short, long, argument, default, argument_default, description, &validate)
58
+ self << Ame::Switch.new(short, long, argument, default, argument_default, description, &validate)
59
+ end
60
+
61
+ # Adds a new {Option} to the receiver.
62
+ # @param (see Option#initialize)
63
+ # @yield (see Option#initialize)
64
+ # @yieldparam (see Option#initialize)
65
+ # @raise (see Option#initialize)
66
+ # @raise [ArgumentError] If SHORT or LONG have already been defined
67
+ # @return [self]
68
+ def option(short, long, argument, default, description, &validate)
69
+ self << Ame::Option.new(short, long, argument, default, description, &validate)
70
+ end
71
+
72
+ # Adds a new {Multioption} to the receiver.
73
+ # @param (see Multioption#initialize)
74
+ # @yield (see Multioption#initialize)
75
+ # @yieldparam (see Multioption#initialize)
76
+ # @raise (see Multioption#initialize)
77
+ # @raise [ArgumentError] If SHORT or LONG have already been defined
78
+ # @return [self]
79
+ def multioption(short, long, argument, type, description, &validate)
80
+ self << Ame::Multioption.new(short, long, argument, type, description, &validate)
81
+ end
82
+
83
+ # @param [String] name
84
+ # @return True if the receiver has any kind of option named NAME
85
+ def include?(name)
86
+ @options.include? name
87
+ end
88
+
89
+ # @return [Options] The defined version of the receiver
90
+ def define
91
+ Ame::Options.new(@options, @ordered, @options_must_precede_arguments)
92
+ end
93
+
94
+ protected
95
+
96
+ def <<(option)
97
+ @ordered << option
98
+ add(option)
99
+ end
100
+
101
+ private
102
+
103
+ def add(option)
104
+ option.names.each do |name|
105
+ self[name] = option
106
+ end
107
+ self
108
+ end
109
+
110
+ def []=(name, option)
111
+ raise ArgumentError, 'option already defined: %s' % name if include? name
112
+ @options[name] = option
113
+ end
114
+ end
@@ -0,0 +1,174 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ # Root of a hierarchy of {Class}es. This class should be subclassed by the
4
+ # root of your command-line interface.
5
+ # @example An rm-like Command-line Interface with Ame
6
+ # class Rm < Ame::Root
7
+ # version '1.0.0'
8
+ #
9
+ # flag 'f', '', false, 'Do not prompt for confirmation'
10
+ # flag 'i', '', nil, 'Prompt for confirmation' do |options|
11
+ # options['f'] = false
12
+ # end
13
+ # flag 'R', '', false, 'Remove file hierarchies'
14
+ # flag 'r', '', nil, 'Equivalent to -R' do |options|
15
+ # options['r'] = true
16
+ # end
17
+ # splus 'FILE', String, 'File to remove'
18
+ # description 'Remove directory entries'
19
+ # def rm(files, options = {})
20
+ # require 'fileutils'
21
+ # FileUtils.send options['R'] ? :rm_r : :rm,
22
+ # [first] + rest, :force => options['f']
23
+ # end
24
+ # end
25
+ # Rm.process
26
+ # @example A Git-like Command-line Interface With Ame
27
+ # module Git end
28
+ # class Git::CLI < Ame::Root
29
+ # version '1.0.0'
30
+ # class Git < Ame::Class
31
+ # description 'The stupid content tracker'
32
+ # def initialize; end
33
+ #
34
+ # description 'Prepare patches for e-mail submission'
35
+ # flag ?n, 'numbered', false, 'Name output in [PATCH n/m] format'
36
+ # flag ?N, 'no-numbered', nil,
37
+ # 'Name output in [PATCH] format' do |options|
38
+ # options['numbered'] = false
39
+ # end
40
+ # toggle ?s, 'signoff', false,
41
+ # 'Add Signed-off-by: line to the commit message'
42
+ # switch '', 'thread', 'STYLE', nil,
43
+ # Ame::Types::Enumeration[:shallow, :deep],
44
+ # 'Controls addition of In-Reply-To and References headers'
45
+ # flag '', 'no-thread', nil,
46
+ # 'Disables addition of In-Reply-To and Reference headers' do |options, _|
47
+ # options.delete 'thread'
48
+ # end
49
+ # option '', 'start-number', 'N', 1,
50
+ # 'Start numbering the patches at N instead of 1'
51
+ # multioption '', 'to', 'ADDRESS', String,
52
+ # 'Add a To: header to the email headers'
53
+ # optional 'SINCE', 'N/A', 'Generate patches for commits after SINCE'
54
+ # def format_patch(since = '', options = {})
55
+ # p since, options
56
+ # end
57
+ #
58
+ # description 'Annotate file lines with commit information'
59
+ # argument 'FILE', String, 'File to annotate'
60
+ # def annotate(file)
61
+ # p file
62
+ # end
63
+ #
64
+ # description 'Add file contents to the index'
65
+ # splat 'PATHSPEC', String, 'Files to add content from'
66
+ # def add(paths)
67
+ # p paths
68
+ # end
69
+ #
70
+ # description 'Display gitattributes information'
71
+ # splus 'PATHNAME', String, 'Files to list attributes of'
72
+ # def check_attr(paths)
73
+ # p paths
74
+ # end
75
+ #
76
+ # class Remote < Ame::Class
77
+ # description 'Manage set of remote repositories'
78
+ # def initialize; end
79
+ #
80
+ # description 'Shows a list of existing remotes'
81
+ # flag 'v', 'verbose', false, 'Show remote URL after name'
82
+ # def list(options = {})
83
+ # p options
84
+ # end
85
+ #
86
+ # description 'Adds a remote named NAME for the repository at URL'
87
+ # argument 'name', String, 'Name of the remote to add'
88
+ # argument 'url', String, 'URL to the repository of the remote to add'
89
+ # def add(name, url)
90
+ # p name, url
91
+ # end
92
+ # end
93
+ # dispatch Remote, :default => 'list'
94
+ # end
95
+ # dispatch Git
96
+ # end
97
+ # Git::CLI.process
98
+ class Ame::Root < Ame::Class
99
+ class << self
100
+ # Sets the HELP object to use for displaying usage information, or returns
101
+ # it if HELP is nil. The default is to use a {Help::Terminal} object.
102
+ # @param (see Class.help)
103
+ # @return [#method, #dispatch, #error, #version]
104
+ def help(help = nil)
105
+ super if help
106
+ @help ||= Ame::Help::Terminal.new
107
+ end
108
+
109
+ # Sets or returns, depending on if VERSION is nil or not, the version of
110
+ # the receiver. The version may be used by {.help} to output version
111
+ # information.
112
+ # @param [String, nil] version
113
+ # @return [String]
114
+ def version(version = nil)
115
+ return @version = version if version
116
+ @version
117
+ end
118
+
119
+ # Process ARGUMENTS as a list of options and arguments, then call METHOD
120
+ # with the results of this processing on a new instance of the receiver.
121
+ # This method catches {AbortAllProcessing}. Any errors will be caught and
122
+ # reported using {.help}#error.
123
+ # @param (see Class.process)
124
+ # @return [self]
125
+ def process(method = File.basename($0), arguments = ARGV)
126
+ catch Ame::AbortAllProcessing do
127
+ super
128
+ end
129
+ self
130
+ rescue => e
131
+ help.error method, e
132
+ end
133
+
134
+ # Call METHOD with ARGUMENTS and OPTIONS on a new instance of the receiver.
135
+ # This method catches {AbortAllProcessing}.
136
+ # @param (see Class.call)
137
+ # @raise (see Class.call)
138
+ # @return [self]
139
+ def call(method, arguments = nil, options = nil)
140
+ catch Ame::AbortAllProcessing do
141
+ super
142
+ end
143
+ self
144
+ end
145
+
146
+ # @api developer
147
+ # @return [String] An empty string
148
+ def basename
149
+ ''
150
+ end
151
+
152
+ private
153
+
154
+ # Defines the previously undefined {.method} now that it’s been added to
155
+ # the class after adding flag “version” that’ll call {.help}#version to
156
+ # output version information and then throw {AbortAllProcessing}.
157
+ # @api internal
158
+ # @param (see Class.method_added)
159
+ # @raise (see Class.method_added)
160
+ # @raise [ArgumentError] If {.version} hasn’t been set
161
+ # @return [self]
162
+ def method_added(ruby_name)
163
+ unless method.option? 'version'
164
+ raise ArgumentError, 'version not set, set it with version VERSION', caller unless defined? @version
165
+ flag '', 'version', nil, 'Display version information' do
166
+ help.version methods[Ame::Method.name(ruby_name)], self.version
167
+ throw Ame::AbortAllProcessing
168
+ end
169
+ end
170
+ super
171
+ rescue; $!.set_backtrace(caller[1..-1]); raise
172
+ end
173
+ end
174
+ end