eac_cli 0.20.0 → 0.21.0
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 +4 -4
- data/lib/eac_cli/definition/help_formatter.rb +3 -2
- data/lib/eac_cli/runner.rb +0 -2
- data/lib/eac_cli/runner/after_class_methods.rb +20 -3
- data/lib/eac_cli/runner/instance_methods.rb +5 -1
- data/lib/eac_cli/runner_with/help.rb +3 -2
- data/lib/eac_cli/runner_with/help/builder.rb +73 -0
- data/lib/eac_cli/runner_with/help/builder/alternative.rb +56 -0
- data/lib/eac_cli/runner_with/subcommands.rb +1 -3
- data/lib/eac_cli/version.rb +1 -1
- metadata +4 -26
- data/lib/eac_cli/docopt/doc_builder.rb +0 -71
- data/lib/eac_cli/docopt/doc_builder/alternative.rb +0 -52
- data/lib/eac_cli/docopt/runner_context_replacement.rb +0 -15
- data/lib/eac_cli/docopt/runner_extension.rb +0 -51
- data/lib/eac_cli/docopt_runner.rb +0 -38
- data/lib/eac_cli/docopt_runner/_class_methods.rb +0 -16
- data/lib/eac_cli/docopt_runner/_doc.rb +0 -23
- data/lib/eac_cli/docopt_runner/_settings.rb +0 -17
- data/lib/eac_cli/docopt_runner/_subcommands.rb +0 -152
- data/lib/eac_cli/docopt_runner/context.rb +0 -18
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d77b174dd680d497c168311008da5096a1de24d0feb6ce1edaf37728141e4224
|
4
|
+
data.tar.gz: 530c92c167b11544b064bf2cf6084f1871bd9a2371df0328bf0d932d489df568
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d08a25c365ec9902ef08092e94b5550c2252f2c2463c1b4dabbc80557e3485da9424b2900554f33d1dca83fa898b10e7287b7df7e61f3d73d4bd7c9e86971c91
|
7
|
+
data.tar.gz: 752d67c71f2eab73ed4f7d420dc7f8319d35f46a1f1296b05a62bf674490540cf48100a87664f04d3f679873a77e8d008bd287dfc88cec7e85f26685340d5d08
|
@@ -1,5 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'eac_cli/runner_with/help/builder/alternative'
|
3
4
|
require 'eac_ruby_utils/core_ext'
|
4
5
|
|
5
6
|
module EacCli
|
@@ -27,7 +28,7 @@ module EacCli
|
|
27
28
|
|
28
29
|
def positional_argument(positional)
|
29
30
|
if positional.subcommand?
|
30
|
-
::EacCli::
|
31
|
+
::EacCli::RunnerWith::Help::Builder::Alternative::SUBCOMMANDS_MACRO
|
31
32
|
else
|
32
33
|
r = "<#{positional.name}>"
|
33
34
|
r += '...' if positional.repeat?
|
@@ -52,7 +53,7 @@ module EacCli
|
|
52
53
|
end
|
53
54
|
|
54
55
|
def self_usage_arguments
|
55
|
-
[::EacCli::
|
56
|
+
[::EacCli::RunnerWith::Help::Builder::Alternative::PROGRAM_MACRO] +
|
56
57
|
definition.options_argument.if_present([]) { |_v| ['[options]'] } +
|
57
58
|
self_usage_arguments_options +
|
58
59
|
self_usage_arguments_positional
|
data/lib/eac_cli/runner.rb
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'eac_cli/definition'
|
4
|
-
require 'eac_cli/docopt/runner_extension'
|
5
4
|
require 'eac_cli/parser'
|
6
5
|
require 'eac_ruby_utils/core_ext'
|
7
6
|
|
@@ -43,7 +42,6 @@ module EacCli
|
|
43
42
|
|
44
43
|
extend AfterClassMethods
|
45
44
|
include InstanceMethods
|
46
|
-
::EacCli::Docopt::RunnerExtension.check(self)
|
47
45
|
include ActiveSupport::Callbacks
|
48
46
|
define_callbacks :run
|
49
47
|
end
|
@@ -1,5 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'eac_cli/speaker'
|
4
|
+
require 'eac_ruby_utils/speaker'
|
5
|
+
|
3
6
|
module EacCli
|
4
7
|
module Runner
|
5
8
|
module AfterClassMethods
|
@@ -10,9 +13,11 @@ module EacCli
|
|
10
13
|
end
|
11
14
|
|
12
15
|
def run(*runner_context_args)
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
+
on_asserted_speaker do
|
17
|
+
r = create(*runner_context_args)
|
18
|
+
r.run_run
|
19
|
+
r
|
20
|
+
end
|
16
21
|
end
|
17
22
|
|
18
23
|
def runner_definition(&block)
|
@@ -24,6 +29,18 @@ module EacCli
|
|
24
29
|
def super_runner_definition
|
25
30
|
superclass.try(:runner_definition).if_present(&:dup) || ::EacCli::Definition.new
|
26
31
|
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def on_asserted_speaker
|
36
|
+
if ::EacRubyUtils::Speaker.context.optional_current
|
37
|
+
yield
|
38
|
+
else
|
39
|
+
::EacRubyUtils::Speaker.context.on(::EacCli::Speaker.new) do
|
40
|
+
yield
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
27
44
|
end
|
28
45
|
end
|
29
46
|
end
|
@@ -15,7 +15,7 @@ module EacCli
|
|
15
15
|
end
|
16
16
|
|
17
17
|
def run_parser_error(error)
|
18
|
-
$stderr.write("#{error}\n")
|
18
|
+
$stderr.write("#{program_name}: #{error}\n")
|
19
19
|
::Kernel.exit(PARSER_ERROR_EXIT_CODE)
|
20
20
|
end
|
21
21
|
|
@@ -33,6 +33,10 @@ module EacCli
|
|
33
33
|
def parsed
|
34
34
|
@parsed ||= ::EacCli::Parser.new(self.class.runner_definition, runner_context.argv).parsed
|
35
35
|
end
|
36
|
+
|
37
|
+
def program_name
|
38
|
+
runner_context.if_present(&:program_name) || $PROGRAM_NAME
|
39
|
+
end
|
36
40
|
end
|
37
41
|
end
|
38
42
|
end
|
@@ -6,11 +6,12 @@ require 'eac_ruby_utils/core_ext'
|
|
6
6
|
module EacCli
|
7
7
|
module RunnerWith
|
8
8
|
module Help
|
9
|
+
require_sub __FILE__
|
9
10
|
common_concern do
|
10
11
|
include ::EacCli::Runner
|
11
12
|
|
12
13
|
runner_definition.alt do
|
13
|
-
bool_opt '-h', '--help', 'Show help.', usage: true
|
14
|
+
bool_opt '-h', '--help', 'Show help.', usage: true, required: true
|
14
15
|
pos_arg :any_arg_with_help, repeat: true, optional: true, visible: false
|
15
16
|
end
|
16
17
|
|
@@ -27,7 +28,7 @@ module EacCli
|
|
27
28
|
end
|
28
29
|
|
29
30
|
def help_text
|
30
|
-
r = ::EacCli::
|
31
|
+
r = ::EacCli::RunnerWith::Help::Builder.new(self.class.runner_definition).to_s
|
31
32
|
r += help_extra_text if respond_to?(:help_extra_text)
|
32
33
|
r
|
33
34
|
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'eac_ruby_utils/core_ext'
|
4
|
+
|
5
|
+
module EacCli
|
6
|
+
module RunnerWith
|
7
|
+
module Help
|
8
|
+
class Builder
|
9
|
+
require_sub __FILE__
|
10
|
+
common_constructor :definition
|
11
|
+
|
12
|
+
SEP = ' '
|
13
|
+
IDENT = SEP * 2
|
14
|
+
OPTION_DESC_SEP = IDENT * 2
|
15
|
+
|
16
|
+
class << self
|
17
|
+
def option_long(option)
|
18
|
+
b = option.long
|
19
|
+
b += '=<value>' if option.argument?
|
20
|
+
b
|
21
|
+
end
|
22
|
+
|
23
|
+
def option_short(option)
|
24
|
+
b = option.short
|
25
|
+
b += '=<value>' if option.argument?
|
26
|
+
b
|
27
|
+
end
|
28
|
+
|
29
|
+
def option_usage_full(option)
|
30
|
+
if option.long.present?
|
31
|
+
[option.short, option_long(option)].reject(&:blank?).join(SEP)
|
32
|
+
else
|
33
|
+
option_short(option)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def option_definition(option)
|
39
|
+
self.class.option_usage_full(option) + option.description.if_present('') do |v|
|
40
|
+
OPTION_DESC_SEP + v
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def section(header, include_header = true)
|
45
|
+
b = include_header ? "#{header.humanize}:\n" : ''
|
46
|
+
b += send("self_#{header}") + "\n"
|
47
|
+
definition.alternatives.each do |alternative|
|
48
|
+
b += IDENT + ::EacCli::RunnerWith::Help::Builder::Alternative.new(alternative).to_s +
|
49
|
+
"\n"
|
50
|
+
end
|
51
|
+
b
|
52
|
+
end
|
53
|
+
|
54
|
+
def options_section
|
55
|
+
"Options:\n" +
|
56
|
+
definition.alternatives.flat_map(&:options)
|
57
|
+
.map { |option| IDENT + option_definition(option) + "\n" }.join
|
58
|
+
end
|
59
|
+
|
60
|
+
def usage_section
|
61
|
+
"Usage:\n" +
|
62
|
+
definition.alternatives.map do |alternative|
|
63
|
+
IDENT + ::EacCli::RunnerWith::Help::Builder::Alternative.new(alternative).to_s + "\n"
|
64
|
+
end.join
|
65
|
+
end
|
66
|
+
|
67
|
+
def to_s
|
68
|
+
"#{definition.description}\n\n#{usage_section}\n#{options_section}\n"
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'eac_ruby_utils/core_ext'
|
4
|
+
|
5
|
+
module EacCli
|
6
|
+
module RunnerWith
|
7
|
+
module Help
|
8
|
+
class Builder
|
9
|
+
class Alternative
|
10
|
+
PROGRAM_MACRO = '__PROGRAM__'
|
11
|
+
SUBCOMMANDS_MACRO = '__SUBCOMMANDS__'
|
12
|
+
|
13
|
+
common_constructor :alternative
|
14
|
+
|
15
|
+
def to_s
|
16
|
+
(
|
17
|
+
[PROGRAM_MACRO] +
|
18
|
+
alternative.options_argument?.if_present([]) { |_v| ['[options]'] } +
|
19
|
+
options +
|
20
|
+
positionals
|
21
|
+
).join(::EacCli::RunnerWith::Help::Builder::SEP)
|
22
|
+
end
|
23
|
+
|
24
|
+
def options
|
25
|
+
alternative.options.select(&:show_on_usage?).map do |option|
|
26
|
+
::EacCli::RunnerWith::Help::Builder.option_long(option)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def option_argument(option)
|
31
|
+
b = option.long
|
32
|
+
b += '=<value>' if option.argument?
|
33
|
+
b
|
34
|
+
end
|
35
|
+
|
36
|
+
def positionals
|
37
|
+
alternative.positional.map { |p| positional(p) }.reject(&:blank?)
|
38
|
+
end
|
39
|
+
|
40
|
+
def positional(positional)
|
41
|
+
return unless positional.visible?
|
42
|
+
|
43
|
+
if positional.subcommand?
|
44
|
+
SUBCOMMANDS_MACRO
|
45
|
+
else
|
46
|
+
r = "<#{positional.name}>"
|
47
|
+
r += '...' if positional.repeat?
|
48
|
+
r = "[#{r}]" if positional.optional?
|
49
|
+
r
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
data/lib/eac_cli/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: eac_cli
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.21.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Esquilo Azul Company
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-06-
|
11
|
+
date: 2021-06-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: colorize
|
@@ -24,20 +24,6 @@ dependencies:
|
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: 0.8.1
|
27
|
-
- !ruby/object:Gem::Dependency
|
28
|
-
name: docopt
|
29
|
-
requirement: !ruby/object:Gem::Requirement
|
30
|
-
requirements:
|
31
|
-
- - "~>"
|
32
|
-
- !ruby/object:Gem::Version
|
33
|
-
version: 0.6.1
|
34
|
-
type: :runtime
|
35
|
-
prerelease: false
|
36
|
-
version_requirements: !ruby/object:Gem::Requirement
|
37
|
-
requirements:
|
38
|
-
- - "~>"
|
39
|
-
- !ruby/object:Gem::Version
|
40
|
-
version: 0.6.1
|
41
27
|
- !ruby/object:Gem::Dependency
|
42
28
|
name: eac_config
|
43
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -102,16 +88,6 @@ files:
|
|
102
88
|
- lib/eac_cli/definition/boolean_option.rb
|
103
89
|
- lib/eac_cli/definition/help_formatter.rb
|
104
90
|
- lib/eac_cli/definition/positional_argument.rb
|
105
|
-
- lib/eac_cli/docopt/doc_builder.rb
|
106
|
-
- lib/eac_cli/docopt/doc_builder/alternative.rb
|
107
|
-
- lib/eac_cli/docopt/runner_context_replacement.rb
|
108
|
-
- lib/eac_cli/docopt/runner_extension.rb
|
109
|
-
- lib/eac_cli/docopt_runner.rb
|
110
|
-
- lib/eac_cli/docopt_runner/_class_methods.rb
|
111
|
-
- lib/eac_cli/docopt_runner/_doc.rb
|
112
|
-
- lib/eac_cli/docopt_runner/_settings.rb
|
113
|
-
- lib/eac_cli/docopt_runner/_subcommands.rb
|
114
|
-
- lib/eac_cli/docopt_runner/context.rb
|
115
91
|
- lib/eac_cli/old_configs.rb
|
116
92
|
- lib/eac_cli/old_configs/entry_reader.rb
|
117
93
|
- lib/eac_cli/old_configs/password_entry_reader.rb
|
@@ -139,6 +115,8 @@ files:
|
|
139
115
|
- lib/eac_cli/runner/instance_methods.rb
|
140
116
|
- lib/eac_cli/runner_with.rb
|
141
117
|
- lib/eac_cli/runner_with/help.rb
|
118
|
+
- lib/eac_cli/runner_with/help/builder.rb
|
119
|
+
- lib/eac_cli/runner_with/help/builder/alternative.rb
|
142
120
|
- lib/eac_cli/runner_with/subcommands.rb
|
143
121
|
- lib/eac_cli/runner_with/subcommands/definition_concern.rb
|
144
122
|
- lib/eac_cli/runner_with_set.rb
|
@@ -1,71 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'eac_ruby_utils/core_ext'
|
4
|
-
require 'eac_cli/docopt_runner'
|
5
|
-
|
6
|
-
module EacCli
|
7
|
-
module Docopt
|
8
|
-
class DocBuilder
|
9
|
-
require_sub __FILE__
|
10
|
-
common_constructor :definition
|
11
|
-
|
12
|
-
SEP = ' '
|
13
|
-
IDENT = SEP * 2
|
14
|
-
OPTION_DESC_SEP = IDENT * 2
|
15
|
-
|
16
|
-
class << self
|
17
|
-
def option_long(option)
|
18
|
-
b = option.long
|
19
|
-
b += '=<value>' if option.argument?
|
20
|
-
b
|
21
|
-
end
|
22
|
-
|
23
|
-
def option_short(option)
|
24
|
-
b = option.short
|
25
|
-
b += '=<value>' if option.argument?
|
26
|
-
b
|
27
|
-
end
|
28
|
-
|
29
|
-
def option_usage_full(option)
|
30
|
-
if option.long.present?
|
31
|
-
[option.short, option_long(option)].reject(&:blank?).join(SEP)
|
32
|
-
else
|
33
|
-
option_short(option)
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
def option_definition(option)
|
39
|
-
self.class.option_usage_full(option) + option.description.if_present('') do |v|
|
40
|
-
OPTION_DESC_SEP + v
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
def section(header, include_header = true)
|
45
|
-
b = include_header ? "#{header.humanize}:\n" : ''
|
46
|
-
b += send("self_#{header}") + "\n"
|
47
|
-
definition.alternatives.each do |alternative|
|
48
|
-
b += IDENT + ::EacCli::Docopt::DocBuilder::Alternative.new(alternative).to_s + "\n"
|
49
|
-
end
|
50
|
-
b
|
51
|
-
end
|
52
|
-
|
53
|
-
def options_section
|
54
|
-
"Options:\n" +
|
55
|
-
definition.alternatives.flat_map(&:options)
|
56
|
-
.map { |option| IDENT + option_definition(option) + "\n" }.join
|
57
|
-
end
|
58
|
-
|
59
|
-
def usage_section
|
60
|
-
"Usage:\n" +
|
61
|
-
definition.alternatives.map do |alternative|
|
62
|
-
IDENT + ::EacCli::Docopt::DocBuilder::Alternative.new(alternative).to_s + "\n"
|
63
|
-
end.join
|
64
|
-
end
|
65
|
-
|
66
|
-
def to_s
|
67
|
-
"#{definition.description}\n\n#{usage_section}\n#{options_section}\n"
|
68
|
-
end
|
69
|
-
end
|
70
|
-
end
|
71
|
-
end
|
@@ -1,52 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'eac_ruby_utils/core_ext'
|
4
|
-
require 'eac_cli/docopt_runner'
|
5
|
-
|
6
|
-
module EacCli
|
7
|
-
module Docopt
|
8
|
-
class DocBuilder
|
9
|
-
class Alternative
|
10
|
-
common_constructor :alternative
|
11
|
-
|
12
|
-
def to_s
|
13
|
-
(
|
14
|
-
[::EacCli::DocoptRunner::PROGRAM_MACRO] +
|
15
|
-
alternative.options_argument?.if_present([]) { |_v| ['[options]'] } +
|
16
|
-
options +
|
17
|
-
positionals
|
18
|
-
).join(::EacCli::Docopt::DocBuilder::SEP)
|
19
|
-
end
|
20
|
-
|
21
|
-
def options
|
22
|
-
alternative.options.select(&:show_on_usage?).map do |option|
|
23
|
-
::EacCli::Docopt::DocBuilder.option_long(option)
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
def option_argument(option)
|
28
|
-
b = option.long
|
29
|
-
b += '=<value>' if option.argument?
|
30
|
-
b
|
31
|
-
end
|
32
|
-
|
33
|
-
def positionals
|
34
|
-
alternative.positional.map { |p| positional(p) }.reject(&:blank?)
|
35
|
-
end
|
36
|
-
|
37
|
-
def positional(positional)
|
38
|
-
return unless positional.visible?
|
39
|
-
|
40
|
-
if positional.subcommand?
|
41
|
-
::EacCli::DocoptRunner::SUBCOMMANDS_MACRO
|
42
|
-
else
|
43
|
-
r = "<#{positional.name}>"
|
44
|
-
r += '...' if positional.repeat?
|
45
|
-
r = "[#{r}]" if positional.optional?
|
46
|
-
r
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|
50
|
-
end
|
51
|
-
end
|
52
|
-
end
|
@@ -1,51 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'eac_cli/docopt/doc_builder'
|
4
|
-
require 'eac_cli/docopt/runner_context_replacement'
|
5
|
-
require 'eac_cli/runner'
|
6
|
-
require 'eac_cli/docopt_runner'
|
7
|
-
|
8
|
-
module EacCli
|
9
|
-
module Docopt
|
10
|
-
module RunnerExtension
|
11
|
-
extend ::ActiveSupport::Concern
|
12
|
-
|
13
|
-
included do
|
14
|
-
prepend InstanceMethods
|
15
|
-
end
|
16
|
-
|
17
|
-
class << self
|
18
|
-
def check(klass)
|
19
|
-
return unless klass < ::EacCli::DocoptRunner
|
20
|
-
|
21
|
-
::EacCli::Runner.alias_runner_class_methods(klass, '', 'eac_cli')
|
22
|
-
::EacCli::Runner.alias_runner_class_methods(klass, 'original', '')
|
23
|
-
|
24
|
-
klass.include(self)
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
module InstanceMethods
|
29
|
-
def doc
|
30
|
-
::EacCli::Docopt::DocBuilder.new(self.class.runner_definition).to_s
|
31
|
-
end
|
32
|
-
|
33
|
-
def docopt_options
|
34
|
-
super.merge(options_first: self.class.runner_definition.options_first?)
|
35
|
-
end
|
36
|
-
|
37
|
-
def runner_context
|
38
|
-
@runner_context ||= ::EacCli::Docopt::RunnerContextReplacement.new(self)
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
def extra_available_subcommands
|
43
|
-
self.class.constants
|
44
|
-
.map { |name| self.class.const_get(name) }
|
45
|
-
.select { |c| c.instance_of? Class }
|
46
|
-
.select { |c| c.included_modules.include?(::EacCli::Runner) }
|
47
|
-
.map { |c| c.name.demodulize.underscore.dasherize }
|
48
|
-
end
|
49
|
-
end
|
50
|
-
end
|
51
|
-
end
|
@@ -1,38 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'eac_ruby_utils/core_ext'
|
4
|
-
require 'docopt'
|
5
|
-
|
6
|
-
module EacCli
|
7
|
-
class DocoptRunner
|
8
|
-
require_sub __FILE__
|
9
|
-
include ::EacCli::DocoptRunner::Context
|
10
|
-
|
11
|
-
class << self
|
12
|
-
def create(settings = {})
|
13
|
-
new(settings)
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
attr_reader :settings
|
18
|
-
|
19
|
-
def initialize(settings = {})
|
20
|
-
@settings = settings.with_indifferent_access.freeze
|
21
|
-
check_subcommands
|
22
|
-
end
|
23
|
-
|
24
|
-
def options
|
25
|
-
@options ||= ::Docopt.docopt(target_doc, docopt_options)
|
26
|
-
end
|
27
|
-
|
28
|
-
def parent
|
29
|
-
settings[:parent]
|
30
|
-
end
|
31
|
-
|
32
|
-
protected
|
33
|
-
|
34
|
-
def docopt_options
|
35
|
-
settings.slice(:version, :argv, :help, :options_first).to_sym_keys_hash
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
@@ -1,16 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module EacCli
|
4
|
-
class DocoptRunner
|
5
|
-
DOCOPT_ERROR_EXIT_CODE = 0xC0
|
6
|
-
|
7
|
-
class << self
|
8
|
-
def run(options = {})
|
9
|
-
create(options).send(:run)
|
10
|
-
rescue Docopt::Exit => e
|
11
|
-
STDERR.write(e.message + "\n")
|
12
|
-
::Kernel.exit(DOCOPT_ERROR_EXIT_CODE)
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
@@ -1,23 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module EacCli
|
4
|
-
class DocoptRunner
|
5
|
-
PROGRAM_MACRO = '__PROGRAM__'
|
6
|
-
|
7
|
-
def source_doc
|
8
|
-
setting_value(:doc)
|
9
|
-
end
|
10
|
-
|
11
|
-
def target_doc
|
12
|
-
source_doc.gsub(PROGRAM_MACRO, target_program_name).strip + "\n"
|
13
|
-
end
|
14
|
-
|
15
|
-
def source_program_name
|
16
|
-
setting_value(:program_name, false)
|
17
|
-
end
|
18
|
-
|
19
|
-
def target_program_name
|
20
|
-
[source_program_name, ENV['PROGRAM_NAME'], $PROGRAM_NAME].find(&:present?)
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
@@ -1,17 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'eac_ruby_utils/settings_provider'
|
4
|
-
|
5
|
-
module EacCli
|
6
|
-
class DocoptRunner
|
7
|
-
include ::EacRubyUtils::SettingsProvider
|
8
|
-
|
9
|
-
attr_reader :settings
|
10
|
-
|
11
|
-
private
|
12
|
-
|
13
|
-
def setting_value(key, required = true)
|
14
|
-
super(key, required: required, order: %w[method settings_object constant])
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
@@ -1,152 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'active_support/core_ext/string/inflections'
|
4
|
-
require 'shellwords'
|
5
|
-
|
6
|
-
module EacCli
|
7
|
-
class DocoptRunner
|
8
|
-
SUBCOMMAND_ARG = '<subcommand>'
|
9
|
-
SUBCOMMAND_ARGS_ARG = '<subcommand-args>'
|
10
|
-
SUBCOMMANDS_MACRO = '__SUBCOMMANDS__'
|
11
|
-
|
12
|
-
def subcommands?
|
13
|
-
source_doc.include?(SUBCOMMANDS_MACRO)
|
14
|
-
end
|
15
|
-
|
16
|
-
def check_subcommands
|
17
|
-
return unless subcommands?
|
18
|
-
|
19
|
-
singleton_class.include(SubcommandsSupport)
|
20
|
-
check_subcommands_arg
|
21
|
-
return if singleton_class.method_defined?(:run)
|
22
|
-
|
23
|
-
singleton_class.send(:alias_method, :run, :run_with_subcommand)
|
24
|
-
end
|
25
|
-
|
26
|
-
module SubcommandsSupport
|
27
|
-
EXTRA_AVAILABLE_SUBCOMMANDS_METHOD_NAME = :extra_available_subcommands
|
28
|
-
|
29
|
-
def check_subcommands_arg
|
30
|
-
if subcommand_arg_as_list?
|
31
|
-
singleton_class.include(SubcommandsSupport::SubcommandArgAsList)
|
32
|
-
else
|
33
|
-
singleton_class.include(SubcommandsSupport::SubcommandArgAsArg)
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
def run_with_subcommand
|
38
|
-
if subcommand_name
|
39
|
-
check_valid_subcommand
|
40
|
-
subcommand_run
|
41
|
-
else
|
42
|
-
run_without_subcommand
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
def subcommand
|
47
|
-
@subcommand ||= subcommand_class_name(subcommand_name).constantize.create(
|
48
|
-
argv: subcommand_args,
|
49
|
-
program_name: subcommand_program,
|
50
|
-
parent: self
|
51
|
-
)
|
52
|
-
end
|
53
|
-
|
54
|
-
def subcommand_run
|
55
|
-
if !subcommand.is_a?(::EacCli::DocoptRunner) &&
|
56
|
-
subcommand.respond_to?(:run_run)
|
57
|
-
subcommand.run_run
|
58
|
-
else
|
59
|
-
subcommand.run
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
def target_doc
|
64
|
-
super.gsub(SUBCOMMANDS_MACRO,
|
65
|
-
"#{target_doc_subcommand_arg} [#{SUBCOMMAND_ARGS_ARG}...]") +
|
66
|
-
"\n" + subcommands_target_doc
|
67
|
-
end
|
68
|
-
|
69
|
-
def docopt_options
|
70
|
-
super.merge(options_first: true)
|
71
|
-
end
|
72
|
-
|
73
|
-
def subcommand_class_name(subcommand)
|
74
|
-
"#{self.class.name}::#{subcommand.underscore.camelize}"
|
75
|
-
end
|
76
|
-
|
77
|
-
def subcommand_arg_as_list?
|
78
|
-
setting_value(:subcommand_arg_as_list, false) || false
|
79
|
-
end
|
80
|
-
|
81
|
-
def subcommand_args
|
82
|
-
options.fetch(SUBCOMMAND_ARGS_ARG)
|
83
|
-
end
|
84
|
-
|
85
|
-
def subcommand_program
|
86
|
-
subcommand_name
|
87
|
-
end
|
88
|
-
|
89
|
-
def available_subcommands
|
90
|
-
r = ::Set.new(setting_value(:subcommands, false) || auto_available_subcommands)
|
91
|
-
if respond_to?(EXTRA_AVAILABLE_SUBCOMMANDS_METHOD_NAME, true)
|
92
|
-
r += send(EXTRA_AVAILABLE_SUBCOMMANDS_METHOD_NAME)
|
93
|
-
end
|
94
|
-
r.sort
|
95
|
-
end
|
96
|
-
|
97
|
-
def auto_available_subcommands
|
98
|
-
self.class.constants
|
99
|
-
.map { |name| self.class.const_get(name) }
|
100
|
-
.select { |c| c.instance_of? Class }
|
101
|
-
.select { |c| c < ::EacCli::DocoptRunner }
|
102
|
-
.map { |c| c.name.demodulize.underscore.dasherize }
|
103
|
-
end
|
104
|
-
|
105
|
-
def run_without_subcommand
|
106
|
-
"Method #{__method__} should be overrided in #{self.class.name}"
|
107
|
-
end
|
108
|
-
|
109
|
-
protected
|
110
|
-
|
111
|
-
def check_valid_subcommand
|
112
|
-
return if available_subcommands.include?(subcommand_name)
|
113
|
-
|
114
|
-
raise ::Docopt::Exit, "\"#{subcommand_name}\" is not a valid subcommand" \
|
115
|
-
" (Valid: #{available_subcommands.join(', ')})"
|
116
|
-
end
|
117
|
-
|
118
|
-
module SubcommandArgAsArg
|
119
|
-
def target_doc_subcommand_arg
|
120
|
-
SUBCOMMAND_ARG
|
121
|
-
end
|
122
|
-
|
123
|
-
def subcommand_name
|
124
|
-
options.fetch(SUBCOMMAND_ARG)
|
125
|
-
end
|
126
|
-
|
127
|
-
def subcommands_target_doc
|
128
|
-
available_subcommands.inject("Subcommands:\n") do |a, e|
|
129
|
-
a + " #{e}\n"
|
130
|
-
end
|
131
|
-
end
|
132
|
-
end
|
133
|
-
|
134
|
-
module SubcommandArgAsList
|
135
|
-
def target_doc_subcommand_arg
|
136
|
-
'(' + available_subcommands.join('|') + ')'
|
137
|
-
end
|
138
|
-
|
139
|
-
def subcommand_name
|
140
|
-
available_subcommands.each do |subcommand|
|
141
|
-
return subcommand if options.fetch(subcommand)
|
142
|
-
end
|
143
|
-
nil
|
144
|
-
end
|
145
|
-
|
146
|
-
def subcommands_target_doc
|
147
|
-
"\n"
|
148
|
-
end
|
149
|
-
end
|
150
|
-
end
|
151
|
-
end
|
152
|
-
end
|
@@ -1,18 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module EacCli
|
4
|
-
class DocoptRunner
|
5
|
-
# Provides the method context which search and call a method in self and ancestor objects.
|
6
|
-
module Context
|
7
|
-
def context(method)
|
8
|
-
current = self
|
9
|
-
while current
|
10
|
-
return current.send(method) if current.respond_to?(method)
|
11
|
-
|
12
|
-
current = current.respond_to?(:parent) ? current.parent : nil
|
13
|
-
end
|
14
|
-
raise "Context method \"#{method}\" not found for #{self.class}"
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|