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.
- checksums.yaml +7 -0
- data/README +541 -3
- data/Rakefile +15 -6
- data/lib/ame-1.0.rb +31 -0
- data/lib/ame-1.0/argument.rb +63 -0
- data/lib/ame-1.0/arguments.rb +44 -0
- data/lib/ame-1.0/arguments/complete.rb +37 -0
- data/lib/ame-1.0/arguments/optional.rb +34 -0
- data/lib/ame-1.0/arguments/undefined.rb +71 -0
- data/lib/ame-1.0/class.rb +436 -0
- data/lib/ame-1.0/flag.rb +101 -0
- data/lib/{ame → ame-1.0}/help.rb +1 -1
- data/lib/ame-1.0/help/delegate.rb +19 -0
- data/lib/ame-1.0/help/terminal.rb +132 -0
- data/lib/ame-1.0/method.rb +75 -0
- data/lib/ame-1.0/method/undefined.rb +184 -0
- data/lib/ame-1.0/methods.rb +40 -0
- data/lib/ame-1.0/multioption.rb +36 -0
- data/lib/ame-1.0/option.rb +37 -0
- data/lib/ame-1.0/optional.rb +31 -0
- data/lib/ame-1.0/options.rb +68 -0
- data/lib/ame-1.0/options/undefined.rb +114 -0
- data/lib/ame-1.0/root.rb +174 -0
- data/lib/ame-1.0/splat.rb +16 -0
- data/lib/ame-1.0/splus.rb +22 -0
- data/lib/ame-1.0/switch.rb +39 -0
- data/lib/ame-1.0/types.rb +60 -0
- data/lib/ame-1.0/types/boolean.rb +13 -0
- data/lib/ame-1.0/types/enumeration.rb +40 -0
- data/lib/ame-1.0/types/float.rb +11 -0
- data/lib/{ame → ame-1.0}/types/integer.rb +3 -3
- data/lib/{ame → ame-1.0}/types/string.rb +2 -2
- data/lib/ame-1.0/types/symbol.rb +9 -0
- data/lib/ame-1.0/version.rb +62 -0
- data/test/unit/ame-1.0.rb +4 -0
- data/test/unit/ame-1.0/argument.rb +46 -0
- data/test/unit/ame-1.0/arguments.rb +63 -0
- data/test/unit/ame-1.0/arguments/complete.rb +4 -0
- data/test/unit/ame-1.0/arguments/optional.rb +4 -0
- data/test/unit/ame-1.0/arguments/undefined.rb +63 -0
- data/test/unit/ame-1.0/class.rb +4 -0
- data/test/unit/ame-1.0/flag.rb +31 -0
- data/test/unit/ame-1.0/help.rb +4 -0
- data/test/unit/ame-1.0/help/delegate.rb +4 -0
- data/test/unit/{ame/help/console.rb → ame-1.0/help/terminal.rb} +34 -23
- data/test/unit/ame-1.0/method.rb +4 -0
- data/test/unit/ame-1.0/method/undefined.rb +33 -0
- data/test/unit/ame-1.0/methods.rb +9 -0
- data/test/unit/ame-1.0/multioption.rb +4 -0
- data/test/unit/ame-1.0/option.rb +11 -0
- data/test/unit/ame-1.0/optional.rb +9 -0
- data/test/unit/ame-1.0/options.rb +149 -0
- data/test/unit/ame-1.0/options/undefined.rb +33 -0
- data/test/unit/ame-1.0/root.rb +4 -0
- data/test/unit/ame-1.0/splat.rb +9 -0
- data/test/unit/ame-1.0/splus.rb +4 -0
- data/test/unit/ame-1.0/switch.rb +15 -0
- data/test/unit/ame-1.0/types.rb +4 -0
- data/test/{ame → unit/ame-1.0}/types/boolean.rb +0 -0
- data/test/unit/ame-1.0/types/enumeration.rb +4 -0
- data/test/unit/ame-1.0/types/float.rb +7 -0
- data/test/{ame → unit/ame-1.0}/types/integer.rb +0 -0
- data/test/{ame → unit/ame-1.0}/types/string.rb +0 -0
- data/test/unit/ame-1.0/types/symbol.rb +5 -0
- data/test/unit/ame-1.0/version.rb +4 -0
- metadata +690 -60
- data/lib/ame.rb +0 -26
- data/lib/ame/argument.rb +0 -56
- data/lib/ame/arguments.rb +0 -65
- data/lib/ame/class.rb +0 -117
- data/lib/ame/help/console.rb +0 -96
- data/lib/ame/method.rb +0 -94
- data/lib/ame/methods.rb +0 -30
- data/lib/ame/option.rb +0 -50
- data/lib/ame/options.rb +0 -102
- data/lib/ame/root.rb +0 -57
- data/lib/ame/splat.rb +0 -12
- data/lib/ame/types.rb +0 -29
- data/lib/ame/types/array.rb +0 -16
- data/lib/ame/types/boolean.rb +0 -16
- data/lib/ame/version.rb +0 -5
- data/test/ame/types/array.rb +0 -13
- data/test/unit/ame/argument.rb +0 -66
- data/test/unit/ame/arguments.rb +0 -106
- data/test/unit/ame/method.rb +0 -40
- data/test/unit/ame/methods.rb +0 -10
- data/test/unit/ame/option.rb +0 -75
- data/test/unit/ame/options.rb +0 -136
- data/test/unit/ame/root.rb +0 -15
- 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
|
data/lib/ame-1.0/root.rb
ADDED
@@ -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
|