eac_tools 0.66.0 → 0.67.0

Sign up to get free protection for your applications and to get access to all the features.
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