ame 0.1.1 → 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|