ehbrs-tools 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (158) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +13 -0
  3. data/exe/ehbrs +6 -0
  4. data/lib/ehbrs.rb +7 -0
  5. data/lib/ehbrs/executables.rb +28 -0
  6. data/lib/ehbrs/tools.rb +9 -0
  7. data/lib/ehbrs/tools/runner.rb +35 -0
  8. data/lib/ehbrs/tools/runner/vg.rb +26 -0
  9. data/lib/ehbrs/tools/runner/vg/ips.rb +90 -0
  10. data/lib/ehbrs/tools/runner/videos.rb +25 -0
  11. data/lib/ehbrs/tools/runner/videos/unsupported.rb +65 -0
  12. data/lib/ehbrs/tools/version.rb +7 -0
  13. data/lib/ehbrs/videos.rb +9 -0
  14. data/lib/ehbrs/videos/convert_job.rb +99 -0
  15. data/lib/ehbrs/videos/file.rb +70 -0
  16. data/lib/ehbrs/videos/profiles/base.rb +35 -0
  17. data/lib/ehbrs/videos/profiles/same_quality.rb +21 -0
  18. data/lib/ehbrs/videos/track.rb +27 -0
  19. data/lib/ehbrs/videos/unsupported/check_result.rb +24 -0
  20. data/lib/ehbrs/videos/unsupported/check_set.rb +43 -0
  21. data/lib/ehbrs/videos/unsupported/check_support.rb +68 -0
  22. data/lib/ehbrs/videos/unsupported/checks.rb +13 -0
  23. data/lib/ehbrs/videos/unsupported/checks/codec_extra_unlisted.rb +27 -0
  24. data/lib/ehbrs/videos/unsupported/checks/codec_extra_unsupported.rb +26 -0
  25. data/lib/ehbrs/videos/unsupported/checks/codec_unlisted.rb +23 -0
  26. data/lib/ehbrs/videos/unsupported/checks/codec_unsupported.rb +25 -0
  27. data/lib/ehbrs/videos/unsupported/checks/invalid_extension.rb +25 -0
  28. data/lib/ehbrs/videos/unsupported/file.rb +50 -0
  29. data/lib/ehbrs/videos/unsupported/file/fix.rb +45 -0
  30. data/lib/ehbrs/videos/unsupported/fix_profile.rb +56 -0
  31. data/lib/ehbrs/videos/unsupported/fixes/supported_codec.rb +36 -0
  32. data/lib/ehbrs/videos/unsupported/fixes/supported_container.rb +17 -0
  33. data/lib/ehbrs/videos/unsupported/profiles.rb +13 -0
  34. data/lib/ehbrs/videos/unsupported/profiles/base.rb +102 -0
  35. data/lib/ehbrs/videos/unsupported/profiles/philco.rb +27 -0
  36. data/lib/ehbrs/videos/unsupported/profiles/samsung.rb +32 -0
  37. data/lib/ehbrs/videos/unsupported/search.rb +72 -0
  38. data/lib/ehbrs/videos/unsupported/track.rb +32 -0
  39. data/vendor/eac_cli/Gemfile +5 -0
  40. data/vendor/eac_cli/eac_cli.gemspec +18 -0
  41. data/vendor/eac_cli/lib/eac_cli.rb +7 -0
  42. data/vendor/eac_cli/lib/eac_cli/default_runner.rb +22 -0
  43. data/vendor/eac_cli/lib/eac_cli/runner.rb +30 -0
  44. data/vendor/eac_cli/lib/eac_cli/runner/argument_option.rb +13 -0
  45. data/vendor/eac_cli/lib/eac_cli/runner/base_option.rb +22 -0
  46. data/vendor/eac_cli/lib/eac_cli/runner/boolean_option.rb +13 -0
  47. data/vendor/eac_cli/lib/eac_cli/runner/definition.rb +60 -0
  48. data/vendor/eac_cli/lib/eac_cli/runner/docopt_doc.rb +65 -0
  49. data/vendor/eac_cli/lib/eac_cli/runner/positional_argument.rb +15 -0
  50. data/vendor/eac_cli/lib/eac_cli/version.rb +5 -0
  51. data/vendor/eac_cli/spec/rubocop_spec.rb +7 -0
  52. data/vendor/eac_cli/spec/spec_helper.rb +100 -0
  53. data/vendor/eac_ruby_utils/Gemfile +16 -0
  54. data/vendor/eac_ruby_utils/MIT-LICENCE +16 -0
  55. data/vendor/eac_ruby_utils/README.rdoc +3 -0
  56. data/vendor/eac_ruby_utils/eac_ruby_utils.gemspec +25 -0
  57. data/vendor/eac_ruby_utils/lib/eac_ruby_utils.rb +23 -0
  58. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/arguments_consumer.rb +81 -0
  59. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/common_constructor.rb +133 -0
  60. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/configs.rb +82 -0
  61. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/configs/file.rb +66 -0
  62. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/console.rb +5 -0
  63. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/console/configs.rb +135 -0
  64. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/console/docopt_runner.rb +39 -0
  65. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/console/docopt_runner/_class_methods.rb +18 -0
  66. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/console/docopt_runner/_doc.rb +25 -0
  67. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/console/docopt_runner/_settings.rb +19 -0
  68. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/console/docopt_runner/_subcommands.rb +139 -0
  69. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/console/speaker.rb +134 -0
  70. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/console/speaker/_class_methods.rb +39 -0
  71. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/console/speaker/list.rb +63 -0
  72. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/console/speaker/node.rb +25 -0
  73. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/contextualizable.rb +16 -0
  74. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/core_ext.rb +5 -0
  75. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/envs.rb +23 -0
  76. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/envs/base_env.rb +28 -0
  77. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/envs/command.rb +155 -0
  78. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/envs/command/extra_options.rb +46 -0
  79. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/envs/executable.rb +51 -0
  80. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/envs/file.rb +22 -0
  81. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/envs/local_env.rb +17 -0
  82. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/envs/process.rb +19 -0
  83. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/envs/ssh_env.rb +72 -0
  84. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/filesystem_cache.rb +53 -0
  85. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/filesystem_traverser.rb +56 -0
  86. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/fs_cache.rb +11 -0
  87. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/listable.rb +17 -0
  88. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/listable/class_methods.rb +14 -0
  89. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/listable/instance_methods.rb +30 -0
  90. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/listable/integer_list.rb +23 -0
  91. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/listable/list.rb +89 -0
  92. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/listable/lists.rb +61 -0
  93. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/listable/string_list.rb +19 -0
  94. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/listable/value.rb +38 -0
  95. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/on_clean_ruby_environment.rb +23 -0
  96. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/options_consumer.rb +62 -0
  97. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/patch.rb +11 -0
  98. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/patches.rb +4 -0
  99. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/patches/class.rb +4 -0
  100. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/patches/class/common_constructor.rb +9 -0
  101. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/patches/hash.rb +5 -0
  102. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/patches/hash/options_consumer.rb +10 -0
  103. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/patches/hash/sym_keys_hash.rb +10 -0
  104. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/patches/module.rb +4 -0
  105. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/patches/module/console_speaker.rb +10 -0
  106. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/patches/module/listable.rb +10 -0
  107. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/patches/module/patch.rb +9 -0
  108. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/patches/module/require_sub.rb +9 -0
  109. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/patches/module/simple_cache.rb +10 -0
  110. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/patches/object.rb +5 -0
  111. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/patches/object/asserts.rb +14 -0
  112. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/patches/object/if_present.rb +12 -0
  113. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/patches/object/template.rb +16 -0
  114. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/paths_hash.rb +95 -0
  115. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/require_sub.rb +11 -0
  116. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/rspec.rb +9 -0
  117. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/rspec/conditional.rb +38 -0
  118. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/rspec/stubbed_ssh.rb +44 -0
  119. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/settings_provider.rb +65 -0
  120. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/simple_cache.rb +42 -0
  121. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/templates.rb +9 -0
  122. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/templates/directory.rb +104 -0
  123. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/templates/file.rb +101 -0
  124. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/templates/searcher.rb +55 -0
  125. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/version.rb +5 -0
  126. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/yaml.rb +13 -0
  127. data/vendor/eac_ruby_utils/spec/lib/eac_ruby_utils/arguments_consumer_spec.rb +17 -0
  128. data/vendor/eac_ruby_utils/spec/lib/eac_ruby_utils/common_constructor_spec.rb +36 -0
  129. data/vendor/eac_ruby_utils/spec/lib/eac_ruby_utils/configs_spec.rb +31 -0
  130. data/vendor/eac_ruby_utils/spec/lib/eac_ruby_utils/console/configs_spec.rb +14 -0
  131. data/vendor/eac_ruby_utils/spec/lib/eac_ruby_utils/console/docopt_runner_spec.rb +136 -0
  132. data/vendor/eac_ruby_utils/spec/lib/eac_ruby_utils/console/speaker_spec.rb +36 -0
  133. data/vendor/eac_ruby_utils/spec/lib/eac_ruby_utils/envs/executable_spec.rb +33 -0
  134. data/vendor/eac_ruby_utils/spec/lib/eac_ruby_utils/envs/ssh_env_spec.rb +25 -0
  135. data/vendor/eac_ruby_utils/spec/lib/eac_ruby_utils/filesystem_cache_spec.rb +32 -0
  136. data/vendor/eac_ruby_utils/spec/lib/eac_ruby_utils/listable_spec.rb +180 -0
  137. data/vendor/eac_ruby_utils/spec/lib/eac_ruby_utils/options_consumer_spec.rb +45 -0
  138. data/vendor/eac_ruby_utils/spec/lib/eac_ruby_utils/patches/hash/options_consumer_spec.rb +17 -0
  139. data/vendor/eac_ruby_utils/spec/lib/eac_ruby_utils/patches/hash/sym_keys_hash_spec.rb +13 -0
  140. data/vendor/eac_ruby_utils/spec/lib/eac_ruby_utils/patches/module/console_speaker_spec.rb +13 -0
  141. data/vendor/eac_ruby_utils/spec/lib/eac_ruby_utils/patches/module/listable_spec.rb +13 -0
  142. data/vendor/eac_ruby_utils/spec/lib/eac_ruby_utils/patches/module/simple_cache_spec.rb +13 -0
  143. data/vendor/eac_ruby_utils/spec/lib/eac_ruby_utils/patches/object/if_present_spec.rb +13 -0
  144. data/vendor/eac_ruby_utils/spec/lib/eac_ruby_utils/patches/object/template_spec.rb +23 -0
  145. data/vendor/eac_ruby_utils/spec/lib/eac_ruby_utils/patches/object/template_spec_files/path/my_stub_with_template +1 -0
  146. data/vendor/eac_ruby_utils/spec/lib/eac_ruby_utils/paths_hash_spec.rb +49 -0
  147. data/vendor/eac_ruby_utils/spec/lib/eac_ruby_utils/settings_provider_spec.rb +46 -0
  148. data/vendor/eac_ruby_utils/spec/lib/eac_ruby_utils/simple_cache_spec.rb +102 -0
  149. data/vendor/eac_ruby_utils/spec/lib/eac_ruby_utils/templates/file_spec.rb +34 -0
  150. data/vendor/eac_ruby_utils/spec/lib/eac_ruby_utils/templates/file_spec_files/expected_content +2 -0
  151. data/vendor/eac_ruby_utils/spec/lib/eac_ruby_utils/templates/file_spec_files/source.template +2 -0
  152. data/vendor/eac_ruby_utils/spec/lib/eac_ruby_utils/templates/searcher_spec.rb +30 -0
  153. data/vendor/eac_ruby_utils/spec/lib/eac_ruby_utils/templates/searcher_spec_files/path1/subdir1/file1.template +1 -0
  154. data/vendor/eac_ruby_utils/spec/lib/eac_ruby_utils/templates/searcher_spec_files/path1/subdir1/file2 +1 -0
  155. data/vendor/eac_ruby_utils/spec/lib/eac_ruby_utils/templates/searcher_spec_files/path2/subdir1/file3.template +1 -0
  156. data/vendor/eac_ruby_utils/spec/locales/pt-BR.yml +38 -0
  157. data/vendor/eac_ruby_utils/spec/spec_helper.rb +12 -0
  158. metadata +227 -0
@@ -0,0 +1,135 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'eac_ruby_utils/common_constructor'
4
+ require 'eac_ruby_utils/configs'
5
+ require 'eac_ruby_utils/console/speaker'
6
+ require 'eac_ruby_utils/options_consumer'
7
+ require 'eac_ruby_utils/patches/object/asserts'
8
+ require 'eac_ruby_utils/simple_cache'
9
+
10
+ module EacRubyUtils
11
+ module Console
12
+ class Configs
13
+ include ::EacRubyUtils::Console::Speaker
14
+
15
+ class << self
16
+ def entry_key_to_envvar_name(entry_key)
17
+ path = if entry_key.is_a?(::Array)
18
+ entry_key
19
+ else
20
+ ::EacRubyUtils::PathsHash.parse_entry_key(entry_key)
21
+ end
22
+ path.join('_').gsub(/[^a-z0-9_]/i, '').gsub(/\A_+/, '').gsub(/_+\z/, '')
23
+ .gsub(/_{2,}/, '_').upcase
24
+ end
25
+ end
26
+
27
+ STORE_PASSWORDS_KEY = 'core.store_passwords'
28
+
29
+ attr_reader :configs
30
+
31
+ def initialize(configs_key, options = {})
32
+ options.assert_argument(::Hash, 'options')
33
+ @configs = ::EacRubyUtils::Configs.new(configs_key, options.merge(autosave: true))
34
+ end
35
+
36
+ def read_password(entry_key, options = {})
37
+ options = options.merge(noecho: true)
38
+ if store_passwords?
39
+ read_entry(entry_key, options)
40
+ else
41
+ looped_entry_value_from_input(entry_key, options)
42
+ end
43
+ end
44
+
45
+ def read_entry(entry_key, options = {})
46
+ options = ReadEntryOptions.new(options)
47
+ unless options[:noenv]
48
+ envvar_value = envvar_read_entry(entry_key)
49
+ return envvar_value if envvar_value.present?
50
+ end
51
+ stored_value = configs.read_entry(entry_key)
52
+ return stored_value if stored_value
53
+ return read_entry_from_console(entry_key, options) unless options[:noinput]
54
+
55
+ raise "No value found for entry \"#{entry_key}\"" if options[:required]
56
+ end
57
+
58
+ def store_passwords?
59
+ read_entry(
60
+ STORE_PASSWORDS_KEY,
61
+ before_input: -> { store_password_banner },
62
+ validator: ->(entry_value) { %w[yes no].include?(entry_value) }
63
+ ) == 'yes'
64
+ end
65
+
66
+ protected
67
+
68
+ def envvar_read_entry(entry_key)
69
+ ENV[self.class.entry_key_to_envvar_name(entry_key)]
70
+ end
71
+
72
+ def read_entry_from_console(entry_key, options)
73
+ options[:before_input].call if options[:before_input].present?
74
+ entry_value = looped_entry_value_from_input(entry_key, options)
75
+ configs.write_entry(entry_key, entry_value)
76
+ entry_value
77
+ end
78
+
79
+ def store_password_banner
80
+ infom 'Do you wanna to store passwords?'
81
+ infom "Warning: the passwords will be store in clear text in \"#{configs.storage_path}\""
82
+ infom 'Enter "yes" or "no"'
83
+ end
84
+
85
+ def looped_entry_value_from_input(entry_key, options)
86
+ loop do
87
+ entry_value = entry_value_from_input(entry_key, options)
88
+ next unless entry_value.present?
89
+ next if options[:validator] && !options[:validator].call(entry_value)
90
+
91
+ return entry_value
92
+ end
93
+ end
94
+
95
+ def entry_value_from_input(entry_key, options)
96
+ entry_value = request_input("Value for entry \"#{entry_key}\"",
97
+ options.request_input_options)
98
+ warn('Entered value is blank') if entry_value.blank?
99
+ entry_value
100
+ end
101
+
102
+ class ReadEntryOptions
103
+ include ::EacRubyUtils::SimpleCache
104
+ ::EacRubyUtils::CommonConstructor.new(:options).setup_class(self)
105
+
106
+ DEFAULT_VALUES = {
107
+ before_input: nil, bool: false, list: false, noecho: false, noenv: false, noinput: false,
108
+ required: true, validator: nil
109
+ }.freeze
110
+
111
+ def [](key)
112
+ values.fetch(key.to_sym)
113
+ end
114
+
115
+ def request_input_options
116
+ values.slice(:bool, :list, :noecho)
117
+ end
118
+
119
+ private
120
+
121
+ def values_uncached
122
+ consumer = ::EacRubyUtils::OptionsConsumer.new(options)
123
+ r = {}
124
+ DEFAULT_VALUES.each do |key, default_value|
125
+ value = consumer.consume(key)
126
+ value = default_value if value.nil?
127
+ r[key] = value
128
+ end
129
+ consumer.validate
130
+ r
131
+ end
132
+ end
133
+ end
134
+ end
135
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_support/core_ext/hash/indifferent_access'
4
+ require 'active_support/core_ext/hash/slice'
5
+ require 'docopt'
6
+ require 'eac_ruby_utils/contextualizable'
7
+ require 'eac_ruby_utils/patches/hash/sym_keys_hash'
8
+ Dir["#{__dir__}/#{::File.basename(__FILE__, '.*')}/_*.rb"].sort.each do |partial|
9
+ require partial
10
+ end
11
+
12
+ module EacRubyUtils
13
+ module Console
14
+ class DocoptRunner
15
+ include ::EacRubyUtils::Contextualizable
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
39
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EacRubyUtils
4
+ module Console
5
+ class DocoptRunner
6
+ DOCOPT_ERROR_EXIT_CODE = 0x22220000
7
+
8
+ class << self
9
+ def run(options = {})
10
+ new(options).send(:run)
11
+ rescue Docopt::Exit => e
12
+ STDERR.write(e.message + "\n")
13
+ ::Kernel.exit(DOCOPT_ERROR_EXIT_CODE)
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EacRubyUtils
4
+ module Console
5
+ class DocoptRunner
6
+ PROGRAM_MACRO = '__PROGRAM__'
7
+
8
+ def source_doc
9
+ setting_value(:doc)
10
+ end
11
+
12
+ def target_doc
13
+ source_doc.gsub(PROGRAM_MACRO, target_program_name).strip + "\n"
14
+ end
15
+
16
+ def source_program_name
17
+ setting_value(:program_name, false)
18
+ end
19
+
20
+ def target_program_name
21
+ [source_program_name, ENV['PROGRAM_NAME'], $PROGRAM_NAME].find(&:present?)
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'eac_ruby_utils/settings_provider'
4
+
5
+ module EacRubyUtils
6
+ module Console
7
+ class DocoptRunner
8
+ include ::EacRubyUtils::SettingsProvider
9
+
10
+ attr_reader :settings
11
+
12
+ private
13
+
14
+ def setting_value(key, required = true)
15
+ super(key, required: required, order: %w[method settings_object constant])
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,139 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_support/core_ext/string/inflections'
4
+ require 'shellwords'
5
+
6
+ module EacRubyUtils
7
+ module Console
8
+ class DocoptRunner
9
+ SUBCOMMAND_ARG = '<subcommand>'
10
+ SUBCOMMAND_ARGS_ARG = '<subcommand-args>'
11
+ SUBCOMMANDS_MACRO = '__SUBCOMMANDS__'
12
+
13
+ def subcommands?
14
+ source_doc.include?(SUBCOMMANDS_MACRO)
15
+ end
16
+
17
+ def check_subcommands
18
+ return unless subcommands?
19
+
20
+ singleton_class.include(SubcommandsSupport)
21
+ check_subcommands_arg
22
+ return if singleton_class.method_defined?(:run)
23
+
24
+ singleton_class.send(:alias_method, :run, :run_with_subcommand)
25
+ end
26
+
27
+ module SubcommandsSupport
28
+ def check_subcommands_arg
29
+ if subcommand_arg_as_list?
30
+ singleton_class.include(SubcommandsSupport::SubcommandArgAsList)
31
+ else
32
+ singleton_class.include(SubcommandsSupport::SubcommandArgAsArg)
33
+ end
34
+ end
35
+
36
+ def run_with_subcommand
37
+ if subcommand_name
38
+ check_valid_subcommand
39
+ subcommand.run
40
+ else
41
+ run_without_subcommand
42
+ end
43
+ end
44
+
45
+ def subcommand
46
+ @subcommand ||= subcommand_class_name(subcommand_name).constantize.new(
47
+ argv: subcommand_args,
48
+ program_name: subcommand_program,
49
+ parent: self
50
+ )
51
+ end
52
+
53
+ def target_doc
54
+ super.gsub(SUBCOMMANDS_MACRO,
55
+ "#{target_doc_subcommand_arg} [#{SUBCOMMAND_ARGS_ARG}...]") +
56
+ "\n" + subcommands_target_doc
57
+ end
58
+
59
+ def docopt_options
60
+ super.merge(options_first: true)
61
+ end
62
+
63
+ def subcommand_class_name(subcommand)
64
+ "#{self.class.name}::#{subcommand.underscore.camelize}"
65
+ end
66
+
67
+ def subcommand_arg_as_list?
68
+ setting_value(:subcommand_arg_as_list, false) || false
69
+ end
70
+
71
+ def subcommand_args
72
+ options.fetch(SUBCOMMAND_ARGS_ARG)
73
+ end
74
+
75
+ def subcommand_program
76
+ subcommand_name
77
+ end
78
+
79
+ def available_subcommands
80
+ (setting_value(:subcommands, false) || auto_available_subcommands).sort
81
+ end
82
+
83
+ def auto_available_subcommands
84
+ self.class.constants
85
+ .map { |name| self.class.const_get(name) }
86
+ .select { |c| c.instance_of? Class }
87
+ .select { |c| c < ::EacRubyUtils::Console::DocoptRunner }
88
+ .map { |c| c.name.demodulize.underscore.dasherize }
89
+ end
90
+
91
+ def run_without_subcommand
92
+ "Method #{__method__} should be overrided in #{self.class.name}"
93
+ end
94
+
95
+ protected
96
+
97
+ def check_valid_subcommand
98
+ return if available_subcommands.include?(subcommand_name)
99
+
100
+ raise ::Docopt::Exit, "\"#{subcommand_name}\" is not a valid subcommand" \
101
+ " (Valid: #{available_subcommands.join(', ')})"
102
+ end
103
+
104
+ module SubcommandArgAsArg
105
+ def target_doc_subcommand_arg
106
+ SUBCOMMAND_ARG
107
+ end
108
+
109
+ def subcommand_name
110
+ options.fetch(SUBCOMMAND_ARG)
111
+ end
112
+
113
+ def subcommands_target_doc
114
+ available_subcommands.inject("Subcommands:\n") do |a, e|
115
+ a + " #{e}\n"
116
+ end
117
+ end
118
+ end
119
+
120
+ module SubcommandArgAsList
121
+ def target_doc_subcommand_arg
122
+ '(' + available_subcommands.join('|') + ')'
123
+ end
124
+
125
+ def subcommand_name
126
+ available_subcommands.each do |subcommand|
127
+ return subcommand if options.fetch(subcommand)
128
+ end
129
+ nil
130
+ end
131
+
132
+ def subcommands_target_doc
133
+ "\n"
134
+ end
135
+ end
136
+ end
137
+ end
138
+ end
139
+ end
@@ -0,0 +1,134 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'colorize'
4
+ require 'io/console'
5
+ require 'eac_ruby_utils/patches/hash/options_consumer'
6
+ require 'eac_ruby_utils/console/speaker/_class_methods'
7
+ require 'eac_ruby_utils/console/speaker/list'
8
+ require 'eac_ruby_utils/console/speaker/node'
9
+
10
+ module EacRubyUtils
11
+ module Console
12
+ # https://github.com/fazibear/colorize
13
+ module Speaker
14
+ def on_speaker_node(&block)
15
+ ::EacRubyUtils::Console::Speaker.on_node(&block)
16
+ end
17
+
18
+ def puts(string = '')
19
+ string.to_s.each_line do |line|
20
+ current_node.stderr.puts(current_node.stderr_line_prefix.to_s + line)
21
+ end
22
+ end
23
+
24
+ def out(string = '')
25
+ current_node.stdout.write(string.to_s)
26
+ end
27
+
28
+ def fatal_error(string)
29
+ puts "ERROR: #{string}".white.on_red
30
+ Kernel.exit 1
31
+ end
32
+
33
+ def title(string)
34
+ string = string.to_s
35
+ puts(('-' * (8 + string.length)).green)
36
+ puts("--- #{string} ---".green)
37
+ puts(('-' * (8 + string.length)).green)
38
+ puts
39
+ end
40
+
41
+ def info(string)
42
+ puts string.to_s.white
43
+ end
44
+
45
+ def infom(string)
46
+ puts string.to_s.light_yellow
47
+ end
48
+
49
+ def warn(string)
50
+ puts string.to_s.yellow
51
+ end
52
+
53
+ # Options:
54
+ # +bool+ ([Boolean], default: +false+): requires a answer "yes" or "no".
55
+ # +list+ ([Hash] or [Array], default: +nil+): requires a answer from a list.
56
+ # +noecho+ ([Boolean], default: +false+): does not output answer.
57
+ def request_input(question, options = {})
58
+ bool, list, noecho = options.to_options_consumer.consume_all(:bool, :list, :noecho)
59
+ if list
60
+ request_from_list(question, list, noecho)
61
+ elsif bool
62
+ request_from_bool(question, noecho)
63
+ else
64
+ request_string(question, noecho)
65
+ end
66
+ end
67
+
68
+ def infov(*args)
69
+ r = []
70
+ args.each_with_index do |v, i|
71
+ if i.even?
72
+ r << "#{v}: ".cyan
73
+ else
74
+ r.last << v.to_s
75
+ end
76
+ end
77
+ puts r.join(', ')
78
+ end
79
+
80
+ def success(string)
81
+ puts string.to_s.green
82
+ end
83
+
84
+ private
85
+
86
+ def list_value(list, input)
87
+ values = list_values(list)
88
+ return input, true unless values
89
+ return input, false unless values.include?(input)
90
+ end
91
+
92
+ def list_values(list)
93
+ if list.is_a?(::Hash)
94
+ list.keys.map(&:to_s)
95
+ elsif list.is_a?(::Array)
96
+ list.map(&:to_s)
97
+ end
98
+ end
99
+
100
+ def request_from_bool(question, noecho)
101
+ request_from_list(question, { yes: true, y: true, no: false, n: false }, noecho)
102
+ end
103
+
104
+ def request_from_list(question, list, noecho)
105
+ list = ::EacRubyUtils::Console::Speaker::List.build(list)
106
+ loop do
107
+ input = request_string("#{question} [#{list.valid_labels.join('/')}]", noecho)
108
+ return list.build_value(input) if list.valid_value?(input)
109
+
110
+ warn "Invalid input: \"#{input}\" (Valid: #{list.valid_labels.join(', ')})"
111
+ end
112
+ end
113
+
114
+ def request_string(question, noecho)
115
+ current_node.stderr.write "#{question}: ".to_s.yellow
116
+ noecho ? request_string_noecho : request_string_echo
117
+ end
118
+
119
+ def request_string_noecho
120
+ r = current_node.stdin.noecho(&:gets).chomp.strip
121
+ current_node.stderr.write("\n")
122
+ r
123
+ end
124
+
125
+ def request_string_echo
126
+ current_node.stdin.gets.chomp.strip
127
+ end
128
+
129
+ def current_node
130
+ ::EacRubyUtils::Console::Speaker.current_node
131
+ end
132
+ end
133
+ end
134
+ end