eac_tools 0.103.0 → 0.103.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (175) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +22 -27
  3. data/lib/eac_tools/version.rb +1 -1
  4. data/sub/avm-eac_redmine_base0/avm-eac_redmine_base0.gemspec +1 -1
  5. data/sub/avm-eac_redmine_base0/lib/avm/eac_redmine_base0/instances/apache_host.rb +0 -2
  6. data/sub/avm-eac_redmine_base0/lib/avm/eac_redmine_base0/instances/base/database.rb +0 -3
  7. data/sub/avm-eac_redmine_base0/lib/avm/eac_redmine_base0/instances/base/files.rb +0 -4
  8. data/sub/avm-eac_redmine_base0/lib/avm/eac_redmine_base0/instances/base/gitolite.rb +0 -3
  9. data/sub/avm-eac_redmine_base0/lib/avm/eac_redmine_base0/instances/base/install.rb +0 -3
  10. data/sub/avm-eac_redmine_base0/lib/avm/eac_redmine_base0/instances/base/nodejs.rb +0 -3
  11. data/sub/avm-eac_redmine_base0/lib/avm/eac_redmine_base0/instances/base/web.rb +0 -3
  12. data/sub/avm-eac_redmine_base0/lib/avm/eac_redmine_base0/instances/base.rb +1 -7
  13. data/sub/avm-eac_redmine_base0/lib/avm/eac_redmine_base0/instances/deploy.rb +0 -3
  14. data/sub/avm-eac_redmine_base0/lib/avm/eac_redmine_base0/instances/docker_image.rb +0 -6
  15. data/sub/avm-eac_redmine_base0/lib/avm/eac_redmine_base0/instances/rest_api/entity_base.rb +0 -4
  16. data/sub/avm-eac_redmine_base0/lib/avm/eac_redmine_base0/instances/rest_api/project.rb +0 -5
  17. data/sub/avm-eac_redmine_base0/lib/avm/eac_redmine_base0/instances/rest_api/root.rb +0 -4
  18. data/sub/avm-eac_redmine_base0/lib/avm/eac_redmine_base0/instances/rest_api/wiki_page.rb +0 -4
  19. data/sub/avm-eac_redmine_base0/lib/avm/eac_redmine_base0/instances/rest_api.rb +0 -4
  20. data/sub/avm-eac_redmine_base0/lib/avm/eac_redmine_base0/instances/runners/docker.rb +0 -2
  21. data/sub/avm-eac_redmine_base0/lib/avm/eac_redmine_base0/instances/runners/project/wiki_page/read.rb +0 -2
  22. data/sub/avm-eac_redmine_base0/lib/avm/eac_redmine_base0/instances/runners/project/wiki_page/write.rb +0 -2
  23. data/sub/avm-eac_redmine_base0/lib/avm/eac_redmine_base0/instances/runners/project/wiki_page.rb +0 -4
  24. data/sub/avm-eac_redmine_base0/lib/avm/eac_redmine_base0/instances/runners/project.rb +0 -4
  25. data/sub/avm-eac_redmine_base0/lib/avm/eac_redmine_base0/instances/runners/project_rename.rb +0 -3
  26. data/sub/avm-eac_redmine_base0/lib/avm/eac_redmine_base0/sources/base.rb +0 -4
  27. data/sub/avm-eac_redmine_base0/lib/avm/eac_redmine_base0/sources/core_update.rb +0 -6
  28. data/sub/avm-eac_redmine_base0/lib/avm/eac_redmine_base0/sources/runners/core_update.rb +0 -4
  29. data/sub/avm-eac_redmine_base0/lib/avm/eac_redmine_base0/sources/runners/docker.rb +0 -3
  30. data/sub/avm-eac_redmine_base0/lib/avm/eac_redmine_base0/version.rb +1 -1
  31. data/sub/avm-eac_redmine_base0/template/avm/eac_redmine_base0/instances/docker_image/Dockerfile.template +1 -0
  32. data/sub/eac_cli/eac_cli.gemspec +23 -0
  33. data/sub/eac_cli/lib/eac_cli/config/entry/options.rb +55 -0
  34. data/sub/eac_cli/lib/eac_cli/config/entry/undefined.rb +26 -0
  35. data/sub/eac_cli/lib/eac_cli/config/entry.rb +55 -0
  36. data/sub/eac_cli/lib/eac_cli/config.rb +15 -0
  37. data/sub/eac_cli/lib/eac_cli/core_ext.rb +4 -0
  38. data/sub/eac_cli/lib/eac_cli/default_runner.rb +12 -0
  39. data/sub/eac_cli/lib/eac_cli/definition/alternative.rb +101 -0
  40. data/sub/eac_cli/lib/eac_cli/definition/argument_option.rb +19 -0
  41. data/sub/eac_cli/lib/eac_cli/definition/boolean_option.rb +25 -0
  42. data/sub/eac_cli/lib/eac_cli/definition/error.rb +8 -0
  43. data/sub/eac_cli/lib/eac_cli/definition/option/initialize_args_parser.rb +48 -0
  44. data/sub/eac_cli/lib/eac_cli/definition/option.rb +70 -0
  45. data/sub/eac_cli/lib/eac_cli/definition/option_or_positional.rb +41 -0
  46. data/sub/eac_cli/lib/eac_cli/definition/positional.rb +50 -0
  47. data/sub/eac_cli/lib/eac_cli/definition.rb +104 -0
  48. data/sub/eac_cli/lib/eac_cli/enum.rb +42 -0
  49. data/sub/eac_cli/lib/eac_cli/old_configs/entry_reader.rb +76 -0
  50. data/sub/eac_cli/lib/eac_cli/old_configs/password_entry_reader.rb +14 -0
  51. data/sub/eac_cli/lib/eac_cli/old_configs/read_entry_options.rb +42 -0
  52. data/sub/eac_cli/lib/eac_cli/old_configs/store_passwords_entry_reader.rb +23 -0
  53. data/sub/eac_cli/lib/eac_cli/old_configs.rb +31 -0
  54. data/sub/eac_cli/lib/eac_cli/parser/alternative/any_options.rb +17 -0
  55. data/sub/eac_cli/lib/eac_cli/parser/alternative/argv.rb +19 -0
  56. data/sub/eac_cli/lib/eac_cli/parser/alternative/double_dash.rb +24 -0
  57. data/sub/eac_cli/lib/eac_cli/parser/alternative/long_options.rb +37 -0
  58. data/sub/eac_cli/lib/eac_cli/parser/alternative/option_argument.rb +29 -0
  59. data/sub/eac_cli/lib/eac_cli/parser/alternative/options.rb +29 -0
  60. data/sub/eac_cli/lib/eac_cli/parser/alternative/positionals.rb +30 -0
  61. data/sub/eac_cli/lib/eac_cli/parser/alternative/short_options.rb +54 -0
  62. data/sub/eac_cli/lib/eac_cli/parser/alternative.rb +99 -0
  63. data/sub/eac_cli/lib/eac_cli/parser/collector.rb +52 -0
  64. data/sub/eac_cli/lib/eac_cli/parser/error.rb +13 -0
  65. data/sub/eac_cli/lib/eac_cli/parser.rb +32 -0
  66. data/sub/eac_cli/lib/eac_cli/patches/object/runner_with.rb +22 -0
  67. data/sub/eac_cli/lib/eac_cli/patches/object.rb +5 -0
  68. data/sub/eac_cli/lib/eac_cli/patches.rb +3 -0
  69. data/sub/eac_cli/lib/eac_cli/rspec/setup.rb +41 -0
  70. data/sub/eac_cli/lib/eac_cli/rspec.rb +7 -0
  71. data/sub/eac_cli/lib/eac_cli/runner/after_class_methods.rb +34 -0
  72. data/sub/eac_cli/lib/eac_cli/runner/class_runner.rb +32 -0
  73. data/sub/eac_cli/lib/eac_cli/runner/context.rb +57 -0
  74. data/sub/eac_cli/lib/eac_cli/runner/context_responders/base.rb +22 -0
  75. data/sub/eac_cli/lib/eac_cli/runner/context_responders/parent.rb +24 -0
  76. data/sub/eac_cli/lib/eac_cli/runner/context_responders/runner.rb +17 -0
  77. data/sub/eac_cli/lib/eac_cli/runner/context_responders/runner_missing_method.rb +29 -0
  78. data/sub/eac_cli/lib/eac_cli/runner/context_responders/set.rb +41 -0
  79. data/sub/eac_cli/lib/eac_cli/runner/context_responders.rb +9 -0
  80. data/sub/eac_cli/lib/eac_cli/runner/exit.rb +14 -0
  81. data/sub/eac_cli/lib/eac_cli/runner/for_context.rb +35 -0
  82. data/sub/eac_cli/lib/eac_cli/runner/instance_methods.rb +45 -0
  83. data/sub/eac_cli/lib/eac_cli/runner.rb +47 -0
  84. data/sub/eac_cli/lib/eac_cli/runner_with/confirmation/input_result.rb +60 -0
  85. data/sub/eac_cli/lib/eac_cli/runner_with/confirmation.rb +65 -0
  86. data/sub/eac_cli/lib/eac_cli/runner_with/help/builder/alternative.rb +61 -0
  87. data/sub/eac_cli/lib/eac_cli/runner_with/help/builder.rb +79 -0
  88. data/sub/eac_cli/lib/eac_cli/runner_with/help/layout.rb +38 -0
  89. data/sub/eac_cli/lib/eac_cli/runner_with/help.rb +51 -0
  90. data/sub/eac_cli/lib/eac_cli/runner_with/input.rb +32 -0
  91. data/sub/eac_cli/lib/eac_cli/runner_with/output.rb +54 -0
  92. data/sub/eac_cli/lib/eac_cli/runner_with/output_item/asciidoc_formatter.rb +70 -0
  93. data/sub/eac_cli/lib/eac_cli/runner_with/output_item/base_formatter.rb +12 -0
  94. data/sub/eac_cli/lib/eac_cli/runner_with/output_item/csv_formatter.rb +21 -0
  95. data/sub/eac_cli/lib/eac_cli/runner_with/output_item/yaml_formatter.rb +16 -0
  96. data/sub/eac_cli/lib/eac_cli/runner_with/output_item.rb +47 -0
  97. data/sub/eac_cli/lib/eac_cli/runner_with/output_list/base_formatter.rb +44 -0
  98. data/sub/eac_cli/lib/eac_cli/runner_with/output_list/csv_formatter.rb +24 -0
  99. data/sub/eac_cli/lib/eac_cli/runner_with/output_list/tty_formatter.rb +34 -0
  100. data/sub/eac_cli/lib/eac_cli/runner_with/output_list/yaml_formatter.rb +21 -0
  101. data/sub/eac_cli/lib/eac_cli/runner_with/output_list.rb +39 -0
  102. data/sub/eac_cli/lib/eac_cli/runner_with/subcommands/definition_concern.rb +10 -0
  103. data/sub/eac_cli/lib/eac_cli/runner_with/subcommands.rb +124 -0
  104. data/sub/eac_cli/lib/eac_cli/runner_with.rb +7 -0
  105. data/sub/eac_cli/lib/eac_cli/runner_with_set.rb +54 -0
  106. data/sub/eac_cli/lib/eac_cli/speaker/constants.rb +11 -0
  107. data/sub/eac_cli/lib/eac_cli/speaker/input_blocked.rb +14 -0
  108. data/sub/eac_cli/lib/eac_cli/speaker/input_requested.rb +8 -0
  109. data/sub/eac_cli/lib/eac_cli/speaker/list.rb +84 -0
  110. data/sub/eac_cli/lib/eac_cli/speaker/options.rb +42 -0
  111. data/sub/eac_cli/lib/eac_cli/speaker/request_from_list.rb +40 -0
  112. data/sub/eac_cli/lib/eac_cli/speaker.rb +114 -0
  113. data/sub/eac_cli/lib/eac_cli/version.rb +5 -0
  114. data/sub/eac_cli/lib/eac_cli.rb +14 -0
  115. data/sub/eac_cli/spec/lib/eac_cli/definition/alternative_spec.rb +18 -0
  116. data/sub/eac_cli/spec/lib/eac_cli/old_configs_spec.rb +14 -0
  117. data/sub/eac_cli/spec/lib/eac_cli/parser/alternative/subcommands_spec.rb +58 -0
  118. data/sub/eac_cli/spec/lib/eac_cli/parser/alternative_spec.rb +89 -0
  119. data/sub/eac_cli/spec/lib/eac_cli/runner/for_context_spec.rb +79 -0
  120. data/sub/eac_cli/spec/lib/eac_cli/runner_spec.rb +129 -0
  121. data/sub/eac_cli/spec/lib/eac_cli/runner_with/confirmation/input_result_spec.rb +36 -0
  122. data/sub/eac_cli/spec/lib/eac_cli/runner_with/confirmation_spec.rb +42 -0
  123. data/sub/eac_cli/spec/lib/eac_cli/runner_with/help/layout_spec.rb +21 -0
  124. data/sub/eac_cli/spec/lib/eac_cli/runner_with/help_spec.rb +51 -0
  125. data/sub/eac_cli/spec/lib/eac_cli/runner_with/output_list_spec.rb +57 -0
  126. data/sub/eac_cli/spec/lib/eac_cli/runner_with/output_spec.rb +81 -0
  127. data/sub/eac_cli/spec/lib/eac_cli/runner_with/subcommands_spec.rb +99 -0
  128. data/sub/eac_cli/spec/lib/eac_cli/speaker_spec.rb +36 -0
  129. data/sub/{eac_docker → eac_cli}/spec/spec_helper.rb +1 -2
  130. metadata +108 -48
  131. data/sub/avm-eac_redmine_base0/lib/avm/eac_redmine_base0/instances/runners.rb +0 -14
  132. data/sub/avm-eac_redmine_base0/lib/avm/eac_redmine_base0/instances.rb +0 -11
  133. data/sub/avm-eac_redmine_base0/lib/avm/eac_redmine_base0/sources/runners.rb +0 -13
  134. data/sub/avm-eac_redmine_base0/lib/avm/eac_redmine_base0/sources.rb +0 -11
  135. data/sub/avm-eac_ubuntu_base0/avm-eac_ubuntu_base0.gemspec +0 -21
  136. data/sub/avm-eac_ubuntu_base0/lib/avm/eac_ubuntu_base0/apache/resource.rb +0 -57
  137. data/sub/avm-eac_ubuntu_base0/lib/avm/eac_ubuntu_base0/apache.rb +0 -24
  138. data/sub/avm-eac_ubuntu_base0/lib/avm/eac_ubuntu_base0/docker_image.rb +0 -31
  139. data/sub/avm-eac_ubuntu_base0/lib/avm/eac_ubuntu_base0/instances/base.rb +0 -24
  140. data/sub/avm-eac_ubuntu_base0/lib/avm/eac_ubuntu_base0/rspec/ssh_docker_server.rb +0 -82
  141. data/sub/avm-eac_ubuntu_base0/lib/avm/eac_ubuntu_base0/runners/base/docker.rb +0 -15
  142. data/sub/avm-eac_ubuntu_base0/lib/avm/eac_ubuntu_base0/runners/base.rb +0 -26
  143. data/sub/avm-eac_ubuntu_base0/lib/avm/eac_ubuntu_base0/version.rb +0 -7
  144. data/sub/avm-eac_ubuntu_base0/lib/avm/eac_ubuntu_base0.rb +0 -13
  145. data/sub/avm-eac_ubuntu_base0/spec/lib/avm/eac_ubuntu_base0/docker_image_spec.rb +0 -12
  146. data/sub/avm-eac_ubuntu_base0/spec/lib/avm/eac_ubuntu_base0/rspec/ssh_docker_server_spec.rb +0 -11
  147. data/sub/avm-eac_ubuntu_base0/spec/lib/avm/eac_ubuntu_base0/runners/base/docker_spec.rb +0 -11
  148. data/sub/avm-eac_ubuntu_base0/spec/lib/avm/eac_ubuntu_base0/runners/base_spec.rb +0 -5
  149. data/sub/avm-eac_ubuntu_base0/spec/spec_helper.rb +0 -5
  150. data/sub/avm-eac_ubuntu_base0/template/avm/eac_ubuntu_base0/docker_image/Dockerfile.template +0 -27
  151. data/sub/avm-eac_ubuntu_base0/template/avm/eac_ubuntu_base0/rspec/ssh_docker_server/Dockerfile.template +0 -24
  152. data/sub/avm-eac_ubuntu_base0/template/avm/eac_ubuntu_base0/rspec/ssh_docker_server/id_rsa +0 -27
  153. data/sub/avm-eac_ubuntu_base0/template/avm/eac_ubuntu_base0/rspec/ssh_docker_server/id_rsa.pub +0 -1
  154. data/sub/eac_docker/Gemfile +0 -8
  155. data/sub/eac_docker/eac_docker.gemspec +0 -20
  156. data/sub/eac_docker/lib/eac_docker/container.rb +0 -83
  157. data/sub/eac_docker/lib/eac_docker/debug.rb +0 -13
  158. data/sub/eac_docker/lib/eac_docker/executables.rb +0 -15
  159. data/sub/eac_docker/lib/eac_docker/images/base.rb +0 -11
  160. data/sub/eac_docker/lib/eac_docker/images/coded.rb +0 -39
  161. data/sub/eac_docker/lib/eac_docker/images/named.rb +0 -26
  162. data/sub/eac_docker/lib/eac_docker/images/templatized.rb +0 -43
  163. data/sub/eac_docker/lib/eac_docker/registry.rb +0 -15
  164. data/sub/eac_docker/lib/eac_docker/rspec/setup.rb +0 -15
  165. data/sub/eac_docker/lib/eac_docker/rspec/stub_image.rb +0 -39
  166. data/sub/eac_docker/lib/eac_docker/version.rb +0 -5
  167. data/sub/eac_docker/lib/eac_docker.rb +0 -9
  168. data/sub/eac_docker/spec/lib/eac_docker/executables_spec.rb +0 -7
  169. data/sub/eac_docker/spec/lib/eac_docker/images/coded_spec.rb +0 -10
  170. data/sub/eac_docker/spec/lib/eac_docker/images/coded_spec_files/image1/Dockerfile +0 -1
  171. data/sub/eac_docker/spec/lib/eac_docker/images/templatized_spec.rb +0 -15
  172. data/sub/eac_docker/spec/lib/eac_docker/images/templatized_spec_files/stub_docker_image/Dockerfile +0 -1
  173. data/sub/eac_docker/spec/rubocop_spec.rb +0 -3
  174. /data/sub/{avm-eac_ubuntu_base0 → eac_cli}/Gemfile +0 -0
  175. /data/sub/{avm-eac_ubuntu_base0 → eac_cli}/spec/rubocop_spec.rb +0 -0
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EacCli
4
+ module Runner
5
+ module ContextResponders
6
+ class Base
7
+ acts_as_abstract :call, :callable?
8
+ common_constructor :context, :method_name do
9
+ self.method_name = method_name.to_sym
10
+ end
11
+ delegate :parent, :runner, to: :context
12
+
13
+ def if_callable # rubocop:disable Naming/PredicateMethod
14
+ return false unless callable?
15
+
16
+ yield(self)
17
+ true
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EacCli
4
+ module Runner
5
+ module ContextResponders
6
+ class Parent < ::EacCli::Runner::ContextResponders::Base
7
+ def callable?
8
+ parent.if_present(false) do |v|
9
+ next true if v.respond_to?(method_name)
10
+
11
+ v.if_respond(:runner_context, false) { |w| w.parent_respond_to?(method_name) }
12
+ end
13
+ end
14
+
15
+ def call(*args, &block)
16
+ return parent.runner_context.call(method_name, *args, &block) if
17
+ parent.respond_to?(:runner_context)
18
+
19
+ raise "Parent #{parent} do not respond to .context or .runner_context (Runner: #{runner})"
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EacCli
4
+ module Runner
5
+ module ContextResponders
6
+ class Runner < ::EacCli::Runner::ContextResponders::Base
7
+ def callable?
8
+ runner.respond_to?(method_name)
9
+ end
10
+
11
+ def call(*args, &block)
12
+ runner.send(method_name, *args, &block)
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EacCli
4
+ module Runner
5
+ module ContextResponders
6
+ class RunnerMissingMethod < ::EacCli::Runner::ContextResponders::Base
7
+ def callable?
8
+ responder_runner.present?
9
+ end
10
+
11
+ def call(*args, &block)
12
+ responder_runner.send(method_name, *args, &block)
13
+ end
14
+
15
+ private
16
+
17
+ def responder_runner
18
+ parent.if_present(nil) do |v|
19
+ next v if v.respond_to?(method_name) && v.for_context?(method_name)
20
+
21
+ v.if_respond(:runner_context, nil) do |w|
22
+ w.runner_missing_method_responder(method_name).send(__method__)
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EacCli
4
+ module Runner
5
+ module ContextResponders
6
+ class Set < ::EacCli::Runner::ContextResponders::Base
7
+ attr_reader :responders_names
8
+
9
+ def initialize(context, method_name, responders_names)
10
+ super(context, method_name)
11
+ @responders_names = responders_names
12
+ end
13
+
14
+ def callable?
15
+ responders_instances.any?(&:callable?)
16
+ end
17
+
18
+ def call(...)
19
+ caller = responder_to_call
20
+ return caller.call(...) if caller
21
+
22
+ raise ::NameError, "No method \"#{method_name}\" found in #{runner} or in its ancestors"
23
+ end
24
+
25
+ private
26
+
27
+ def responder_class(class_name)
28
+ ::EacCli::Runner::ContextResponders.const_get(class_name.to_s.camelize)
29
+ end
30
+
31
+ def responders_instances
32
+ responders_names.lazy.map { |name| responder_class(name).new(context, method_name) }
33
+ end
34
+
35
+ def responder_to_call
36
+ responders_instances.lazy.select(&:callable?).first
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EacCli
4
+ module Runner
5
+ module ContextResponders
6
+ require_sub __FILE__
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EacCli
4
+ module Runner
5
+ class Exit < ::StandardError
6
+ attr_reader :status
7
+
8
+ def initialize(status = true) # rubocop:disable Style/OptionalBooleanParameter
9
+ super
10
+ @status = status
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EacCli
4
+ module Runner
5
+ module ForContext
6
+ common_concern
7
+
8
+ module ClassMethods
9
+ # @param methods_names [Enumerable<Symbol>]
10
+ # @return [void]
11
+ def for_context(*methods_names)
12
+ for_context_methods.merge(methods_names.map(&:to_sym))
13
+ end
14
+
15
+ # @param method_name [Symbol]
16
+ # @return [Boolean]
17
+ def for_context?(method_name)
18
+ for_context_methods.include?(method_name.to_sym)
19
+ end
20
+
21
+ private
22
+
23
+ # @return [EacRubyUtils::ModuleAncestorsVariable::Set<Symbol>]
24
+ def for_context_methods
25
+ @for_context_methods ||=
26
+ ::EacRubyUtils::ModuleAncestorsVariable::Set.new(self, __method__)
27
+ end
28
+ end
29
+
30
+ # @param method_name [Symbol]
31
+ # @return [Boolean]
32
+ delegate :for_context?, to: :class
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EacCli
4
+ module Runner
5
+ module InstanceMethods
6
+ def run_run
7
+ parsed
8
+ run_callbacks(:run) { run }
9
+ rescue ::EacCli::Runner::Exit
10
+ # Do nothing
11
+ end
12
+
13
+ def runner_context
14
+ return @runner_context if @runner_context
15
+
16
+ raise 'Context was required, but was not set yet'
17
+ end
18
+
19
+ def runner_context=(new_runner_context)
20
+ @runner_context = new_runner_context
21
+ @parsed = nil
22
+ end
23
+
24
+ def parsed
25
+ @parsed ||= ::EacCli::Parser.new(self.class.runner_definition, runner_context.argv).parsed
26
+ end
27
+
28
+ def program_name
29
+ runner_context.if_present(&:program_name) || $PROGRAM_NAME
30
+ end
31
+
32
+ def respond_to_missing?(method, include_all = false)
33
+ runner_context.runner_missing_method_responder(method).callable? || super
34
+ end
35
+
36
+ def method_missing(method, *args, &block)
37
+ runner_context.runner_missing_method_responder(method).if_callable do |v|
38
+ return v.call(*args, &block)
39
+ end
40
+
41
+ super
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EacCli
4
+ module Runner
5
+ require_sub __FILE__
6
+ extend ::ActiveSupport::Concern
7
+
8
+ class << self
9
+ def alias_runner_class_methods(klass, from_suffix, to_suffix)
10
+ %i[create run].each do |method|
11
+ alias_class_method(klass, build_method_name(method, from_suffix),
12
+ build_method_name(method, to_suffix))
13
+ end
14
+ end
15
+
16
+ def runner?(object)
17
+ object.is_a?(::Class) && object.included_modules.include?(::EacCli::Runner)
18
+ end
19
+
20
+ private
21
+
22
+ def alias_class_method(klass, from, to)
23
+ sklass = klass.singleton_class
24
+ return unless sklass.method_defined?(from)
25
+
26
+ sklass.send(:alias_method, to, from)
27
+ end
28
+
29
+ def build_method_name(name, suffix)
30
+ ss = suffix.if_present('') { |s| "#{s}_" }
31
+ "#{ss}#{name}"
32
+ end
33
+ end
34
+
35
+ the_module = self
36
+ included do
37
+ the_module.alias_runner_class_methods(self, '', 'original')
38
+
39
+ extend AfterClassMethods
40
+ include InstanceMethods
41
+ include ::EacCli::Runner::ForContext
42
+ include ActiveSupport::Callbacks
43
+
44
+ define_callbacks :run
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EacCli
4
+ module RunnerWith
5
+ module Confirmation
6
+ class InputResult
7
+ INPUT_NO_FOR_ONE = 'n'
8
+ INPUT_NO_FOR_ALL = 'N'
9
+ INPUT_YES_FOR_ONE = 'y'
10
+ INPUT_YES_FOR_ALL = 'Y'
11
+ INPUT_FOR_ONE = [INPUT_NO_FOR_ONE, INPUT_YES_FOR_ONE].freeze
12
+ INPUT_FOR_ALL = [INPUT_NO_FOR_ALL, INPUT_YES_FOR_ALL].freeze
13
+ INPUT_NO = [INPUT_NO_FOR_ONE, INPUT_NO_FOR_ALL].freeze
14
+ INPUT_YES = [INPUT_YES_FOR_ONE, INPUT_YES_FOR_ALL].freeze
15
+ INPUT_LIST = [INPUT_NO_FOR_ALL, INPUT_NO_FOR_ONE, INPUT_YES_FOR_ONE, INPUT_YES_FOR_ALL]
16
+ .freeze
17
+
18
+ class << self
19
+ enable_speaker
20
+
21
+ # @param message [String]
22
+ # @return [EacCli::RunnerWith::Confirmation::InputResult]
23
+ def by_message(message)
24
+ new(input_value_by_speaker(message))
25
+ end
26
+
27
+ # @param message [String]
28
+ # @return [String]
29
+ def input_value_by_speaker(message)
30
+ input(message, list: INPUT_LIST, ignore_case: false)
31
+ end
32
+ end
33
+
34
+ common_constructor :input_value
35
+
36
+ # @return [Boolean]
37
+ def confirm?
38
+ input_value_to_bool(INPUT_NO, INPUT_YES)
39
+ end
40
+
41
+ # @return [Boolean]
42
+ def for_all?
43
+ input_value_to_bool(INPUT_FOR_ONE, INPUT_FOR_ALL)
44
+ end
45
+
46
+ private
47
+
48
+ # @param false_list [Array<String>]
49
+ # @param true_list [Array<String>]
50
+ # @return [Boolean]
51
+ def input_value_to_bool(false_list, true_list)
52
+ return false if false_list.include?(input_value)
53
+ return true if true_list.include?(input_value)
54
+
55
+ ibr input_value
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,65 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EacCli
4
+ module RunnerWith
5
+ module Confirmation
6
+ DEFAULT_CONFIRM_QUESTION_TEXT = 'Confirm?'
7
+
8
+ common_concern do
9
+ include ::EacCli::Runner
10
+
11
+ enable_settings_provider
12
+ enable_simple_cache
13
+ runner_definition do
14
+ bool_opt '--no', 'Deny confirmation without question.'
15
+ bool_opt '--yes', 'Accept confirmation without question.'
16
+ end
17
+ end
18
+
19
+ # @param message [String, nil]
20
+ # @return [Boolean]
21
+ def confirm?(message = nil)
22
+ return for_all_answers.fetch(message) if for_all_answers.key?(message)
23
+ return false if parsed.no?
24
+ return true if parsed.yes?
25
+
26
+ confirm_input_and_register(message)
27
+ rescue ::EacCli::Speaker::InputRequested => e
28
+ fatal_error e.message
29
+ end
30
+
31
+ def run_confirm(message = nil)
32
+ yield if confirm?(message)
33
+ end
34
+
35
+ private
36
+
37
+ def cached_confirm_uncached?(message = nil)
38
+ confirm?(message)
39
+ end
40
+
41
+ # @param message [String, nil]
42
+ # @return [Boolean]
43
+ def confirm_input(message)
44
+ ::EacCli::RunnerWith::Confirmation::InputResult.by_message(
45
+ message || setting_value(:confirm_question_text, default: DEFAULT_CONFIRM_QUESTION_TEXT)
46
+ )
47
+ end
48
+
49
+ # @param message [String, nil]
50
+ # @return [Boolean]
51
+ def confirm_input_and_register(message) # rubocop:disable Naming/PredicateMethod
52
+ r = confirm_input(message)
53
+ for_all_answers[message] = r.confirm? if r.for_all?
54
+ r.confirm?
55
+ end
56
+
57
+ # @return [Hash<String, Boolean>]
58
+ def for_all_answers_uncached
59
+ {}
60
+ end
61
+
62
+ require_sub __FILE__
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,61 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EacCli
4
+ module RunnerWith
5
+ module Help
6
+ class Builder
7
+ class Alternative
8
+ enable_method_class
9
+
10
+ SUBCOMMANDS_MACRO = '__SUBCOMMANDS__'
11
+
12
+ common_constructor :builder, :alternative
13
+
14
+ def result
15
+ (
16
+ program_name +
17
+ alternative.options_argument?.if_present([]) { |_v| ['[options]'] } +
18
+ options +
19
+ positionals
20
+ ).join(builder.word_separator)
21
+ end
22
+
23
+ def options
24
+ alternative.options.select(&:show_on_usage?).map do |option|
25
+ ::EacCli::RunnerWith::Help::Builder.option_long(option)
26
+ end
27
+ end
28
+
29
+ def option_argument(option)
30
+ b = option.long
31
+ b += '=<value>' if option.argument?
32
+ b
33
+ end
34
+
35
+ def positionals
36
+ alternative.positional.map { |p| positional(p) }.compact_blank
37
+ end
38
+
39
+ def positional(positional)
40
+ return unless positional.visible?
41
+
42
+ if positional.subcommand?
43
+ SUBCOMMANDS_MACRO
44
+ else
45
+ r = "<#{positional.name}>"
46
+ r += '...' if positional.repeat?
47
+ r = "[#{r}]" if positional.optional?
48
+ r
49
+ end
50
+ end
51
+
52
+ def program_name
53
+ r = builder.runner.program_name
54
+ r = [r] unless r.is_a?(::Enumerable)
55
+ r
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,79 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EacCli
4
+ module RunnerWith
5
+ module Help
6
+ class Builder
7
+ include ::EacCli::RunnerWith::Help::Layout
8
+
9
+ require_sub __FILE__, require_mode: :kernel
10
+ common_constructor :runner
11
+
12
+ class << self
13
+ def option_long(option)
14
+ b = option.long
15
+ b += '=<value>' if option.argument?
16
+ b
17
+ end
18
+
19
+ def option_short(option)
20
+ b = option.short
21
+ b += '=<value>' if option.argument?
22
+ b
23
+ end
24
+
25
+ def option_usage_full(option)
26
+ if option.long.present?
27
+ [option.short, option_long(option)].compact_blank.join(word_separator)
28
+ else
29
+ option_short(option)
30
+ end
31
+ end
32
+
33
+ def word_separator
34
+ WORD_SEPARATOR
35
+ end
36
+ end
37
+
38
+ delegate :word_separator, to: :class
39
+
40
+ def definition
41
+ runner.class.runner_definition
42
+ end
43
+
44
+ # @return [Enumerable<String>]
45
+ def extra_sections
46
+ runner.if_respond(:help_extra_text, []) do |v|
47
+ [v.to_s]
48
+ end
49
+ end
50
+
51
+ def option_definition(option)
52
+ [self.class.option_usage_full(option), option.description,
53
+ option.default_value? ? "[Default: \"#{option.default_value}\"]" : nil]
54
+ .compact_blank.join(OPTION_DESCRIPTION_SEPARATOR)
55
+ end
56
+
57
+ # @return [String]
58
+ def options_section
59
+ list_section(
60
+ 'Options',
61
+ definition.alternatives.flat_map(&:options).map { |option| option_definition(option) }
62
+ )
63
+ end
64
+
65
+ # @return [String]
66
+ def usage_section
67
+ list_section(
68
+ 'Usage',
69
+ definition.alternatives.map { |alternative| self.alternative(alternative) }
70
+ )
71
+ end
72
+
73
+ def to_s
74
+ join_sections(definition.description, usage_section, options_section, *extra_sections)
75
+ end
76
+ end
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EacCli
4
+ module RunnerWith
5
+ module Help
6
+ module Layout
7
+ common_concern do
8
+ include InstanceClassMethods
9
+ extend InstanceClassMethods
10
+ end
11
+
12
+ module InstanceClassMethods
13
+ WORD_SEPARATOR = ' '
14
+ IDENTATION = WORD_SEPARATOR * 2
15
+ OPTION_DESCRIPTION_SEPARATOR = IDENTATION * 2
16
+ LINE_BREAK = "\n"
17
+ SECTION_SEPARATOR = LINE_BREAK * 2
18
+
19
+ # @param title String
20
+ # @param items [Enumerable<String>]
21
+ # @return [String]
22
+ def list_section(title, items)
23
+ (["#{title}:"] + items.map { |line| "#{IDENTATION}#{line}" })
24
+ .map { |line| "#{line}\n" }.join
25
+ end
26
+
27
+ # @param sections [Enumerable<String>]
28
+ # @return [String]
29
+ def join_sections(*sections)
30
+ sections.map { |s| s.to_s.strip }.join(SECTION_SEPARATOR) + LINE_BREAK
31
+ end
32
+ end
33
+
34
+ extend InstanceClassMethods
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EacCli
4
+ module RunnerWith
5
+ module Help
6
+ require_sub __FILE__, require_mode: :kernel
7
+ common_concern do
8
+ include ::EacCli::Runner
9
+ include ::EacCli::RunnerWith::Help::Layout
10
+
11
+ runner_definition.alt do
12
+ bool_opt '-h', '--help', 'Show help.', usage: true, required: true
13
+ any_opt
14
+ pos_arg :any_arg_with_help, repeat: true, optional: true, visible: false
15
+ end
16
+
17
+ set_callback :run, :before do
18
+ help_run
19
+ end
20
+ end
21
+
22
+ # @param items [Enumerable<String>]
23
+ # @return [String]
24
+ def help_list_section(title, items)
25
+ ::EacCli::RunnerWith::Help::Layout.list_section(title, items)
26
+ end
27
+
28
+ # @param items [Enumerable<String>]
29
+ # @return [String]
30
+ def help_join_sections(*sections)
31
+ ::EacCli::RunnerWith::Help::Layout.join_sections(*sections)
32
+ end
33
+
34
+ def help_run
35
+ return unless show_help?
36
+
37
+ puts help_text
38
+ raise ::EacCli::Runner::Exit
39
+ end
40
+
41
+ # @return [String]
42
+ def help_text
43
+ ::EacCli::RunnerWith::Help::Builder.new(self).to_s
44
+ end
45
+
46
+ def show_help?
47
+ parsed.help? && !if_respond(:run_subcommand?, false)
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EacCli
4
+ module RunnerWith
5
+ module Input
6
+ STDIN_OPTION = '-'
7
+ BLANK_OPTION = '+'
8
+ DEFAULT_DEFAULT_INPUT_OPTION = BLANK_OPTION
9
+
10
+ common_concern do
11
+ enable_settings_provider
12
+ include ::EacCli::Runner
13
+
14
+ runner_definition do
15
+ arg_opt '-i', '--input', 'Input from file.'
16
+ end
17
+ end
18
+
19
+ def input_content
20
+ case input_option
21
+ when STDIN_OPTION then $stdin.read
22
+ when BLANK_OPTION then ''
23
+ else input_option.to_pathname.read
24
+ end
25
+ end
26
+
27
+ def input_option
28
+ parsed.input || setting_value(:default_input_option, default: DEFAULT_DEFAULT_INPUT_OPTION)
29
+ end
30
+ end
31
+ end
32
+ end