ehbrs-tools 0.15.0 → 0.16.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (64) hide show
  1. checksums.yaml +4 -4
  2. data/lib/ehbrs/runner.rb +4 -7
  3. data/lib/ehbrs/runner/finances.rb +4 -7
  4. data/lib/ehbrs/runner/finances/bb_browser.rb +5 -10
  5. data/lib/ehbrs/runner/fs.rb +4 -7
  6. data/lib/ehbrs/runner/fs/used_space.rb +4 -5
  7. data/lib/ehbrs/runner/google.rb +4 -7
  8. data/lib/ehbrs/runner/google/translate.rb +7 -12
  9. data/lib/ehbrs/runner/self.rb +4 -7
  10. data/lib/ehbrs/runner/self/test.rb +5 -10
  11. data/lib/ehbrs/runner/vg.rb +4 -7
  12. data/lib/ehbrs/runner/vg/ips.rb +9 -14
  13. data/lib/ehbrs/runner/vg/wii.rb +10 -13
  14. data/lib/ehbrs/runner/videos.rb +3 -5
  15. data/lib/ehbrs/runner/videos/extract.rb +10 -13
  16. data/lib/ehbrs/runner/videos/probe.rb +3 -6
  17. data/lib/ehbrs/runner/videos/series.rb +5 -8
  18. data/lib/ehbrs/runner/videos/series/rename.rb +9 -12
  19. data/lib/ehbrs/runner/videos/unsupported.rb +9 -13
  20. data/lib/ehbrs/runner/web_utils.rb +5 -7
  21. data/lib/ehbrs/runner/web_utils/videos.rb +4 -6
  22. data/lib/ehbrs/runner/web_utils/videos/download.rb +8 -11
  23. data/lib/ehbrs/runner/web_utils/videos/upload.rb +8 -11
  24. data/lib/ehbrs/tools/version.rb +1 -1
  25. data/lib/ehbrs/videos/series/rename/file/options.rb +3 -13
  26. data/vendor/eac_cli/eac_cli.gemspec +1 -1
  27. data/vendor/eac_cli/lib/eac_cli/definition.rb +25 -3
  28. data/vendor/eac_cli/lib/eac_cli/definition/base_option.rb +17 -1
  29. data/vendor/eac_cli/lib/eac_cli/definition/positional_argument.rb +8 -4
  30. data/vendor/eac_cli/lib/eac_cli/docopt/runner_extension.rb +1 -0
  31. data/vendor/eac_cli/lib/eac_cli/parser/collector.rb +4 -0
  32. data/vendor/eac_cli/lib/eac_cli/parser/options_collection.rb +23 -1
  33. data/vendor/eac_cli/lib/eac_cli/parser/parse_result.rb +17 -0
  34. data/vendor/eac_cli/lib/eac_cli/parser/positional_collection.rb +47 -19
  35. data/vendor/eac_cli/lib/eac_cli/patches/object/runner_with.rb +2 -1
  36. data/vendor/eac_cli/lib/eac_cli/runner.rb +5 -1
  37. data/vendor/eac_cli/lib/eac_cli/runner/context.rb +19 -2
  38. data/vendor/eac_cli/lib/eac_cli/runner_with/subcommands.rb +96 -0
  39. data/vendor/eac_cli/lib/eac_cli/version.rb +1 -1
  40. data/vendor/eac_cli/spec/lib/eac_cli/docopt/runner_extension_spec.rb +25 -0
  41. data/vendor/eac_cli/spec/lib/eac_cli/runner_spec.rb +48 -40
  42. data/vendor/eac_cli/spec/lib/eac_cli/runner_with/subcommands_spec.rb +57 -0
  43. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/blank_not_blank.rb +19 -0
  44. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/configs/base.rb +43 -0
  45. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/configs/file.rb +12 -31
  46. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/console/configs.rb +8 -40
  47. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/console/configs/read_entry_options.rb +41 -0
  48. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/fs/clearable_directory.rb +57 -0
  49. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/patches/enumerator.rb +4 -0
  50. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/patches/enumerator/current.rb +9 -0
  51. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/patches/enumerator/stopped.rb +14 -0
  52. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/paths_hash.rb +21 -58
  53. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/paths_hash/entry_key_error.rb +8 -0
  54. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/paths_hash/node.rb +67 -0
  55. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/paths_hash/path_search.rb +39 -0
  56. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/ruby/command.rb +2 -1
  57. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/struct.rb +4 -0
  58. data/vendor/eac_ruby_utils/lib/eac_ruby_utils/version.rb +1 -1
  59. data/vendor/eac_ruby_utils/spec/lib/eac_ruby_utils/blank_not_blank_spec.rb +16 -0
  60. data/vendor/eac_ruby_utils/spec/lib/eac_ruby_utils/configs_spec.rb +15 -0
  61. data/vendor/eac_ruby_utils/spec/lib/eac_ruby_utils/patches/enumerator/current_spec.rb +26 -0
  62. data/vendor/eac_ruby_utils/spec/lib/eac_ruby_utils/patches/enumerator/stopped_spec.rb +32 -0
  63. data/vendor/eac_ruby_utils/spec/lib/eac_ruby_utils/paths_hash_spec.rb +52 -13
  64. metadata +18 -2
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'eac_cli/docopt/doc_builder'
4
+ require 'eac_cli/runner'
4
5
  require 'eac_ruby_utils/console/docopt_runner'
5
6
 
6
7
  module EacCli
@@ -31,6 +31,10 @@ module EacCli
31
31
  end
32
32
  end
33
33
 
34
+ def supplied?(option)
35
+ data[option].present?
36
+ end
37
+
34
38
  private
35
39
 
36
40
  def data
@@ -14,18 +14,40 @@ module EacCli
14
14
  common_constructor(:definition, :argv, :collector) { collect }
15
15
  attr_reader :arguments
16
16
 
17
+ def options_first?
18
+ definition.options_first? || definition.subcommands?
19
+ end
20
+
17
21
  private
18
22
 
23
+ def check_required_options
24
+ definition.options.each do |option|
25
+ next unless option.required?
26
+ next if collector.supplied?(option)
27
+
28
+ raise ::EacCli::Parser::Error.new(
29
+ definition, argv, "Option \"#{option}\" is required and a value was not supplied"
30
+ )
31
+ end
32
+ end
33
+
19
34
  def collect
20
35
  build_banner
21
36
  build_options
22
- @arguments = option_parser.parse(argv)
37
+ parse_argv
38
+ check_required_options
23
39
  end
24
40
 
25
41
  def option_parser_uncached
26
42
  ::OptionParser.new
27
43
  end
28
44
 
45
+ def parse_argv
46
+ @arguments = options_first? ? option_parser.order(argv) : option_parser.parse(argv)
47
+ rescue ::OptionParser::InvalidOption => e
48
+ raise ::EacCli::Parser::Error.new(definition, argv, e.message)
49
+ end
50
+
29
51
  def build_banner
30
52
  option_parser.banner = "#{definition.description}\n\n#{section('usage')}"
31
53
  end
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'eac_cli/parser/error'
3
4
  require 'eac_ruby_utils/core_ext'
4
5
 
5
6
  module EacCli
@@ -8,6 +9,20 @@ module EacCli
8
9
  common_constructor :definition, :argv
9
10
 
10
11
  def result
12
+ result_or_error = parse(definition)
13
+ return result_or_error unless result_or_error.is_a?(::Exception)
14
+
15
+ definition.alternatives.each do |alternative|
16
+ alt_result_or_error = parse(alternative)
17
+ return alt_result_or_error unless alt_result_or_error.is_a?(::Exception)
18
+ end
19
+
20
+ raise result_or_error
21
+ end
22
+
23
+ private
24
+
25
+ def parse(definition)
11
26
  ::EacCli::Parser::Collector.to_data(definition) do |collector|
12
27
  ::EacCli::Parser::PositionalCollection.new(
13
28
  definition,
@@ -15,6 +30,8 @@ module EacCli
15
30
  collector
16
31
  )
17
32
  end
33
+ rescue ::EacCli::Parser::Error => e
34
+ e
18
35
  end
19
36
  end
20
37
  end
@@ -10,39 +10,67 @@ module EacCli
10
10
 
11
11
  private
12
12
 
13
+ def argv_enum
14
+ @argv_enum ||= argv.each
15
+ end
16
+
17
+ def argv_pending?
18
+ argv_enum.ongoing?
19
+ end
20
+
21
+ def argv_pending_check
22
+ return unless argv_pending?
23
+ return unless positional_enum.stopped?
24
+
25
+ raise ::EacCli::Parser::Error.new(
26
+ definition, argv, "No positional left for argv \"#{argv_enum.current}\""
27
+ )
28
+ end
29
+
13
30
  def collected
14
31
  @collected ||= ::Set.new
15
32
  end
16
33
 
17
34
  def collect
18
- argv.each { |argv_value| colect_argv_value(argv_value) }
19
- return unless pending_required_positional?
35
+ loop do
36
+ break unless enums('pending?').any?
20
37
 
21
- raise ::EacCli::Parser::Error.new(
22
- definition, argv, 'No value for required positional ' \
23
- "\"#{current_positional.identifier}\""
24
- )
38
+ enums('pending_check')
39
+ collect_argv_value
40
+ end
41
+ end
42
+
43
+ def collect_argv_value
44
+ collector.collect(*enums('enum', &:peek))
45
+ collected << positional_enum.peek
46
+ positional_enum.next unless positional_enum.peek.repeat?
47
+ argv_enum.next
25
48
  end
26
49
 
27
- def colect_argv_value(argv_value)
28
- collector.collect(current_positional, argv_value)
29
- collected << current_positional
30
- positional_enumerator.next unless current_positional.repeat?
50
+ def enums(method_suffix, &block)
51
+ %w[positional argv].map do |method_prefix|
52
+ v = send("#{method_prefix}_#{method_suffix}")
53
+ block ? block.call(v) : v
54
+ end
31
55
  end
32
56
 
33
- def pending_required_positional?
34
- !(current_positional.blank? || current_positional.optional? ||
35
- collected.include?(current_positional))
57
+ def positional_enum
58
+ @positional_enum ||= definition.positional.each
36
59
  end
37
60
 
38
- def positional_enumerator
39
- @positional_enumerator ||= definition.positional.each
61
+ def positional_pending?
62
+ !(positional_enum.stopped? || positional_enum.current.optional? ||
63
+ collected.include?(positional_enum.current))
40
64
  end
41
65
 
42
- def current_positional
43
- positional_enumerator.peek
44
- rescue ::StopIteration
45
- nil
66
+ def positional_pending_check
67
+ return unless positional_pending?
68
+ return unless argv_enum.stopped?
69
+
70
+ raise ::EacCli::Parser::Error.new(
71
+ definition, argv, 'No value for required positional ' \
72
+ "\"#{positional_enum.current.identifier}\""
73
+ )
46
74
  end
47
75
  end
48
76
  end
@@ -5,13 +5,14 @@ require 'eac_cli/runner'
5
5
  require 'eac_cli/runner_with'
6
6
 
7
7
  class Object
8
- def runner_with(*runners)
8
+ def runner_with(*runners, &block)
9
9
  include ::EacCli::Runner
10
10
  enable_simple_cache
11
11
  enable_console_speaker
12
12
  runners.each do |runner|
13
13
  include runner_with_to_module(runner)
14
14
  end
15
+ runner_definition(&block) if block
15
16
  end
16
17
 
17
18
  private
@@ -18,6 +18,10 @@ module EacCli
18
18
  end
19
19
  end
20
20
 
21
+ def runner?(object)
22
+ object.is_a?(::Class) && object.included_modules.include?(::EacCli::Runner)
23
+ end
24
+
21
25
  private
22
26
 
23
27
  def alias_class_method(klass, from, to)
@@ -45,7 +49,7 @@ module EacCli
45
49
  module AfterClassMethods
46
50
  def create(*runner_context_args)
47
51
  r = new
48
- r.runner_context = ::EacCli::Runner::Context.new(*runner_context_args)
52
+ r.runner_context = ::EacCli::Runner::Context.new(r, *runner_context_args)
49
53
  r
50
54
  end
51
55
 
@@ -5,13 +5,30 @@ require 'eac_ruby_utils/core_ext'
5
5
  module EacCli
6
6
  module Runner
7
7
  class Context
8
- attr_reader :argv, :parent, :program_name
8
+ attr_reader :argv, :parent, :program_name, :runner
9
9
 
10
- def initialize(*context_args)
10
+ def initialize(runner, *context_args)
11
11
  options = context_args.extract_options!
12
12
  @argv = (context_args[0] || options.delete(:argv) || ARGV).dup.freeze
13
13
  @parent = context_args[1] || options.delete(:parent)
14
14
  @program_name = options.delete(:program_name)
15
+ @runner = runner
16
+ end
17
+
18
+ # Call a method in the runner or in one of it ancestors.
19
+ def call(method_name, *args)
20
+ return runner.send(method_name, *args) if runner.respond_to?(method_name)
21
+ return parent_call(method_name, *args) if parent.present?
22
+
23
+ raise ::NameError, "No method \"#{method_name}\" found in #{runner} or in its ancestors"
24
+ end
25
+
26
+ protected
27
+
28
+ def parent_call(method_name, *args)
29
+ return parent.context(method_name, *args) if parent.respond_to?(:context)
30
+
31
+ parent.runner_context.call(method_name, *args)
15
32
  end
16
33
  end
17
34
  end
@@ -0,0 +1,96 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'eac_cli/runner'
4
+ require 'eac_ruby_utils/core_ext'
5
+
6
+ module EacCli
7
+ module RunnerWith
8
+ module Subcommands
9
+ common_concern do
10
+ include ::EacCli::Runner
11
+ end
12
+
13
+ EXTRA_AVAILABLE_SUBCOMMANDS_METHOD_NAME = :extra_available_subcommands
14
+
15
+ def available_subcommands
16
+ @available_subcommands ||= available_subcommands_auto.merge(available_subcommands_extra)
17
+ end
18
+
19
+ def available_subcommands_auto
20
+ self.class.constants
21
+ .map { |name| [name.to_s.underscore.gsub('_', '-'), self.class.const_get(name)] }
22
+ .select { |c| ::EacCli::Runner.runner?(c[1]) }
23
+ .to_h.with_indifferent_access
24
+ end
25
+
26
+ def available_subcommands_extra
27
+ if respond_to?(EXTRA_AVAILABLE_SUBCOMMANDS_METHOD_NAME, true)
28
+ send(EXTRA_AVAILABLE_SUBCOMMANDS_METHOD_NAME)
29
+ else
30
+ {}
31
+ end
32
+ end
33
+
34
+ def method_missing(method_name, *arguments, &block)
35
+ return run_with_subcommand(*arguments, &block) if
36
+ run_with_subcommand_alias_run?(method_name)
37
+
38
+ super
39
+ end
40
+
41
+ def respond_to_missing?(method_name, include_private = false)
42
+ run_with_subcommand_alias_run?(method_name) || super
43
+ end
44
+
45
+ def run_with_subcommand
46
+ if subcommand_name
47
+ subcommand_runner.run
48
+ else
49
+ run_without_subcommand
50
+ end
51
+ end
52
+
53
+ def run_with_subcommand_alias_run?(method_name)
54
+ subcommands? && method_name.to_sym == :run
55
+ end
56
+
57
+ def run_without_subcommand
58
+ "Method #{__method__} should be overrided in #{self.class.name}"
59
+ end
60
+
61
+ def subcommands?
62
+ self.class.runner_definition.subcommands?
63
+ end
64
+
65
+ def subcommand_args
66
+ parsed.fetch(::EacCli::Definition::SUBCOMMAND_ARGS_ARG)
67
+ end
68
+
69
+ def subcommand_class
70
+ available_subcommands[subcommand_name].if_present { |v| return v }
71
+
72
+ raise(::EacCli::Parser::Error.new(
73
+ self.class.runner_definition, runner_context.argv,
74
+ "Subcommand \"#{subcommand_name}\" not found " \
75
+ "(Available: #{available_subcommands.keys}"
76
+ ))
77
+ end
78
+
79
+ def subcommand_name
80
+ parsed.fetch(::EacCli::Definition::SUBCOMMAND_NAME_ARG)
81
+ end
82
+
83
+ def subcommand_program
84
+ subcommand_name
85
+ end
86
+
87
+ def subcommand_runner
88
+ @subcommand_runner ||= subcommand_class.create(
89
+ argv: subcommand_args,
90
+ program_name: subcommand_program,
91
+ parent: self
92
+ )
93
+ end
94
+ end
95
+ end
96
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module EacCli
4
- VERSION = '0.8.0'
4
+ VERSION = '0.10.0'
5
5
  end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'eac_cli/docopt/runner_extension'
4
+
5
+ RSpec.describe ::EacCli::Docopt::RunnerExtension do
6
+ let(:stub_runner) do
7
+ r = Class.new(::EacRubyUtils::Console::DocoptRunner) do
8
+ def run; end
9
+ end
10
+ r.include ::EacCli::Runner
11
+ r.runner_definition do
12
+ desc 'A stub runner.'
13
+ arg_opt '-o', '--opt1', 'A argument option'
14
+ pos_arg 'pos1'
15
+ end
16
+ r
17
+ end
18
+
19
+ let(:instance) { stub_runner.new(argv: %w[-o aaa bbb]) }
20
+
21
+ before { instance.run }
22
+
23
+ it { expect(instance.options.fetch('--opt1')).to eq('aaa') }
24
+ it { expect(instance.options.fetch('<pos1>')).to eq('bbb') }
25
+ end
@@ -4,67 +4,75 @@ require 'eac_ruby_utils/console/docopt_runner'
4
4
  require 'eac_cli/runner'
5
5
 
6
6
  RSpec.describe ::EacCli::Runner do
7
- let(:stub_runner) do
8
- r = Class.new(::EacRubyUtils::Console::DocoptRunner) do
7
+ let(:runner_class) do
8
+ the_module = described_class
9
+ ::Class.new do
10
+ include the_module
11
+
12
+ runner_definition do
13
+ arg_opt '-o', '--opt1', 'A arg option.'
14
+ bool_opt '-o', '--opt2', 'A boolean option'
15
+ pos_arg :pos1
16
+ pos_arg :pos2, repeat: true, optional: true
17
+ alt do
18
+ bool_opt '-a', '--opt3', 'A boolean option in a alternative.', required: true
19
+ end
20
+ end
21
+
9
22
  def run; end
10
23
  end
11
- r.include described_class
12
- r.runner_definition do
13
- desc 'A stub runner.'
14
- arg_opt '-o', '--opt1', 'A argument option'
15
- pos_arg 'pos1'
16
- end
17
- r
18
24
  end
19
25
 
20
- let(:instance) { stub_runner.new(argv: %w[-o aaa bbb]) }
26
+ context 'when all args are supplied' do
27
+ let(:instance) { runner_class.create(%w[--opt1 aaa --opt2 bbb ccc ddd]) }
28
+
29
+ it { expect(instance.parsed.opt1).to eq('aaa') }
30
+ it { expect(instance.parsed.opt2?).to eq(true) }
31
+ it { expect(instance.parsed.pos1).to eq('bbb') }
32
+ it { expect(instance.parsed.pos2).to eq(%w[ccc ddd]) }
33
+ end
34
+
35
+ context 'when only required args are supplied' do
36
+ let(:instance) { runner_class.create(%w[bbb]) }
37
+
38
+ it { expect(instance.parsed.opt1).to be_nil }
39
+ it { expect(instance.parsed.opt2?).to eq(false) }
40
+ it { expect(instance.parsed.pos1).to eq('bbb') }
41
+ it { expect(instance.parsed.pos2).to eq([]) }
42
+ end
43
+
44
+ context 'when required args are not supplied' do
45
+ let(:instance) { runner_class.create(%w[]) }
21
46
 
22
- before { instance.run }
47
+ it do
48
+ expect { instance.parsed }.to raise_error(::EacCli::Parser::Error)
49
+ end
50
+ end
51
+
52
+ context 'when alternative args are supplied' do
53
+ let(:instance) { runner_class.create(%w[--opt3]) }
23
54
 
24
- it { expect(instance.options.fetch('--opt1')).to eq('aaa') }
25
- it { expect(instance.options.fetch('<pos1>')).to eq('bbb') }
55
+ it { expect(instance.parsed.opt3?).to eq(true) }
56
+ end
26
57
 
27
- context 'without docopt runner' do
58
+ context 'when extra args are not supplied' do
28
59
  let(:runner_class) do
29
60
  the_module = described_class
30
61
  ::Class.new do
31
62
  include the_module
32
63
 
33
64
  runner_definition do
34
- arg_opt '-o', '--opt1', 'A arg option.'
35
- bool_opt '-o', '--opt2', 'A boolean option'
36
65
  pos_arg :pos1
37
- pos_arg :pos2, repeat: true, optional: true
38
66
  end
39
67
 
40
68
  def run; end
41
69
  end
42
70
  end
43
71
 
44
- context 'when all args are supplied' do
45
- let(:instance) { runner_class.create(%w[--opt1 aaa --opt2 bbb ccc ddd]) }
46
-
47
- it { expect(instance.parsed.opt1).to eq('aaa') }
48
- it { expect(instance.parsed.opt2?).to eq(true) }
49
- it { expect(instance.parsed.pos1).to eq('bbb') }
50
- it { expect(instance.parsed.pos2).to eq(%w[ccc ddd]) }
51
- end
72
+ let(:instance) { runner_class.create(%w[aaa bbb]) }
52
73
 
53
- context 'when only required args are supplied' do
54
- let(:instance) { runner_class.create(%w[bbb]) }
55
-
56
- it { expect(instance.parsed.opt1).to be_nil }
57
- it { expect(instance.parsed.opt2?).to eq(false) }
58
- it { expect(instance.parsed.pos1).to eq('bbb') }
59
- it { expect(instance.parsed.pos2).to eq([]) }
60
- end
61
-
62
- context 'when required args are not supplied' do
63
- let(:instance) { runner_class.create(%w[]) }
64
-
65
- it do
66
- expect { instance.parsed }.to raise_error(::EacCli::Parser::Error)
67
- end
74
+ it do
75
+ expect { instance.parsed }.to raise_error(::EacCli::Parser::Error)
68
76
  end
69
77
  end
70
78
  end