eac_tools 0.66.0 → 0.67.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +28 -28
  3. data/lib/eac_tools/version.rb +1 -1
  4. data/sub/avm/avm.gemspec +2 -2
  5. data/sub/avm/lib/avm/data/clearer.rb +8 -6
  6. data/sub/avm/lib/avm/data/package/base_performer.rb +38 -0
  7. data/sub/avm/lib/avm/data/package/clear.rb +3 -4
  8. data/sub/avm/lib/avm/data/performer.rb +49 -0
  9. data/sub/avm/lib/avm/instances/runner.rb +1 -1
  10. data/sub/avm/lib/avm/sources/runner.rb +2 -0
  11. data/sub/avm/lib/avm/version.rb +1 -1
  12. data/sub/avm-eac_ubuntu_base0/avm-eac_ubuntu_base0.gemspec +3 -3
  13. data/sub/avm-eac_ubuntu_base0/lib/avm/eac_ubuntu_base0/runners/base.rb +2 -0
  14. data/sub/avm-eac_ubuntu_base0/lib/avm/eac_ubuntu_base0/version.rb +1 -1
  15. data/sub/avm-eac_webapp_base0/avm-eac_webapp_base0.gemspec +3 -3
  16. data/sub/avm-eac_webapp_base0/lib/avm/eac_webapp_base0/file_formats/provider.rb +2 -2
  17. data/sub/avm-eac_webapp_base0/lib/avm/eac_webapp_base0/version.rb +1 -1
  18. data/sub/avm-tools/avm-tools.gemspec +2 -2
  19. data/sub/avm-tools/lib/avm/tools/runner/instance/data/clear.rb +1 -1
  20. data/sub/avm-tools/lib/avm/tools/runner/instance/data/unit/dump.rb +2 -2
  21. data/sub/avm-tools/lib/avm/tools/runner/instance/data/unit/load.rb +1 -1
  22. data/sub/avm-tools/lib/avm/tools/runner/instance/data/unit.rb +2 -5
  23. data/sub/avm-tools/lib/avm/tools/runner/instance/data.rb +2 -0
  24. data/sub/avm-tools/lib/avm/tools/runner_with/include_exclude.rb +23 -0
  25. data/sub/avm-tools/lib/avm/tools/runner_with/instance_data_clear.rb +11 -1
  26. data/sub/avm-tools/lib/avm/tools/version.rb +1 -1
  27. data/sub/eac_cli/eac_cli.gemspec +1 -1
  28. data/sub/eac_cli/lib/eac_cli/definition/alternative.rb +11 -7
  29. data/sub/eac_cli/lib/eac_cli/definition/base_option/initialize_args_parser.rb +2 -1
  30. data/sub/eac_cli/lib/eac_cli/definition/base_option.rb +1 -1
  31. data/sub/eac_cli/lib/eac_cli/definition/boolean_option.rb +2 -1
  32. data/sub/eac_cli/lib/eac_cli/definition/error.rb +8 -0
  33. data/sub/eac_cli/lib/eac_cli/runner/after_class_methods.rb +6 -1
  34. data/sub/eac_cli/lib/eac_cli/runner/context.rb +22 -3
  35. data/sub/eac_cli/lib/eac_cli/runner/context_responders/base.rb +24 -0
  36. data/sub/eac_cli/lib/eac_cli/runner/context_responders/parent.rb +27 -0
  37. data/sub/eac_cli/lib/eac_cli/runner/context_responders/runner.rb +20 -0
  38. data/sub/eac_cli/lib/eac_cli/runner/context_responders/runner_missing_method.rb +32 -0
  39. data/sub/eac_cli/lib/eac_cli/runner/context_responders/set.rb +44 -0
  40. data/sub/eac_cli/lib/eac_cli/runner/context_responders.rb +11 -0
  41. data/sub/eac_cli/lib/eac_cli/runner/for_context.rb +40 -0
  42. data/sub/eac_cli/lib/eac_cli/runner/instance_methods.rb +5 -3
  43. data/sub/eac_cli/lib/eac_cli/runner.rb +1 -0
  44. data/sub/eac_cli/lib/eac_cli/version.rb +1 -1
  45. data/sub/eac_cli/spec/lib/eac_cli/runner/for_context_spec.rb +79 -0
  46. data/sub/eac_cli/spec/lib/eac_cli/runner_with/subcommands_spec.rb +1 -0
  47. data/sub/eac_ruby_base0/eac_ruby_base0.gemspec +3 -3
  48. data/sub/eac_ruby_base0/lib/eac_ruby_base0/runner/contexts.rb +52 -0
  49. data/sub/eac_ruby_base0/lib/eac_ruby_base0/runner/prepend.rb +17 -4
  50. data/sub/eac_ruby_base0/lib/eac_ruby_base0/runner.rb +1 -39
  51. data/sub/eac_ruby_base0/lib/eac_ruby_base0/version.rb +1 -1
  52. data/sub/eac_ruby_utils/lib/eac_ruby_utils/acts_as_abstract.rb +17 -6
  53. data/sub/eac_ruby_utils/lib/eac_ruby_utils/acts_as_immutable/array_accessor.rb +25 -0
  54. data/sub/eac_ruby_utils/lib/eac_ruby_utils/acts_as_immutable/base_accessor.rb +57 -0
  55. data/sub/eac_ruby_utils/lib/eac_ruby_utils/{immutable → acts_as_immutable}/boolean_accessor.rb +3 -3
  56. data/sub/eac_ruby_utils/lib/eac_ruby_utils/{immutable → acts_as_immutable}/class_methods.rb +2 -2
  57. data/sub/eac_ruby_utils/lib/eac_ruby_utils/{immutable → acts_as_immutable}/common_accessor.rb +5 -5
  58. data/sub/eac_ruby_utils/lib/eac_ruby_utils/{immutable/array_accessor.rb → acts_as_immutable/enumerable_accessor.rb} +11 -8
  59. data/sub/eac_ruby_utils/lib/eac_ruby_utils/{immutable → acts_as_immutable}/hash_accessor.rb +5 -5
  60. data/sub/eac_ruby_utils/lib/eac_ruby_utils/{immutable → acts_as_immutable}/instance_methods.rb +1 -1
  61. data/sub/eac_ruby_utils/lib/eac_ruby_utils/acts_as_immutable/set_accessor.rb +25 -0
  62. data/sub/eac_ruby_utils/lib/eac_ruby_utils/{immutable.rb → acts_as_immutable.rb} +1 -1
  63. data/sub/eac_ruby_utils/lib/eac_ruby_utils/enumerables_methods.rb +42 -0
  64. data/sub/eac_ruby_utils/lib/eac_ruby_utils/module_ancestors_variable/base.rb +34 -0
  65. data/sub/eac_ruby_utils/lib/eac_ruby_utils/module_ancestors_variable/hash.rb +20 -0
  66. data/sub/eac_ruby_utils/lib/eac_ruby_utils/module_ancestors_variable/set.rb +19 -0
  67. data/sub/eac_ruby_utils/lib/eac_ruby_utils/module_ancestors_variable.rb +9 -0
  68. data/sub/eac_ruby_utils/lib/eac_ruby_utils/patches/module/acts_as_immutable.rb +10 -0
  69. data/sub/eac_ruby_utils/lib/eac_ruby_utils/patches/module/immutable.rb +3 -2
  70. data/sub/eac_ruby_utils/lib/eac_ruby_utils/patches/object/debug.rb +9 -0
  71. data/sub/eac_ruby_utils/lib/eac_ruby_utils/unimplemented_method_error.rb +6 -0
  72. data/sub/eac_ruby_utils/lib/eac_ruby_utils/version.rb +1 -1
  73. data/sub/eac_ruby_utils/spec/lib/eac_ruby_utils/acts_as_abstract_spec.rb +73 -7
  74. data/sub/eac_ruby_utils/spec/lib/eac_ruby_utils/{immutable → acts_as_immutable}/array_accessor_spec.rb +11 -3
  75. data/sub/eac_ruby_utils/spec/lib/eac_ruby_utils/acts_as_immutable/common_accessor_spec.rb +57 -0
  76. data/sub/eac_ruby_utils/spec/lib/eac_ruby_utils/{immutable → acts_as_immutable}/hash_accessor_spec.rb +3 -3
  77. data/sub/eac_ruby_utils/spec/lib/eac_ruby_utils/acts_as_immutable/set_accessor_spec.rb +43 -0
  78. data/sub/eac_ruby_utils/spec/lib/eac_ruby_utils/enumerables_methods_spec.rb +50 -0
  79. data/sub/eac_ruby_utils/spec/lib/eac_ruby_utils/module_ancestors_variable/hash_spec.rb +57 -0
  80. data/sub/eac_ruby_utils/spec/lib/eac_ruby_utils/module_ancestors_variable/set_spec.rb +57 -0
  81. metadata +47 -20
  82. data/sub/eac_ruby_utils/lib/eac_ruby_utils/immutable/base_accessor.rb +0 -23
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'eac_cli/definition'
4
+ require 'eac_cli/definition/error'
4
5
  require 'eac_cli/runner/class_runner'
5
6
 
6
7
  module EacCli
@@ -21,7 +22,11 @@ module EacCli
21
22
 
22
23
  def runner_definition(&block)
23
24
  @runner_definition ||= super_runner_definition
24
- @runner_definition.instance_eval(&block) if block
25
+ begin
26
+ @runner_definition.instance_eval(&block) if block
27
+ rescue ::EacCli::Definition::Error => _e
28
+ raise ::EacCli::Definition::Error, "Definition error for #{self}"
29
+ end
25
30
  @runner_definition
26
31
  end
27
32
 
@@ -1,6 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'eac_ruby_utils/core_ext'
4
+ require 'eac_cli/runner/context_responders/parent'
5
+ require 'eac_cli/runner/context_responders/runner'
6
+ require 'eac_cli/runner/context_responders/runner_missing_method'
7
+ require 'eac_cli/runner/context_responders/set'
4
8
 
5
9
  module EacCli
6
10
  module Runner
@@ -17,10 +21,19 @@ module EacCli
17
21
 
18
22
  # Call a method in the runner or in one of it ancestors.
19
23
  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_respond_to?(method_name)
24
+ context_call_responder(method_name).call(*args)
25
+ end
26
+
27
+ # @return [EacCli::Runner::ContextResponders]
28
+ def context_call_responder(method_name)
29
+ ::EacCli::Runner::ContextResponders::Set.new(self, method_name, %i[runner parent])
30
+ end
22
31
 
23
- raise ::NameError, "No method \"#{method_name}\" found in #{runner} or in its ancestors"
32
+ # @param method_name [Symbol]
33
+ # @return [EacCli::Runner::ContextResponders::Parent]
34
+ def runner_missing_method_responder(method_name)
35
+ ::EacCli::Runner::ContextResponders::RunnerMissingMethod
36
+ .new(self, method_name)
24
37
  end
25
38
 
26
39
  # @param method_name [Symbol]
@@ -38,6 +51,12 @@ module EacCli
38
51
 
39
52
  raise "Parent #{parent} do not respond to .context or .runner_context (Runner: #{runner})"
40
53
  end
54
+
55
+ # @param method_name [Symbol]
56
+ # @return [EacCli::Runner::ContextResponders::Parent]
57
+ def parent_responder(method_name)
58
+ ::EacCli::Runner::ContextResponders::Parent.new(self, method_name)
59
+ end
41
60
  end
42
61
  end
43
62
  end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'eac_ruby_utils/core_ext'
4
+
5
+ module EacCli
6
+ module Runner
7
+ module ContextResponders
8
+ class Base
9
+ acts_as_abstract :call, :callable?
10
+ common_constructor :context, :method_name do
11
+ self.method_name = method_name.to_sym
12
+ end
13
+ delegate :parent, :runner, to: :context
14
+
15
+ def if_callable
16
+ return false unless callable?
17
+
18
+ yield(self)
19
+ true
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'eac_ruby_utils/core_ext'
4
+ require 'eac_cli/runner/context_responders/base'
5
+
6
+ module EacCli
7
+ module Runner
8
+ module ContextResponders
9
+ class Parent < ::EacCli::Runner::ContextResponders::Base
10
+ def callable?
11
+ parent.if_present(false) do |v|
12
+ next true if v.respond_to?(method_name)
13
+
14
+ v.if_respond(:runner_context, false) { |w| w.parent_respond_to?(method_name) }
15
+ end
16
+ end
17
+
18
+ def call(*args, &block)
19
+ return parent.runner_context.call(method_name, *args, &block) if
20
+ parent.respond_to?(:runner_context)
21
+
22
+ raise "Parent #{parent} do not respond to .context or .runner_context (Runner: #{runner})"
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'eac_ruby_utils/core_ext'
4
+ require 'eac_cli/runner/context_responders/base'
5
+
6
+ module EacCli
7
+ module Runner
8
+ module ContextResponders
9
+ class Runner < ::EacCli::Runner::ContextResponders::Base
10
+ def callable?
11
+ runner.respond_to?(method_name)
12
+ end
13
+
14
+ def call(*args, &block)
15
+ runner.send(method_name, *args, &block)
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'eac_ruby_utils/core_ext'
4
+ require 'eac_cli/runner/context_responders/base'
5
+
6
+ module EacCli
7
+ module Runner
8
+ module ContextResponders
9
+ class RunnerMissingMethod < ::EacCli::Runner::ContextResponders::Base
10
+ def callable?
11
+ responder_runner.present?
12
+ end
13
+
14
+ def call(*args, &block)
15
+ responder_runner.send(method_name, *args, &block)
16
+ end
17
+
18
+ private
19
+
20
+ def responder_runner
21
+ parent.if_present(nil) do |v|
22
+ next v if v.respond_to?(method_name) && v.for_context?(method_name)
23
+
24
+ v.if_respond(:runner_context, nil) do |w|
25
+ w.runner_missing_method_responder(method_name).send(__method__)
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'eac_ruby_utils/core_ext'
4
+ require 'eac_cli/runner/context_responders/base'
5
+
6
+ module EacCli
7
+ module Runner
8
+ module ContextResponders
9
+ class Set < ::EacCli::Runner::ContextResponders::Base
10
+ attr_reader :responders_names
11
+
12
+ def initialize(context, method_name, responders_names)
13
+ super(context, method_name)
14
+ @responders_names = responders_names
15
+ end
16
+
17
+ def callable?
18
+ responders_instances.any?(&:callable?)
19
+ end
20
+
21
+ def call(*args, &block)
22
+ caller = responder_to_call
23
+ return caller.call(*args, &block) if caller
24
+
25
+ raise ::NameError, "No method \"#{method_name}\" found in #{runner} or in its ancestors"
26
+ end
27
+
28
+ private
29
+
30
+ def responder_class(class_name)
31
+ ::EacCli::Runner::ContextResponders.const_get(class_name.to_s.camelize)
32
+ end
33
+
34
+ def responders_instances
35
+ responders_names.lazy.map { |name| responder_class(name).new(context, method_name) }
36
+ end
37
+
38
+ def responder_to_call
39
+ responders_instances.lazy.select(&:callable?).first
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'eac_ruby_utils/core_ext'
4
+
5
+ module EacCli
6
+ module Runner
7
+ module ContextResponders
8
+ require_sub __FILE__
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'eac_ruby_utils/core_ext'
4
+ require 'eac_ruby_utils/module_ancestors_variable/set'
5
+
6
+ module EacCli
7
+ module Runner
8
+ module ForContext
9
+ common_concern
10
+
11
+ module ClassMethods
12
+ # @param methods_names [Enumerable<Symbol>]
13
+ # @return [void]
14
+ def for_context(*methods_names)
15
+ for_context_methods.merge(methods_names.map(&:to_sym))
16
+ end
17
+
18
+ # @param method_name [Symbol]
19
+ # @return [Boolean]
20
+ def for_context?(method_name)
21
+ for_context_methods.include?(method_name.to_sym)
22
+ end
23
+
24
+ private
25
+
26
+ # @return [EacRubyUtils::ModuleAncestorsVariable::Set<Symbol>]
27
+ def for_context_methods
28
+ @for_context_methods ||=
29
+ ::EacRubyUtils::ModuleAncestorsVariable::Set.new(self, __method__)
30
+ end
31
+ end
32
+
33
+ # @param method_name [Symbol]
34
+ # @return [Boolean]
35
+ def for_context?(method_name)
36
+ self.class.for_context?(method_name)
37
+ end
38
+ end
39
+ end
40
+ end
@@ -30,13 +30,15 @@ module EacCli
30
30
  end
31
31
 
32
32
  def respond_to_missing?(method, include_all = false)
33
- runner_context.parent_respond_to?(method) || super
33
+ runner_context.runner_missing_method_responder(method).callable? || super
34
34
  end
35
35
 
36
36
  def method_missing(method, *args, &block)
37
- return super unless runner_context.parent_respond_to?(method)
37
+ runner_context.runner_missing_method_responder(method).if_callable do |v|
38
+ return v.call(*args, &block)
39
+ end
38
40
 
39
- runner_context.parent_call(method, *args, &block)
41
+ super
40
42
  end
41
43
  end
42
44
  end
@@ -42,6 +42,7 @@ module EacCli
42
42
 
43
43
  extend AfterClassMethods
44
44
  include InstanceMethods
45
+ include ::EacCli::Runner::ForContext
45
46
  include ActiveSupport::Callbacks
46
47
  define_callbacks :run
47
48
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module EacCli
4
- VERSION = '0.34.0'
4
+ VERSION = '0.35.0'
5
5
  end
@@ -0,0 +1,79 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'eac_cli/runner'
4
+
5
+ ::RSpec.describe ::EacCli::Runner do
6
+ let(:parent_runner_class) do
7
+ example = self
8
+ ::Class.new do
9
+ include example.described_class
10
+
11
+ def self.name
12
+ 'ParentRunnerClass'
13
+ end
14
+
15
+ for_context :method_for_context
16
+
17
+ def run; end
18
+
19
+ def method_for_context; end
20
+
21
+ def method_not_for_context; end
22
+ end
23
+ end
24
+
25
+ let(:child_runner_class_1) do
26
+ example = self
27
+ ::Class.new do
28
+ include example.described_class
29
+
30
+ def self.name
31
+ 'ChildRunnerClass1'
32
+ end
33
+
34
+ def run
35
+ method_for_context
36
+ runner_context.call(:method_for_context)
37
+ runner_context.call(:method_not_for_context)
38
+ end
39
+ end
40
+ end
41
+
42
+ let(:child_runner_class_2) do
43
+ example = self
44
+ ::Class.new do
45
+ include example.described_class
46
+
47
+ def self.name
48
+ 'ChildRunnerClass2'
49
+ end
50
+
51
+ def run
52
+ method_not_for_context
53
+ end
54
+ end
55
+ end
56
+
57
+ let(:parent_runner) { parent_runner_class.create }
58
+ let(:context_args) { [{ argv: [], parent: parent_runner }] }
59
+ let(:child_runner) { child_runner_class.create(*context_args) }
60
+
61
+ it { expect(parent_runner.for_context?(:method_for_context)).to eq(true) }
62
+ it { expect(parent_runner.for_context?(:method_not_for_context)).to eq(false) }
63
+
64
+ context 'when method is for context' do
65
+ let(:child_runner_class) { child_runner_class_1 }
66
+
67
+ it do
68
+ expect { child_runner.run }.not_to raise_error
69
+ end
70
+ end
71
+
72
+ context 'when method is not for context' do
73
+ let(:child_runner_class) { child_runner_class_2 }
74
+
75
+ it do
76
+ expect { child_runner.run }.to raise_error(::NameError)
77
+ end
78
+ end
79
+ end
@@ -19,6 +19,7 @@ RSpec.describe ::EacCli::RunnerWith::Subcommands do
19
19
  end
20
20
 
21
21
  delegate :root_var, to: :parsed
22
+ for_context :method_in_parent_runner
22
23
 
23
24
  def method_in_parent_runner; end
24
25
  end
@@ -12,10 +12,10 @@ Gem::Specification.new do |s|
12
12
 
13
13
  s.files = Dir['{lib}/**/*']
14
14
 
15
- s.add_dependency 'avm-eac_ruby_base1', '~> 0.30', '>= 0.30.2'
16
- s.add_dependency 'eac_cli', '~> 0.31'
15
+ s.add_dependency 'avm-eac_ruby_base1', '~> 0.30', '>= 0.30.3'
16
+ s.add_dependency 'eac_cli', '~> 0.35'
17
17
  s.add_dependency 'eac_fs', '~> 0.16'
18
- s.add_dependency 'eac_ruby_utils', '~> 0.112'
18
+ s.add_dependency 'eac_ruby_utils', '~> 0.117'
19
19
 
20
20
  s.add_development_dependency 'eac_ruby_gem_support', '~> 0.5.1'
21
21
  end
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'eac_config/node'
4
+ require 'eac_fs/contexts'
5
+ require 'eac_ruby_utils/core_ext'
6
+ require 'eac_ruby_utils/speaker'
7
+
8
+ module EacRubyBase0
9
+ module Runner
10
+ module Contexts
11
+ def on_context(&block)
12
+ top_block = block
13
+ available_contexts.each do |context|
14
+ next if context.object.any?
15
+
16
+ last_block = top_block
17
+ top_block = ::Proc.new { context.object.on(context.builder.call, &last_block) }
18
+ end
19
+ top_block.call
20
+ end
21
+
22
+ private
23
+
24
+ # @return [Array<EacRubyUtils::Struct>]
25
+ def available_contexts
26
+ (filesystem_available_contexts + [
27
+ [:config, ::EacConfig::Node.context,
28
+ -> { runner_context.call(:application).build_config }],
29
+ [:speaker, ::EacRubyUtils::Speaker.context, -> { build_speaker }]
30
+ ]).map { |row| available_context_row_to_struct(row) }
31
+ end
32
+
33
+ def available_context_row_to_struct(row)
34
+ %i[type object builder].zip(row).to_h.to_struct
35
+ end
36
+
37
+ def build_speaker
38
+ options = {}
39
+ options[:err_out] = ::StringIO.new if parsed.quiet?
40
+ options[:in_in] = ::EacCli::Speaker::InputBlocked.new if parsed.no_input?
41
+ ::EacCli::Speaker.new(options)
42
+ end
43
+
44
+ def filesystem_available_contexts
45
+ ::EacFs::Contexts::TYPES.map do |type|
46
+ key = "fs_#{type}".to_sym
47
+ [key, ::EacFs::Contexts.send(type), -> { application.send("self_#{key}") }]
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
@@ -10,17 +10,30 @@ require 'eac_ruby_utils/speaker'
10
10
  module EacRubyBase0
11
11
  module Runner
12
12
  module Prepend
13
+ SYSTEM_STACK_ERROR_FILE = 'system_stack_error'
14
+
13
15
  def run
14
- if parsed.version?
15
- show_version
16
- else
17
- run_with_subcommand
16
+ on_rescue_stack_overflow do
17
+ if parsed.version?
18
+ show_version
19
+ else
20
+ run_with_subcommand
21
+ end
18
22
  end
19
23
  end
20
24
 
21
25
  def run_run
22
26
  on_context { super }
23
27
  end
28
+
29
+ private
30
+
31
+ def on_rescue_stack_overflow
32
+ yield
33
+ rescue ::SystemStackError => e
34
+ SYSTEM_STACK_ERROR_FILE.to_pathname.write(e.backtrace.map { |v| "#{v}\n" }.join)
35
+ raise e
36
+ end
24
37
  end
25
38
  end
26
39
  end
@@ -14,6 +14,7 @@ module EacRubyBase0
14
14
  common_concern do
15
15
  include ::EacCli::RunnerWith::Help
16
16
  include ::EacCli::RunnerWith::Subcommands
17
+ include ::EacRubyBase0::Runner::Contexts
17
18
  prepend ::EacRubyBase0::Runner::Prepend
18
19
  runner_definition do
19
20
  bool_opt '-q', '--quiet', 'Quiet mode.'
@@ -29,47 +30,8 @@ module EacRubyBase0
29
30
  runner_context.call(:application).version.to_s
30
31
  end
31
32
 
32
- def on_context(&block)
33
- top_block = block
34
- available_contexts.each do |context|
35
- next if context.object.any?
36
-
37
- last_block = top_block
38
- top_block = ::Proc.new { context.object.on(context.builder.call, &last_block) }
39
- end
40
- top_block.call
41
- end
42
-
43
33
  def show_version
44
34
  out("#{application_version}\n")
45
35
  end
46
-
47
- private
48
-
49
- # @return [Array<EacRubyUtils::Struct>]
50
- def available_contexts
51
- (filesystem_available_contexts + [
52
- [:config, ::EacConfig::Node.context, -> { runner_context.call(:application).build_config }],
53
- [:speaker, ::EacRubyUtils::Speaker.context, -> { build_speaker }]
54
- ]).map { |row| available_context_row_to_struct(row) }
55
- end
56
-
57
- def available_context_row_to_struct(row)
58
- %i[type object builder].zip(row).to_h.to_struct
59
- end
60
-
61
- def build_speaker
62
- options = {}
63
- options[:err_out] = ::StringIO.new if parsed.quiet?
64
- options[:in_in] = ::EacCli::Speaker::InputBlocked.new if parsed.no_input?
65
- ::EacCli::Speaker.new(options)
66
- end
67
-
68
- def filesystem_available_contexts
69
- ::EacFs::Contexts::TYPES.map do |type|
70
- key = "fs_#{type}".to_sym
71
- [key, ::EacFs::Contexts.send(type), -> { application.send("self_#{key}") }]
72
- end
73
- end
74
36
  end
75
37
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module EacRubyBase0
4
- VERSION = '0.18.0'
4
+ VERSION = '0.19.0'
5
5
  end
@@ -1,7 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'eac_ruby_utils/module_ancestors_variable/hash'
3
4
  require 'eac_ruby_utils/patches/class/self_included_modules'
4
5
  require 'eac_ruby_utils/patches/module/common_concern'
6
+ require 'eac_ruby_utils/unimplemented_method_error'
5
7
 
6
8
  module EacRubyUtils
7
9
  # Support to abstract methods.
@@ -39,9 +41,7 @@ module EacRubyUtils
39
41
  # @param arguments [Enumerable<Symbol>]
40
42
  # @return [void]
41
43
  def abstract_method(name, *arguments)
42
- define_method name.to_sym do |*_the_args|
43
- raise_abstract_method(name.to_sym, arguments)
44
- end
44
+ abstract_methods_hash[name.to_sym] = arguments
45
45
  end
46
46
 
47
47
  # @param methods_names [Enumerable<Object>] Each item can be a symbolizable or a hash.
@@ -63,6 +63,12 @@ module EacRubyUtils
63
63
  def abstract_methods_from_hash(hash)
64
64
  hash.each { |name, arguments| abstract_method(name, *arguments) }
65
65
  end
66
+
67
+ # @return [Hash<Symbol, Array]
68
+ def abstract_methods_hash
69
+ @abstract_methods_hash ||=
70
+ ::EacRubyUtils::ModuleAncestorsVariable::Hash.new(self, __method__)
71
+ end
66
72
  end
67
73
 
68
74
  module InstanceMethods
@@ -76,13 +82,18 @@ module EacRubyUtils
76
82
  super
77
83
  end
78
84
 
85
+ # @param method_name [Symbol]
86
+ # @return [Boolean]
79
87
  def abstract_method?(method_name)
80
- self.class.abstract_methods.include?(method_name.to_sym)
88
+ return false if self.class.method_defined?(method_name)
89
+
90
+ self.class.send(:abstract_methods_hash).key?(method_name.to_sym)
81
91
  end
82
92
 
83
93
  def raise_abstract_method(method_name, arguments = [])
84
- raise ::NoMethodError, "Abstract method #{method_name}(#{arguments.join(', ')}) hit in " \
85
- "#{self}\" (Class: #{self.class})"
94
+ raise ::EacRubyUtils::UnimplementedMethodError,
95
+ "Abstract method #{method_name}(#{arguments.join(', ')}) hit in " \
96
+ "#{self}\" (Class: #{self.class})"
86
97
  end
87
98
  end
88
99
  end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'eac_ruby_utils/acts_as_immutable/enumerable_accessor'
4
+
5
+ module EacRubyUtils
6
+ module ActsAsImmutable
7
+ class ArrayAccessor < ::EacRubyUtils::ActsAsImmutable::EnumerableAccessor
8
+ INITIAL_VALUE = [].freeze
9
+
10
+ # @param value [Object]
11
+ # @return [Array]
12
+ def immutable_value_set_assert(value)
13
+ return value if value.is_a?(::Array)
14
+ return value.to_a if value.respond_to?(:to_a)
15
+
16
+ Array(value)
17
+ end
18
+
19
+ # @return [Array] A empty array.
20
+ def initial_value
21
+ INITIAL_VALUE
22
+ end
23
+ end
24
+ end
25
+ end