ultra_command_line 0.4.7
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/.gitignore +14 -0
- data/.rspec +2 -0
- data/.travis.yml +5 -0
- data/Gemfile +4 -0
- data/README.md +36 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/docs/command_definition.puml +160 -0
- data/lib/ultra_command_line.rb +23 -0
- data/lib/ultra_command_line/commands/command_line_parser.rb +34 -0
- data/lib/ultra_command_line/commands/factory.rb +31 -0
- data/lib/ultra_command_line/commands/help_formatter.rb +43 -0
- data/lib/ultra_command_line/commands/main_command.rb +10 -0
- data/lib/ultra_command_line/commands/option_definition.rb +68 -0
- data/lib/ultra_command_line/commands/sub_command.rb +58 -0
- data/lib/ultra_command_line/commands/validation.rb +80 -0
- data/lib/ultra_command_line/error.rb +7 -0
- data/lib/ultra_command_line/manager/base.rb +35 -0
- data/lib/ultra_command_line/manager/cmd_line_args.rb +25 -0
- data/lib/ultra_command_line/manager/commands.rb +67 -0
- data/lib/ultra_command_line/manager/factory.rb +50 -0
- data/lib/ultra_command_line/manager/layered_definition.rb +86 -0
- data/lib/ultra_command_line/manager/processors.rb +75 -0
- data/lib/ultra_command_line/utils/basic_logger.rb +23 -0
- data/lib/ultra_command_line/utils/error_propagation.rb +22 -0
- data/lib/ultra_command_line/utils/yaml_factory.rb +24 -0
- data/lib/ultra_command_line/version.rb +3 -0
- data/ultra_command_line.gemspec +30 -0
- metadata +156 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: b7cd80a8c2740619c3fbba59d3d76fee87f6763c
|
4
|
+
data.tar.gz: ab0a550b07ac26bfeae400c9d0a0002c563efe75
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: c8a55f46171afd5a91ea53301915efb2f5f92f61cc87f91f2c84b7638ffebc5788b49a621c8023282549552ffc146b39f1c0c3d2d2e89f75b88f14682cbc0ff3
|
7
|
+
data.tar.gz: 979c60dffeb59988e17a490064352ee18601fc14a02d9fc4674362077bab055cef6433b760c51268faf0b131763d2454cc9648e90bf125f85b71ca890224ba48
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
UltraCommandLine
|
2
|
+
================
|
3
|
+
|
4
|
+
This gem is basically a wrapper around the `slop` gem which generates slop options from a YAML definition file.
|
5
|
+
This is most probably only used by the `climatic` gem
|
6
|
+
|
7
|
+
|
8
|
+
## Installation
|
9
|
+
|
10
|
+
Add this line to your application's Gemfile:
|
11
|
+
|
12
|
+
```ruby
|
13
|
+
gem 'ultra_command_line'
|
14
|
+
```
|
15
|
+
|
16
|
+
And then execute:
|
17
|
+
|
18
|
+
$ bundle
|
19
|
+
|
20
|
+
Or install it yourself as:
|
21
|
+
|
22
|
+
$ gem install ultra_command_line
|
23
|
+
|
24
|
+
## Usage
|
25
|
+
|
26
|
+
TODO: Write usage instructions here
|
27
|
+
|
28
|
+
## Development
|
29
|
+
|
30
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
31
|
+
|
32
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
33
|
+
|
34
|
+
## Contributing
|
35
|
+
|
36
|
+
Bug reports and pull requests are welcome on GitHub at https://gitlab.com/lbriais/ultra_command_line.
|
data/Rakefile
ADDED
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'bundler/setup'
|
4
|
+
require 'ultra_command_line'
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require 'irb'
|
14
|
+
IRB.start(__FILE__)
|
data/bin/setup
ADDED
@@ -0,0 +1,160 @@
|
|
1
|
+
@startuml
|
2
|
+
|
3
|
+
|
4
|
+
skinparam class {
|
5
|
+
backgroundColor<<module>> LightGray
|
6
|
+
backgroundColor<<external>> Gray
|
7
|
+
}
|
8
|
+
|
9
|
+
set namespaceSeparator ::
|
10
|
+
|
11
|
+
|
12
|
+
namespace Commands {
|
13
|
+
|
14
|
+
class OptionDefinition {
|
15
|
+
Defines one command line option,
|
16
|
+
wrapping around slop features.
|
17
|
+
+{method}:to_slop_options
|
18
|
+
}
|
19
|
+
|
20
|
+
class SubCommand {
|
21
|
+
Represents a a-la-git sub-command
|
22
|
+
..
|
23
|
+
+{field}name
|
24
|
+
}
|
25
|
+
|
26
|
+
class MainCommand << (M, #ADD1B2) module>> {
|
27
|
+
Represents the main command.
|
28
|
+
Basically a Subcommand but
|
29
|
+
with an empty name.
|
30
|
+
..
|
31
|
+
}
|
32
|
+
|
33
|
+
class Factory << (M, #ADD1B2) module>> {
|
34
|
+
How to create a SubCommand from
|
35
|
+
a definition hash.
|
36
|
+
..
|
37
|
+
+{method}:from_hash
|
38
|
+
}
|
39
|
+
|
40
|
+
class HelpFormatter << (M, #ADD1B2) module>> {
|
41
|
+
Builds help for a command.
|
42
|
+
..
|
43
|
+
+{field}help_template
|
44
|
+
+{method}:help
|
45
|
+
}
|
46
|
+
|
47
|
+
class Validation << (M, #ADD1B2) module>> {
|
48
|
+
Checks the validity of options
|
49
|
+
defined.
|
50
|
+
..
|
51
|
+
+{method}:valid?
|
52
|
+
}
|
53
|
+
|
54
|
+
|
55
|
+
class CommandLineParser <<(M, #ADD1B2) module>> {
|
56
|
+
Parses command-line
|
57
|
+
..
|
58
|
+
+{field}cmd_line_args
|
59
|
+
+{method}:extra_arguments
|
60
|
+
+{method}:params_hash
|
61
|
+
}
|
62
|
+
|
63
|
+
|
64
|
+
SubCommand "1" *-- "n" OptionDefinition : "contains\nand\ncreates"
|
65
|
+
SubCommand -|> Factory : extends
|
66
|
+
SubCommand --|> HelpFormatter : includes
|
67
|
+
SubCommand -|> Validation : includes
|
68
|
+
SubCommand --|> CommandLineParser : includes
|
69
|
+
|
70
|
+
MainCommand ..|> SubCommand : "included\nfor main command\nat runtime"
|
71
|
+
|
72
|
+
}
|
73
|
+
|
74
|
+
|
75
|
+
namespace Manager {
|
76
|
+
|
77
|
+
|
78
|
+
class Base {
|
79
|
+
Manages completely the list of
|
80
|
+
options definition and how to find
|
81
|
+
a processor for a list of command
|
82
|
+
line parameters
|
83
|
+
}
|
84
|
+
|
85
|
+
class LayeredDefinition <<(M, #ADD1B2) module>> {
|
86
|
+
Wrapper around SuperStack::Manager
|
87
|
+
to manage "contributions" to the definition
|
88
|
+
with cache management.
|
89
|
+
..
|
90
|
+
+{method}:definition_hash
|
91
|
+
+{method}:contribute_to_definition
|
92
|
+
+{method}:[]=
|
93
|
+
}
|
94
|
+
|
95
|
+
class ProcessorMatcher <<(M, #ADD1B2) module>> {
|
96
|
+
Determines a suitable list of potential
|
97
|
+
processors from the command-line
|
98
|
+
parameters
|
99
|
+
..
|
100
|
+
+{method}:candidates
|
101
|
+
}
|
102
|
+
|
103
|
+
class Commands <<(M, #ADD1B2) module>> {
|
104
|
+
Manages a main command
|
105
|
+
and optionally sub commands.
|
106
|
+
..
|
107
|
+
+{field}commands
|
108
|
+
}
|
109
|
+
|
110
|
+
class Factory <<(M, #ADD1B2) module>> {
|
111
|
+
How to create a Manager from
|
112
|
+
a definition hash.
|
113
|
+
..
|
114
|
+
+{method}:from_hash
|
115
|
+
}
|
116
|
+
|
117
|
+
Base -|> ProcessorMatcher : includes
|
118
|
+
Base ---|> LayeredDefinition : includes
|
119
|
+
Base --|> Commands : includes
|
120
|
+
Base --|> Factory : extends
|
121
|
+
}
|
122
|
+
|
123
|
+
namespace Processors {
|
124
|
+
class Base
|
125
|
+
|
126
|
+
class Registration<<(M, #ADD1B2) module>>
|
127
|
+
|
128
|
+
Base -|> Registration : includes
|
129
|
+
|
130
|
+
}
|
131
|
+
|
132
|
+
|
133
|
+
namespace Utils {
|
134
|
+
class BasicLogger<<(M, #ADD1B2) module>>
|
135
|
+
class ErrorPropagation<<(M, #ADD1B2) module>>
|
136
|
+
class YamlFactory<<(M, #ADD1B2) module>> {
|
137
|
+
If your module or class implements
|
138
|
+
#from_hash, then including this module
|
139
|
+
will bring the ability to load it from
|
140
|
+
a yaml string or a yaml file.
|
141
|
+
..
|
142
|
+
+{method}:from_yaml
|
143
|
+
+{method}:from_yaml_file
|
144
|
+
}
|
145
|
+
}
|
146
|
+
|
147
|
+
Manager::Commands "1" *---- "n" Commands::SubCommand : "contains\nand\ncreates"
|
148
|
+
Manager::ProcessorMatcher "0" *- "n" Processors::Base
|
149
|
+
|
150
|
+
Manager::Factory -|> Utils::YamlFactory : includes
|
151
|
+
Commands::Factory -|> Utils::YamlFactory : includes
|
152
|
+
|
153
|
+
Manager::Base -|> Utils::ErrorPropagation : includes
|
154
|
+
Commands::SubCommand --|> Utils::ErrorPropagation : includes
|
155
|
+
|
156
|
+
|
157
|
+
|
158
|
+
|
159
|
+
|
160
|
+
@enduml
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'slop'
|
2
|
+
|
3
|
+
require 'ultra_command_line/version'
|
4
|
+
require 'ultra_command_line/error'
|
5
|
+
require 'ultra_command_line/utils/basic_logger'
|
6
|
+
require 'ultra_command_line/utils/error_propagation'
|
7
|
+
require 'ultra_command_line/utils/yaml_factory'
|
8
|
+
|
9
|
+
|
10
|
+
module UltraCommandLine
|
11
|
+
|
12
|
+
extend UltraCommandLine::Utils::BasicLogger
|
13
|
+
|
14
|
+
def self.new_slop_options
|
15
|
+
Slop::Options.new underscore_flags: false
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
|
20
|
+
|
21
|
+
require 'ultra_command_line/commands/sub_command'
|
22
|
+
require 'ultra_command_line/manager/base'
|
23
|
+
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module UltraCommandLine
|
2
|
+
module Commands
|
3
|
+
|
4
|
+
module CommandLineParser
|
5
|
+
|
6
|
+
def params_hash
|
7
|
+
parse_cmd_line_options.to_hash
|
8
|
+
end
|
9
|
+
|
10
|
+
def extra_arguments
|
11
|
+
parse_cmd_line_options.to_hash
|
12
|
+
@extra_arguments ||= []
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def parse_cmd_line_options(options_definition = UltraCommandLine.new_slop_options)
|
18
|
+
parser = build_parser(options_definition)
|
19
|
+
hash = parser.parse cmd_line_args
|
20
|
+
# @cmd_line_args = cmd_line_args
|
21
|
+
@extra_arguments = parser.arguments
|
22
|
+
hash
|
23
|
+
end
|
24
|
+
|
25
|
+
def build_parser(options_definition)
|
26
|
+
options_definition.banner = banner
|
27
|
+
options.each { |option| option.to_slop_options options_definition }
|
28
|
+
Slop::Parser.new options_definition
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module UltraCommandLine
|
2
|
+
module Commands
|
3
|
+
|
4
|
+
module Factory
|
5
|
+
|
6
|
+
DEFAULT_BANNER = ''.freeze
|
7
|
+
|
8
|
+
include UltraCommandLine::Utils::YamlFactory
|
9
|
+
|
10
|
+
def from_hash(definition_hash, factory_options = {})
|
11
|
+
name = factory_options.fetch :name, ''
|
12
|
+
options_definition_hash = definition_hash.fetch(:options, {})
|
13
|
+
manager = factory_options[:manager]
|
14
|
+
banner = definition_hash.fetch :banner, DEFAULT_BANNER
|
15
|
+
create_command name, options_definition_hash, banner, manager
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def create_command(name, options_definition_hash, banner, manager)
|
21
|
+
options = options_definition_hash.map do |option_name, option_definition_hash|
|
22
|
+
option_type = option_definition_hash[:type].to_sym
|
23
|
+
UltraCommandLine::Commands::OptionDefinition.new option_name, option_type, option_definition_hash
|
24
|
+
end
|
25
|
+
new manager, name, banner, options: options
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module UltraCommandLine
|
2
|
+
module Commands
|
3
|
+
|
4
|
+
module HelpFormatter
|
5
|
+
|
6
|
+
DEFAULT_SEPARATOR_WIDTH = 80
|
7
|
+
DEFAULT_SEPARATOR_FILLER = '-'.freeze
|
8
|
+
DEFAULT_TITLE = 'Options'.freeze
|
9
|
+
|
10
|
+
attr_writer :separator_width, :separator_filler
|
11
|
+
|
12
|
+
def separator_width
|
13
|
+
@separator_width ||= DEFAULT_SEPARATOR_WIDTH
|
14
|
+
end
|
15
|
+
|
16
|
+
def title
|
17
|
+
name.nil? || name.empty? ? DEFAULT_TITLE : name
|
18
|
+
end
|
19
|
+
|
20
|
+
def separator_filler
|
21
|
+
@separator_filler ||= DEFAULT_SEPARATOR_FILLER
|
22
|
+
end
|
23
|
+
|
24
|
+
def help
|
25
|
+
output = []
|
26
|
+
output << banner
|
27
|
+
unless options.empty?
|
28
|
+
output << build_separator(title)
|
29
|
+
output.concat options.map(&:help_line)
|
30
|
+
end
|
31
|
+
output
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def build_separator(title)
|
37
|
+
"#{separator_filler * 2} #{title} ".ljust separator_width, separator_filler
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
module UltraCommandLine
|
2
|
+
module Commands
|
3
|
+
|
4
|
+
class OptionDefinition
|
5
|
+
|
6
|
+
DEFAULT_SUMMARY = 'Option summary not provided.'.freeze
|
7
|
+
attr_reader :name, :type
|
8
|
+
attr_reader :short_aliases, :long_aliases
|
9
|
+
attr_accessor :summary, :default, :description, :help, :dependencies, :incompatibilities
|
10
|
+
|
11
|
+
def initialize(name, type, options = {})
|
12
|
+
@name = name
|
13
|
+
@type = type
|
14
|
+
@summary = options.fetch(:summary, DEFAULT_SUMMARY)
|
15
|
+
@default = options.fetch(:default, nil)
|
16
|
+
@description = options.fetch(:description, summary)
|
17
|
+
@help = options.fetch(:help, description)
|
18
|
+
@global = options.fetch(:global, false)
|
19
|
+
@dependencies = options.fetch(:dependencies, [])
|
20
|
+
self.dependencies = dependencies.is_a?(Array) ? dependencies : [dependencies]
|
21
|
+
@incompatibilities = options.fetch(:incompatibilities, [])
|
22
|
+
self.incompatibilities = incompatibilities.is_a?(Array) ? incompatibilities : [incompatibilities]
|
23
|
+
short_aliases = options.fetch(:short_aliases, [])
|
24
|
+
long_aliases = options.fetch(:long_aliases, [])
|
25
|
+
self.short_aliases = (short_aliases.is_a?(Array) ? short_aliases : [short_aliases]).map &:to_sym
|
26
|
+
self.long_aliases = (long_aliases.is_a?(Array) ? long_aliases : [long_aliases]).map &:to_sym
|
27
|
+
end
|
28
|
+
|
29
|
+
def short_aliases=(options)
|
30
|
+
options.each do |option|
|
31
|
+
raise UltraCommandLine::Error, "Invalid short option defined for slop option '#{option}' !" unless option.to_s.size == 1
|
32
|
+
end
|
33
|
+
@short_aliases = options
|
34
|
+
end
|
35
|
+
|
36
|
+
def long_aliases=(options)
|
37
|
+
if options.include? name
|
38
|
+
raise UltraCommandLine::Error, "Inconsistent long options for slop option '#{name}' already defined as main option !"
|
39
|
+
end
|
40
|
+
@long_aliases = options
|
41
|
+
# long_aliases.unshift name
|
42
|
+
end
|
43
|
+
|
44
|
+
def global?
|
45
|
+
@global
|
46
|
+
end
|
47
|
+
|
48
|
+
def to_slop_options(slop_options = UltraCommandLine.new_slop_options)
|
49
|
+
one_letter_options = short_aliases.map.each { |option| "-#{option}" }
|
50
|
+
word_options = long_aliases.map.each { |option| "--#{option}" }
|
51
|
+
# The main option as last entry before description
|
52
|
+
option_def = word_options.concat(one_letter_options) << "--#{name}" << summary
|
53
|
+
option_def.concat [{ default: default }] unless default.nil?
|
54
|
+
slop_options.send type, *option_def
|
55
|
+
slop_options.banner = nil
|
56
|
+
slop_options
|
57
|
+
rescue NoMethodError => e
|
58
|
+
raise UltraCommandLine::Error, "Invalid option type '#{e.name}' for option '#{name}' !"
|
59
|
+
end
|
60
|
+
|
61
|
+
def help_line(slop_options = UltraCommandLine.new_slop_options)
|
62
|
+
to_slop_options(slop_options).to_s.gsub /\n/, ''
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'ultra_command_line/commands/validation'
|
2
|
+
require 'ultra_command_line/commands/command_line_parser'
|
3
|
+
require 'ultra_command_line/commands/main_command'
|
4
|
+
require 'ultra_command_line/commands/option_definition'
|
5
|
+
require 'ultra_command_line/commands/help_formatter'
|
6
|
+
require 'ultra_command_line/commands/factory'
|
7
|
+
|
8
|
+
module UltraCommandLine
|
9
|
+
module Commands
|
10
|
+
|
11
|
+
class SubCommand
|
12
|
+
|
13
|
+
include UltraCommandLine::Utils::ErrorPropagation
|
14
|
+
|
15
|
+
extend UltraCommandLine::Commands::Factory
|
16
|
+
|
17
|
+
include UltraCommandLine::Commands::Validation
|
18
|
+
include UltraCommandLine::Commands::HelpFormatter
|
19
|
+
include UltraCommandLine::Commands::CommandLineParser
|
20
|
+
|
21
|
+
|
22
|
+
attr_reader :name, :manager, :options, :aliases
|
23
|
+
attr_accessor :banner
|
24
|
+
|
25
|
+
def initialize(manager,
|
26
|
+
name = '',
|
27
|
+
banner = UltraCommandLine::Commands::Factory::DEFAULT_BANNER,
|
28
|
+
options: [])
|
29
|
+
@manager = manager
|
30
|
+
@name = name
|
31
|
+
if name.empty?
|
32
|
+
class << self; include UltraCommandLine::Commands::MainCommand; end
|
33
|
+
end
|
34
|
+
self.banner = banner
|
35
|
+
@options = options
|
36
|
+
@aliases = [self.name]
|
37
|
+
end
|
38
|
+
|
39
|
+
def root_command?
|
40
|
+
singleton_class.ancestors.include? UltraCommandLine::Commands::MainCommand
|
41
|
+
end
|
42
|
+
|
43
|
+
def cmd_line_args
|
44
|
+
self_view_of_manager_cmd_line_args
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
attr_writer :manager
|
50
|
+
|
51
|
+
def self_view_of_manager_cmd_line_args
|
52
|
+
manager.cmd_line_args_for_command self
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
module UltraCommandLine
|
2
|
+
module Commands
|
3
|
+
|
4
|
+
module Validation
|
5
|
+
|
6
|
+
|
7
|
+
def valid?(raise_error: false)
|
8
|
+
# return false_or_raise 'You have to successfully parse cmd line parameters before checking its validity !', raise_error: raise_error if params_hash.nil?
|
9
|
+
begin
|
10
|
+
raise if params_hash.nil?
|
11
|
+
rescue
|
12
|
+
return false_or_raise 'You have to successfully parse cmd line parameters before checking its validity !', raise_error: raise_error
|
13
|
+
end
|
14
|
+
return false unless check_options_dependencies raise_error: raise_error
|
15
|
+
return false unless check_options_incompatibilities raise_error: raise_error
|
16
|
+
if name.empty?
|
17
|
+
unless root_command?
|
18
|
+
return false_or_raise 'Only a root command should not have a name !', raise_error: raise_error
|
19
|
+
end
|
20
|
+
end
|
21
|
+
true
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def check_options_incompatibilities(raise_error: false)
|
27
|
+
options.each do |option|
|
28
|
+
if option_eligible_for_incompatibility_test? option
|
29
|
+
option.incompatibilities.each do |incompatibility|
|
30
|
+
unless params_hash[incompatibility.to_sym].nil? or params_hash[incompatibility.to_sym] == false
|
31
|
+
return false_or_raise "Command line option '#{option.name}' is incompatible with option '#{incompatibility}' !",
|
32
|
+
raise_error: raise_error,
|
33
|
+
error_type: UltraCommandLine::OptionDependencyError
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
true
|
39
|
+
end
|
40
|
+
|
41
|
+
def option_eligible_for_incompatibility_test?(option)
|
42
|
+
return false if option.incompatibilities.empty?
|
43
|
+
keys_str = params_hash.keys.map &:to_s
|
44
|
+
if keys_str.include? option.name
|
45
|
+
not (params_hash[option.name.to_sym].nil? or params_hash[option.name.to_sym] == false)
|
46
|
+
else
|
47
|
+
false
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
|
52
|
+
def check_options_dependencies(raise_error: false)
|
53
|
+
options.each do |option|
|
54
|
+
if option_eligible_for_dependency_test? option
|
55
|
+
option.dependencies.each do |dependency|
|
56
|
+
if params_hash[dependency.to_sym].nil? or params_hash[dependency.to_sym] == false
|
57
|
+
return false_or_raise "Command line option '#{option.name}' requires option '#{dependency}' !",
|
58
|
+
raise_error: raise_error,
|
59
|
+
error_type: UltraCommandLine::OptionDependencyError
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
true
|
65
|
+
end
|
66
|
+
|
67
|
+
def option_eligible_for_dependency_test?(option)
|
68
|
+
return false if option.dependencies.empty?
|
69
|
+
keys_str = params_hash.keys.map &:to_s
|
70
|
+
if keys_str.include? option.name
|
71
|
+
not (params_hash[option.name.to_sym].nil? or params_hash[option.name.to_sym] == false)
|
72
|
+
else
|
73
|
+
false
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'ultra_command_line/manager/factory'
|
2
|
+
require 'ultra_command_line/manager/layered_definition'
|
3
|
+
require 'ultra_command_line/manager/cmd_line_args'
|
4
|
+
require 'ultra_command_line/manager/commands'
|
5
|
+
require 'ultra_command_line/manager/processors'
|
6
|
+
|
7
|
+
module UltraCommandLine
|
8
|
+
module Manager
|
9
|
+
|
10
|
+
class Base
|
11
|
+
|
12
|
+
include UltraCommandLine::Utils::ErrorPropagation
|
13
|
+
|
14
|
+
extend UltraCommandLine::Manager::Factory
|
15
|
+
|
16
|
+
include UltraCommandLine::Manager::LayeredDefinition
|
17
|
+
include UltraCommandLine::Manager::Commands
|
18
|
+
|
19
|
+
include UltraCommandLine::Manager::Processors
|
20
|
+
|
21
|
+
def initialize(commands = [])
|
22
|
+
@commands = commands
|
23
|
+
end
|
24
|
+
|
25
|
+
def definition_hash_to_commands
|
26
|
+
self.class.from_hash(definition_hash) do |commands|
|
27
|
+
commands.each {|command| command.send :manager=, self }
|
28
|
+
@commands = commands
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
|
2
|
+
module UltraCommandLine
|
3
|
+
module Manager
|
4
|
+
|
5
|
+
module CmdLineArgs
|
6
|
+
|
7
|
+
def cmd_line_args
|
8
|
+
@cmd_line_args ||= []
|
9
|
+
end
|
10
|
+
|
11
|
+
def cmd_line_args=(cmd_line_args)
|
12
|
+
cmd_line_args = case cmd_line_args
|
13
|
+
when Array
|
14
|
+
cmd_line_args
|
15
|
+
when String
|
16
|
+
cmd_line_args.split ' '
|
17
|
+
end
|
18
|
+
UltraCommandLine.logger.debug "Cmd line: #{cmd_line_args.inspect}"
|
19
|
+
@cmd_line_args = cmd_line_args
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
module UltraCommandLine
|
2
|
+
module Manager
|
3
|
+
|
4
|
+
module Commands
|
5
|
+
|
6
|
+
include UltraCommandLine::Manager::CmdLineArgs
|
7
|
+
|
8
|
+
def commands
|
9
|
+
@commands ||= []
|
10
|
+
end
|
11
|
+
|
12
|
+
def root_command
|
13
|
+
return nil if commands.empty?
|
14
|
+
l = commands.select {|c| c.root_command? && c.name.empty? }
|
15
|
+
raise UltraCommandLine::Error, 'Wrong commands definition !' unless l.count == 1
|
16
|
+
l.first
|
17
|
+
end
|
18
|
+
|
19
|
+
def aliases_consistent?
|
20
|
+
# including aliases
|
21
|
+
full_names_list = []
|
22
|
+
commands.each do |command|
|
23
|
+
if command.root_command?
|
24
|
+
return false unless command.name.empty? && command.aliases == [command.name]
|
25
|
+
else
|
26
|
+
command.aliases.each do |alias_name|
|
27
|
+
return false if full_names_list.include? alias_name.to_s
|
28
|
+
full_names_list << alias_name.to_s
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
end
|
33
|
+
true
|
34
|
+
end
|
35
|
+
|
36
|
+
def command(cmd_line_args = self.cmd_line_args)
|
37
|
+
command_alias = cmd_line_args.empty? ? '' : cmd_line_args.first
|
38
|
+
command_by_alias(command_alias) || root_command
|
39
|
+
end
|
40
|
+
|
41
|
+
def command_by_alias(command_alias)
|
42
|
+
raise UltraCommandLine::Error, 'command names/aliases are not consistent !' unless aliases_consistent?
|
43
|
+
candidates = commands.select do |command|
|
44
|
+
command.aliases.map(&:to_s).include? command_alias.to_s
|
45
|
+
end
|
46
|
+
# raise UltraCommandLine::Error, "There is no command named '#{command_alias}'!" unless candidates.siez == 1
|
47
|
+
candidates.size == 1 ? candidates.first : nil
|
48
|
+
end
|
49
|
+
|
50
|
+
def cmd_line_args_for_command(command)
|
51
|
+
if command.root_command?
|
52
|
+
cmd_line_args
|
53
|
+
else
|
54
|
+
clfc = cmd_line_args.dup
|
55
|
+
clfc.shift
|
56
|
+
clfc
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
protected
|
61
|
+
|
62
|
+
attr_writer :commands
|
63
|
+
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module UltraCommandLine
|
2
|
+
module Manager
|
3
|
+
|
4
|
+
module Factory
|
5
|
+
|
6
|
+
include UltraCommandLine::Utils::YamlFactory
|
7
|
+
|
8
|
+
def from_hash(definition_hash, factory_options = {})
|
9
|
+
UltraCommandLine.logger.debug 'Starting commands analysis from definition hash.'
|
10
|
+
commands = []
|
11
|
+
# Create main command
|
12
|
+
UltraCommandLine.logger.debug 'Defining main command.'
|
13
|
+
main_command = create_command '', definition_hash
|
14
|
+
main_command.banner = definition_hash.fetch :banner, ''
|
15
|
+
commands << main_command
|
16
|
+
# Create sub-commands
|
17
|
+
definition_hash.fetch(:subcommands, {}).each do |subcommand_name, subcommand_definition|
|
18
|
+
UltraCommandLine.logger.debug "Defining sub-command '#{subcommand_name}'."
|
19
|
+
# subcommand_definition ||= {}
|
20
|
+
subcommand = create_command subcommand_name, subcommand_definition
|
21
|
+
subcommand.banner = subcommand_definition.fetch :banner, ''
|
22
|
+
# Let's add global options
|
23
|
+
main_command.options.select(&:global?).each do |global_option|
|
24
|
+
subcommand.options << global_option
|
25
|
+
end
|
26
|
+
commands << subcommand
|
27
|
+
end
|
28
|
+
if block_given?
|
29
|
+
yield commands
|
30
|
+
else
|
31
|
+
# Return a new object supporting a list of commands as parameter
|
32
|
+
new_manager = new commands
|
33
|
+
new_manager.initialize_definition definition_hash
|
34
|
+
commands.each {|c| c.send :manager=, new_manager}
|
35
|
+
new_manager
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def create_command(name, options_definition)
|
42
|
+
UltraCommandLine::Commands::SubCommand.from_hash options_definition, name: name, manager: self
|
43
|
+
end
|
44
|
+
|
45
|
+
|
46
|
+
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
require 'super_stack'
|
2
|
+
|
3
|
+
module UltraCommandLine
|
4
|
+
module Manager
|
5
|
+
|
6
|
+
module LayeredDefinition
|
7
|
+
|
8
|
+
def definition_hash
|
9
|
+
@cached_definition ||= layers_manager[].to_hash
|
10
|
+
end
|
11
|
+
|
12
|
+
def initialize_definition(hash)
|
13
|
+
reset_cached_configuration
|
14
|
+
@layers_manager = setup_layers_manager hash
|
15
|
+
self
|
16
|
+
end
|
17
|
+
|
18
|
+
def contribute_to_definition(hash, layer_name: :unknown_layer)
|
19
|
+
reset_cached_configuration
|
20
|
+
layers_manager
|
21
|
+
new_layer = SuperStack::LayerWrapper.from_hash hash
|
22
|
+
new_layer.name = layer_name
|
23
|
+
new_layer.priority = definition_counter
|
24
|
+
layers_manager.add_layer new_layer
|
25
|
+
end
|
26
|
+
|
27
|
+
def []=(key, value)
|
28
|
+
layers_manager[key] = value
|
29
|
+
end
|
30
|
+
|
31
|
+
def refresh
|
32
|
+
reset_cached_configuration
|
33
|
+
end
|
34
|
+
|
35
|
+
def clear
|
36
|
+
reset_definition_hash
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
BASE_LAYER_PRIORITY = 10
|
42
|
+
DEFINITION_LAYERS_BASE_PRIORITY = 100
|
43
|
+
UPDATE_LAYER_PRIORITY = 1000
|
44
|
+
|
45
|
+
def reset_cached_configuration
|
46
|
+
@cached_definition = nil
|
47
|
+
end
|
48
|
+
|
49
|
+
def reset_definition_hash
|
50
|
+
reset_cached_configuration
|
51
|
+
@layers_manager = nil
|
52
|
+
end
|
53
|
+
|
54
|
+
def definition_counter
|
55
|
+
raise UltraCommandLine::Error, 'Maximum number of definition reached !' if @definition_counter+1 >= UPDATE_LAYER_PRIORITY
|
56
|
+
@definition_counter += 1
|
57
|
+
end
|
58
|
+
|
59
|
+
def layers_manager
|
60
|
+
@layers_manager ||= setup_layers_manager
|
61
|
+
end
|
62
|
+
|
63
|
+
def setup_layers_manager(hash = nil)
|
64
|
+
merger = SuperStack::Manager.new
|
65
|
+
merger.merge_policy = SuperStack::MergePolicies::FullMergePolicy
|
66
|
+
base_layer = if hash.nil?
|
67
|
+
SuperStack::Layer.new
|
68
|
+
else
|
69
|
+
SuperStack::LayerWrapper.from_hash(hash)
|
70
|
+
end
|
71
|
+
base_layer.name = :base
|
72
|
+
base_layer.priority = BASE_LAYER_PRIORITY
|
73
|
+
merger.add_layer base_layer
|
74
|
+
update_layer = SuperStack::Layer.new
|
75
|
+
update_layer.name = :manual_updates
|
76
|
+
update_layer.priority = UPDATE_LAYER_PRIORITY
|
77
|
+
merger.add_layer update_layer
|
78
|
+
merger.write_layer = update_layer
|
79
|
+
@definition_counter = DEFINITION_LAYERS_BASE_PRIORITY
|
80
|
+
merger
|
81
|
+
end
|
82
|
+
|
83
|
+
end
|
84
|
+
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
module UltraCommandLine
|
2
|
+
module Manager
|
3
|
+
|
4
|
+
module Processors
|
5
|
+
|
6
|
+
include UltraCommandLine::Manager::Commands
|
7
|
+
|
8
|
+
MANDATORY_PROCESSOR_METHODS = %i[check_params execute].freeze
|
9
|
+
|
10
|
+
def processors(for_command: nil)
|
11
|
+
if for_command.nil?
|
12
|
+
processors_hash.values.inject([]) do |res, value|
|
13
|
+
res.concat value
|
14
|
+
res
|
15
|
+
end .uniq
|
16
|
+
else
|
17
|
+
processors_hash[for_command]
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def register_processor(command_name_or_command, processor)
|
22
|
+
verify_processor_implementation processor
|
23
|
+
if processors.include? processor
|
24
|
+
msg = 'Trying to insert a processor already registered: %s' % [processor.inspect]
|
25
|
+
UltraCommandLine.logger.debug msg
|
26
|
+
end
|
27
|
+
command = command_name_or_command_to_command command_name_or_command
|
28
|
+
processors_hash[command.name] ||= []
|
29
|
+
processors_hash[command.name] << processor
|
30
|
+
command_name = command.name.empty? ? 'Root' : "#{command.name}"
|
31
|
+
UltraCommandLine.logger.debug "Registered Processor #{processor.inspect} to '#{command_name}' command"
|
32
|
+
end
|
33
|
+
|
34
|
+
def clear_processors
|
35
|
+
@processors_hash = nil
|
36
|
+
end
|
37
|
+
|
38
|
+
def processor
|
39
|
+
processor_candidates = processors_hash.fetch(command(cmd_line_args).name, []) .select do |processor|
|
40
|
+
processor.check_params command.cmd_line_args
|
41
|
+
end
|
42
|
+
raise UltraCommandLine::Error, 'No processor found for this command line' if processor_candidates.empty?
|
43
|
+
raise UltraCommandLine::Error, 'Too many possible processors' unless processor_candidates.size == 1
|
44
|
+
processor_candidates.first
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
def command_name_or_command_to_command(command_name_or_command)
|
50
|
+
case command_name_or_command
|
51
|
+
when String
|
52
|
+
command_by_alias command_name_or_command
|
53
|
+
when UltraCommandLine::Commands::SubCommand
|
54
|
+
command_name_or_command
|
55
|
+
else
|
56
|
+
raise UltraCommandLine::Error, "Invalid command or command name: '#{command_name_or_command.inspect}'"
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def verify_processor_implementation(processor)
|
61
|
+
MANDATORY_PROCESSOR_METHODS.each do |method_name|
|
62
|
+
unless processor.respond_to? method_name
|
63
|
+
raise UltraCommandLine::Error, "Invalid processor '#{processor.inspect}' missing method '#{method_name}'!"
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def processors_hash
|
69
|
+
@processors_hash ||= {}
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module UltraCommandLine
|
2
|
+
module Utils
|
3
|
+
|
4
|
+
module BasicLogger
|
5
|
+
|
6
|
+
class NullLogger
|
7
|
+
def method_missing(*args)
|
8
|
+
# Do nothing
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def logger=(logger)
|
13
|
+
@logger = logger
|
14
|
+
end
|
15
|
+
|
16
|
+
def logger
|
17
|
+
@logger ||= NullLogger.new
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module UltraCommandLine
|
2
|
+
module Utils
|
3
|
+
|
4
|
+
module ErrorPropagation
|
5
|
+
|
6
|
+
DEFAULT_ERROR_MESSAGE = 'Error message not provided!'.freeze
|
7
|
+
|
8
|
+
private
|
9
|
+
|
10
|
+
def false_or_raise(message = DEFAULT_ERROR_MESSAGE, raise_error: false, error_type: UltraCommandLine::Error)
|
11
|
+
if raise_error
|
12
|
+
raise error_type, message
|
13
|
+
else
|
14
|
+
UltraCommandLine.logger.warn message
|
15
|
+
end
|
16
|
+
false
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module UltraCommandLine
|
2
|
+
module Utils
|
3
|
+
|
4
|
+
module YamlFactory
|
5
|
+
|
6
|
+
def from_yaml_file(yaml_file, factory_options = {}, &block)
|
7
|
+
yaml_file = File.expand_path yaml_file
|
8
|
+
UltraCommandLine.logger.debug "Loading commands definitions from '#{yaml_file}'."
|
9
|
+
raise UltraCommandLine::Error, 'Invalid Yaml command file specified !' unless File.exists? yaml_file
|
10
|
+
raise UltraCommandLine::Error, 'Cannot read Yaml command file !' unless File.readable? yaml_file
|
11
|
+
from_yaml File.read(yaml_file), factory_options, &block
|
12
|
+
end
|
13
|
+
|
14
|
+
def from_yaml(yaml, factory_options = {}, &block)
|
15
|
+
from_hash YAML.load(yaml), factory_options, &block
|
16
|
+
rescue => e
|
17
|
+
UltraCommandLine.logger.error "#{e.message}\nBacktrace:\n#{e.backtrace.join("\n\t")}"
|
18
|
+
raise UltraCommandLine::Error, 'Invalid Yaml content. Parser error !'
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'ultra_command_line/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = 'ultra_command_line'
|
8
|
+
spec.version = UltraCommandLine::VERSION
|
9
|
+
spec.authors = ['Laurent B.']
|
10
|
+
spec.email = ['lbnetid+rb@gmail.com']
|
11
|
+
|
12
|
+
spec.summary = %q{Manage complex sub_command line options.}
|
13
|
+
spec.description = %q{Allows to handle complex sub_command line options with subcommands a-la-git.}
|
14
|
+
spec.homepage = 'https://gitlab.com/lbriais/ultra_command_line'
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
17
|
+
f.match(%r{^(test|spec|features)/})
|
18
|
+
end
|
19
|
+
spec.bindir = 'exe'
|
20
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
21
|
+
spec.require_paths = ['lib']
|
22
|
+
|
23
|
+
spec.add_development_dependency 'bundler', '~> 1.15'
|
24
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
25
|
+
spec.add_development_dependency 'rspec', '~> 3.0'
|
26
|
+
spec.add_development_dependency 'simplecov'
|
27
|
+
|
28
|
+
spec.add_dependency 'super_stack', '~> 1.0'
|
29
|
+
spec.add_dependency 'slop', '~> 4.5'
|
30
|
+
end
|
metadata
ADDED
@@ -0,0 +1,156 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ultra_command_line
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.4.7
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Laurent B.
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2019-08-25 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.15'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.15'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '3.0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '3.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: simplecov
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: super_stack
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '1.0'
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '1.0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: slop
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '4.5'
|
90
|
+
type: :runtime
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '4.5'
|
97
|
+
description: Allows to handle complex sub_command line options with subcommands a-la-git.
|
98
|
+
email:
|
99
|
+
- lbnetid+rb@gmail.com
|
100
|
+
executables: []
|
101
|
+
extensions: []
|
102
|
+
extra_rdoc_files: []
|
103
|
+
files:
|
104
|
+
- ".gitignore"
|
105
|
+
- ".rspec"
|
106
|
+
- ".travis.yml"
|
107
|
+
- Gemfile
|
108
|
+
- README.md
|
109
|
+
- Rakefile
|
110
|
+
- bin/console
|
111
|
+
- bin/setup
|
112
|
+
- docs/command_definition.puml
|
113
|
+
- lib/ultra_command_line.rb
|
114
|
+
- lib/ultra_command_line/commands/command_line_parser.rb
|
115
|
+
- lib/ultra_command_line/commands/factory.rb
|
116
|
+
- lib/ultra_command_line/commands/help_formatter.rb
|
117
|
+
- lib/ultra_command_line/commands/main_command.rb
|
118
|
+
- lib/ultra_command_line/commands/option_definition.rb
|
119
|
+
- lib/ultra_command_line/commands/sub_command.rb
|
120
|
+
- lib/ultra_command_line/commands/validation.rb
|
121
|
+
- lib/ultra_command_line/error.rb
|
122
|
+
- lib/ultra_command_line/manager/base.rb
|
123
|
+
- lib/ultra_command_line/manager/cmd_line_args.rb
|
124
|
+
- lib/ultra_command_line/manager/commands.rb
|
125
|
+
- lib/ultra_command_line/manager/factory.rb
|
126
|
+
- lib/ultra_command_line/manager/layered_definition.rb
|
127
|
+
- lib/ultra_command_line/manager/processors.rb
|
128
|
+
- lib/ultra_command_line/utils/basic_logger.rb
|
129
|
+
- lib/ultra_command_line/utils/error_propagation.rb
|
130
|
+
- lib/ultra_command_line/utils/yaml_factory.rb
|
131
|
+
- lib/ultra_command_line/version.rb
|
132
|
+
- ultra_command_line.gemspec
|
133
|
+
homepage: https://gitlab.com/lbriais/ultra_command_line
|
134
|
+
licenses: []
|
135
|
+
metadata: {}
|
136
|
+
post_install_message:
|
137
|
+
rdoc_options: []
|
138
|
+
require_paths:
|
139
|
+
- lib
|
140
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
141
|
+
requirements:
|
142
|
+
- - ">="
|
143
|
+
- !ruby/object:Gem::Version
|
144
|
+
version: '0'
|
145
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
146
|
+
requirements:
|
147
|
+
- - ">="
|
148
|
+
- !ruby/object:Gem::Version
|
149
|
+
version: '0'
|
150
|
+
requirements: []
|
151
|
+
rubyforge_project:
|
152
|
+
rubygems_version: 2.5.1
|
153
|
+
signing_key:
|
154
|
+
specification_version: 4
|
155
|
+
summary: Manage complex sub_command line options.
|
156
|
+
test_files: []
|