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,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EacCli
4
+ class OldConfigs
5
+ require_sub __FILE__
6
+ enable_speaker
7
+
8
+ class << self
9
+ delegate :entry_key_to_envvar_name, to: :'::EacCli::OldConfigs::EntryReader'
10
+ end
11
+
12
+ attr_reader :configs
13
+
14
+ def initialize(configs_key, options = {})
15
+ options.assert_argument(::Hash, 'options')
16
+ @configs = ::EacConfig::OldConfigs.new(configs_key, options.merge(autosave: true))
17
+ end
18
+
19
+ def read_password(entry_key, options = {})
20
+ ::EacCli::OldConfigs::PasswordEntryReader.new(self, entry_key, options).read
21
+ end
22
+
23
+ def read_entry(entry_key, options = {})
24
+ ::EacCli::OldConfigs::EntryReader.new(self, entry_key, options).read
25
+ end
26
+
27
+ def store_passwords?
28
+ ::EacCli::OldConfigs::StorePasswordsEntryReader.new(self) == 'yes'
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EacCli
4
+ class Parser
5
+ class Alternative
6
+ module AnyOptions
7
+ delegate :any_option?, to: :alternative
8
+
9
+ # @return [EacCli::Definition::BooleanOption] if #any_option? is true.
10
+ # @raise [EacCli::Parser::Error] if #any_option? is false.
11
+ def any_option_collect_option
12
+ any_option? ? alternative.any_options_option : raise_argv_current_invalid_option
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EacCli
4
+ class Parser
5
+ class Alternative
6
+ module Argv
7
+ # @return [Enumerator<String>]
8
+ def argv_enum
9
+ @argv_enum ||= argv.each
10
+ end
11
+
12
+ # @return [Boolean]
13
+ def argv_pending?
14
+ argv_enum.ongoing?
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EacCli
4
+ class Parser
5
+ class Alternative
6
+ module DoubleDash
7
+ DOUBLE_DASH = '--'
8
+
9
+ private
10
+
11
+ attr_accessor :double_dash
12
+
13
+ def argv_current_double_dash?
14
+ argv_enum.peek == DOUBLE_DASH && !double_dash
15
+ end
16
+
17
+ def double_dash_collect_argv_value
18
+ self.phase = PHASE_POSITIONAL
19
+ self.double_dash = true
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EacCli
4
+ class Parser
5
+ class Alternative
6
+ module LongOptions
7
+ LONG_OPTION_PREFIX = '--'
8
+ OPTION_WITH_ARGUMENT_PATTERN = /\A([^=]+)(?:=(.*))\z/.freeze
9
+
10
+ private
11
+
12
+ def argv_current_long_option?
13
+ phase == PHASE_ANY && argv_enum.peek.start_with?(LONG_OPTION_PREFIX) &&
14
+ !argv_current_double_dash?
15
+ end
16
+
17
+ def long_option_collect_argv_value
18
+ option_long, value = parse_option_current_argv
19
+ alternative.options.any? do |option|
20
+ next false unless option.long == option_long
21
+
22
+ if value.nil?
23
+ option_collect_option(option)
24
+ else
25
+ option_argument_collect(option, value)
26
+ end
27
+ end || any_option_collect_option
28
+ end
29
+
30
+ def parse_option_current_argv
31
+ m = OPTION_WITH_ARGUMENT_PATTERN.match(argv_enum.peek)
32
+ m ? [m[1], m[2].if_present('')] : [argv_enum.peek, nil]
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EacCli
4
+ class Parser
5
+ class Alternative
6
+ module OptionArgument
7
+ private
8
+
9
+ attr_accessor :argument_option
10
+
11
+ def argument_option_collect_argv(option)
12
+ self.argument_option = option
13
+ self.phase = PHASE_OPTION_ARGUMENT
14
+ end
15
+
16
+ def option_argument_collect(option, value)
17
+ collector.collect(option, value)
18
+ self.argument_option = nil
19
+ self.phase = PHASE_ANY
20
+ option
21
+ end
22
+
23
+ def option_argument_collect_argv_value
24
+ option_argument_collect(argument_option, argv_enum.peek)
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EacCli
4
+ class Parser
5
+ class Alternative
6
+ module Options
7
+ private
8
+
9
+ def boolean_option_collect_argv(option)
10
+ collector.collect(option, true)
11
+ end
12
+
13
+ def option_collect_option(option)
14
+ if option.argument?
15
+ argument_option_collect_argv(option)
16
+ else
17
+ boolean_option_collect_argv(option)
18
+ end
19
+
20
+ option
21
+ end
22
+
23
+ def raise_argv_current_invalid_option
24
+ raise_error "Invalid option: \"#{argv_enum.peek}\""
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EacCli
4
+ class Parser
5
+ class Alternative
6
+ module Positionals
7
+ private
8
+
9
+ def positional_collect_argv_value
10
+ positional_check
11
+ collector.collect(positional_enum.peek, argv_enum.peek)
12
+ positional_next
13
+ end
14
+
15
+ def positional_enum
16
+ @positional_enum ||= alternative.positional.each
17
+ end
18
+
19
+ def positional_check
20
+ raise_error("Invalid positional: #{argv_enum.peek}") if positional_enum.stopped?
21
+ end
22
+
23
+ def positional_next
24
+ self.phase = PHASE_POSITIONAL if positional_enum.peek.subcommand?
25
+ positional_enum.next unless positional_enum.peek.repeat?
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EacCli
4
+ class Parser
5
+ class Alternative
6
+ module ShortOptions
7
+ SHORT_OPTION_PREFIX = '-'
8
+ SHORT_OPTION_CHAR_PATTERN = /\A[0-9a-zA-Z]\z/.freeze
9
+
10
+ private
11
+
12
+ # @return [Boolean]
13
+ def argv_current_short_option?
14
+ phase == PHASE_ANY && argv_enum.peek.start_with?(SHORT_OPTION_PREFIX) &&
15
+ !argv_current_long_option?
16
+ end
17
+
18
+ # @para char [String]
19
+ # @return [EacCli::Definition::Option, nil]
20
+ def find_short_option(char)
21
+ alternative.options.find do |option|
22
+ short_without_prefix(option.short).if_present(false) { |v| v == char }
23
+ end
24
+ end
25
+
26
+ # @return [void]
27
+ def short_option_collect_argv_value
28
+ last_option = nil
29
+ short_without_prefix(argv_enum.peek).each_char do |char|
30
+ raise_error "Invalid option: \"#{char}\"" unless SHORT_OPTION_CHAR_PATTERN.match?(char)
31
+ raise_error "Option \"#{last_option}\" requires a argument not provided" if
32
+ last_option.present?
33
+
34
+ collected_option = short_option_collect_char(char)
35
+ last_option = collected_option if collected_option.argument?
36
+ end
37
+ end
38
+
39
+ # @param char [String]
40
+ # @return [EacCli::Definition::Option] The option collected.
41
+ def short_option_collect_char(char)
42
+ option = find_short_option(char)
43
+ option ? option_collect_option(option) : any_option_collect_option
44
+ end
45
+
46
+ # @param short [String]
47
+ # @return [String]
48
+ def short_without_prefix(short)
49
+ short.to_s.gsub(/\A#{::Regexp.quote(SHORT_OPTION_PREFIX)}/, '')
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,99 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EacCli
4
+ class Parser
5
+ class Alternative
6
+ require_sub __FILE__, include_modules: true
7
+ enable_listable
8
+ lists.add_symbol :phase, :any, :option_argument, :positional
9
+
10
+ # @return [EacCli::Parser::Error, nil]
11
+ attr_reader :error
12
+
13
+ # @!method initialize(alternative, argv)
14
+ # @param alternative [EacCli::Definition::Alternative]
15
+ # @param argv [Array<String>]
16
+ common_constructor :alternative, :argv do
17
+ alternative.assert_argument(::EacCli::Definition::Alternative, :alternative)
18
+ self.phase = PHASE_ANY
19
+ collect
20
+ end
21
+
22
+ # @return [Boolean]
23
+ def error?
24
+ error.present?
25
+ end
26
+
27
+ # @return [Boolean]
28
+ def success?
29
+ !error?
30
+ end
31
+
32
+ # @return [EacRubyUtils::Struct]
33
+ def parsed
34
+ @parsed ||= collector.to_data.freeze
35
+ end
36
+
37
+ private
38
+
39
+ # @return [Symbol]
40
+ attr_accessor :phase
41
+
42
+ # @return [void]
43
+ def any_collect_argv_value
44
+ %w[double_dash long_option short_option].each do |arg_type|
45
+ return send("#{arg_type}_collect_argv_value") if send("argv_current_#{arg_type}?")
46
+ end
47
+
48
+ positional_collect_argv_value
49
+ end
50
+
51
+ # @return [EacCli::Parser::Collector]
52
+ def collector
53
+ @collector ||= ::EacCli::Parser::Collector.new(alternative)
54
+ end
55
+
56
+ # @return [void]
57
+ def collect
58
+ loop do
59
+ break unless argv_pending?
60
+
61
+ collect_argv_value
62
+ end
63
+ validate
64
+ rescue ::EacCli::Parser::Error => e
65
+ @error = e
66
+ end
67
+
68
+ # @return [void]
69
+ def collect_argv_value
70
+ send("#{phase}_collect_argv_value")
71
+ argv_enum.next
72
+ end
73
+
74
+ # @param message [String]
75
+ # @raise [EacCli::Parser::Error] Always.
76
+ def raise_error(message)
77
+ raise ::EacCli::Parser::Error.new(alternative, argv, message)
78
+ end
79
+
80
+ # @return [void]
81
+ # @raise [EacCli::Parser::Error] If options where not properly supplied.
82
+ def validate
83
+ (alternative.options + alternative.positional).each do |option|
84
+ validate_option(option)
85
+ end
86
+ end
87
+
88
+ # @param option [EacCli::Definition::Option, EacCli::Definition::Positional]
89
+ # @return [void]
90
+ # @raise [EacCli::Parser::Error] If option was not properly supplied.
91
+ def validate_option(option)
92
+ return unless option.required?
93
+ return if collector.supplied?(option)
94
+
95
+ raise_error("Required option/positional #{option} not supplied")
96
+ end
97
+ end
98
+ end
99
+ end
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EacCli
4
+ class Parser
5
+ class Collector
6
+ class << self
7
+ def to_data(definition)
8
+ collector = new(definition)
9
+ yield(collector)
10
+ collector.to_data
11
+ end
12
+ end
13
+
14
+ # @!method initialize(definition)
15
+ # @param definition [EacCli::Definition]
16
+ common_constructor :definition do
17
+ default_values
18
+ end
19
+
20
+ # @return [EacRubyUtils::Struct]
21
+ def to_data
22
+ ::EacRubyUtils::Struct.new(data.transform_keys(&:identifier))
23
+ end
24
+
25
+ # @param option [EacCli::Definition::Option]
26
+ # @param value [String]
27
+ # @return [void]
28
+ def collect(option, value)
29
+ data[option] = option.build_value(value, data[option])
30
+ end
31
+
32
+ # @param option [EacCli::Definition::Option]
33
+ # @return [Boolean]
34
+ def supplied?(option)
35
+ data[option].present?
36
+ end
37
+
38
+ private
39
+
40
+ # @return [Hash]
41
+ def data
42
+ @data ||= {}
43
+ end
44
+
45
+ # @return [void]
46
+ def default_values
47
+ definition.options.each { |option| data[option] = option.default_value }
48
+ definition.positional.each { |positional| data[positional] = positional.default_value }
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EacCli
4
+ class Parser
5
+ class Error < ::StandardError
6
+ def initialize(definition, argv, message)
7
+ @definition = definition
8
+ @argv = argv
9
+ super(message)
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EacCli
4
+ class Parser
5
+ require_sub __FILE__
6
+ enable_simple_cache
7
+ common_constructor :definition, :argv
8
+
9
+ private
10
+
11
+ def parsed_uncached
12
+ raise 'Definition has no alternatives' if alternatives.empty?
13
+ raise first_error unless alternatives.any?(&:success?)
14
+
15
+ alternatives_parsed(true).merge(alternatives_parsed(false))
16
+ end
17
+
18
+ def alternatives_parsed(error)
19
+ alternatives.select { |a| error == a.error? }.map(&:parsed).reverse
20
+ .inject(::EacRubyUtils::Struct.new) { |a, e| a.merge(e) }
21
+ end
22
+
23
+ def alternatives_uncached
24
+ definition.alternatives
25
+ .map { |alternative| ::EacCli::Parser::Alternative.new(alternative, argv) }
26
+ end
27
+
28
+ def first_error_uncached
29
+ alternatives.lazy.select(&:error?).map(&:error).first
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Object
4
+ def runner_with(*runners, &block)
5
+ include ::EacCli::Runner
6
+
7
+ enable_simple_cache
8
+ enable_speaker
9
+ runners.each do |runner|
10
+ include ::EacCli::RunnerWithSet.default.item_to_module(runner)
11
+ end
12
+ runner_definition(&block) if block
13
+ end
14
+
15
+ private
16
+
17
+ def runner_with_to_module(runner)
18
+ return runner if runner.is_a?(::Module)
19
+
20
+ "EacCli::RunnerWith::#{runner.to_s.camelize}".constantize
21
+ end
22
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ Dir["#{File.dirname(__FILE__)}/#{File.basename(__FILE__, '.*')}/*.rb"].sort.each do |path|
4
+ require path
5
+ end
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ EacRubyUtils.require_sub(__FILE__)
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EacCli
4
+ module Rspec
5
+ module Setup
6
+ def disable_input_request
7
+ disable_config_input_request
8
+ disable_speaker_input_request
9
+ end
10
+
11
+ def disable_config_input_request
12
+ rspec_config.before do
13
+ # Fixes EacCli::Config::Entry does not implement #input_value error
14
+ ::EacCli::Config::Entry.define_method(:input_value) do
15
+ super
16
+ end
17
+ allow_any_instance_of(::EacCli::Config::Entry).to receive(:input_value) do |obj|
18
+ raise "Console input requested for entry (Path: #{obj.path})"
19
+ end
20
+ end
21
+ end
22
+
23
+ def disable_speaker_input_request
24
+ ::RSpec.configure do |config|
25
+ config.around do |example|
26
+ ::EacRubyUtils::Speaker
27
+ .context.on(::EacCli::Speaker.new(in_in: FailIfRequestInput.new)) { example.run }
28
+ end
29
+ end
30
+ end
31
+
32
+ class FailIfRequestInput
33
+ %w[gets noecho].each do |method|
34
+ define_method(method) do
35
+ raise "Input method requested: #{method}. Should not request input on RSpec."
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EacCli
4
+ module Rspec
5
+ require_sub __FILE__
6
+ end
7
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EacCli
4
+ module Runner
5
+ module AfterClassMethods
6
+ # @return [EacCli::Runner::ClassRunner]
7
+ def class_runner(runner_context_args)
8
+ ::EacCli::Runner::ClassRunner.new(self, runner_context_args)
9
+ end
10
+
11
+ def create(*runner_context_args)
12
+ class_runner(runner_context_args).create
13
+ end
14
+
15
+ def run(*runner_context_args)
16
+ class_runner(runner_context_args).run
17
+ end
18
+
19
+ def runner_definition(&block)
20
+ @runner_definition ||= super_runner_definition
21
+ begin
22
+ @runner_definition.instance_eval(&block) if block
23
+ rescue ::EacCli::Definition::Error => _e
24
+ raise ::EacCli::Definition::Error, "Definition error for #{self}"
25
+ end
26
+ @runner_definition
27
+ end
28
+
29
+ def super_runner_definition
30
+ superclass.try(:runner_definition).if_present(&:dup) || ::EacCli::Definition.new
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EacCli
4
+ module Runner
5
+ class ClassRunner
6
+ PARSER_ERROR_EXIT_CODE = 1
7
+
8
+ common_constructor :klass, :context_args
9
+
10
+ def create
11
+ r = klass.new
12
+ r.runner_context = ::EacCli::Runner::Context.new(r, *context_args)
13
+ r
14
+ end
15
+
16
+ def run
17
+ r = create
18
+ begin
19
+ r.run_run
20
+ rescue ::EacCli::Parser::Error => e
21
+ run_parser_error(r, e)
22
+ end
23
+ r
24
+ end
25
+
26
+ def run_parser_error(runner_instance, error)
27
+ $stderr.write("#{runner_instance.program_name}: #{error}\n")
28
+ ::Kernel.exit(PARSER_ERROR_EXIT_CODE)
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EacCli
4
+ module Runner
5
+ class Context
6
+ attr_reader :argv, :parent, :program_name, :runner
7
+
8
+ def initialize(runner, *context_args)
9
+ options = context_args.extract_options!
10
+ @argv = (context_args[0] || options.delete(:argv) || ARGV).dup.freeze
11
+ @parent = context_args[1] || options.delete(:parent)
12
+ @program_name = options.delete(:program_name)
13
+ @runner = runner
14
+ end
15
+
16
+ # Call a method in the runner or in one of it ancestors.
17
+ def call(method_name, *args, &block)
18
+ context_call_responder(method_name).call(*args, &block)
19
+ end
20
+
21
+ # @return [EacCli::Runner::ContextResponders]
22
+ def context_call_responder(method_name)
23
+ ::EacCli::Runner::ContextResponders::Set.new(self, method_name, %i[runner parent])
24
+ end
25
+
26
+ # @param method_name [Symbol]
27
+ # @return [EacCli::Runner::ContextResponders::Parent]
28
+ def runner_missing_method_responder(method_name)
29
+ ::EacCli::Runner::ContextResponders::RunnerMissingMethod
30
+ .new(self, method_name)
31
+ end
32
+
33
+ # @param method_name [Symbol]
34
+ # @return [Boolean]
35
+ def parent_respond_to?(method_name)
36
+ parent.if_present(false) do |v|
37
+ next true if v.respond_to?(method_name)
38
+
39
+ v.if_respond(:runner_context, false) { |w| w.parent_respond_to?(method_name) }
40
+ end
41
+ end
42
+
43
+ def parent_call(method_name, *args, &block)
44
+ return parent.runner_context.call(method_name, *args, &block) if
45
+ parent.respond_to?(:runner_context)
46
+
47
+ raise "Parent #{parent} do not respond to .context or .runner_context (Runner: #{runner})"
48
+ end
49
+
50
+ # @param method_name [Symbol]
51
+ # @return [EacCli::Runner::ContextResponders::Parent]
52
+ def parent_responder(method_name)
53
+ ::EacCli::Runner::ContextResponders::Parent.new(self, method_name)
54
+ end
55
+ end
56
+ end
57
+ end