avm 0.23.0 → 0.26.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9dbfd028daf9c304679d35bee81282c6bfbee007613933e1482c9b3c58cf824d
4
- data.tar.gz: 16bdf2e2fafcd9bfc52cdeabb555ff1ce392d8e4165661f3e74ca00b5304d2ee
3
+ metadata.gz: 409db17d04ee296956e9770e61a5f65919fbf2b0c8bea4efae0ed68fb169572a
4
+ data.tar.gz: 3c7e6ea386a2527ed86c3bb9ef8a71b1767d17a204d48b1ecc3b74c015772328
5
5
  SHA512:
6
- metadata.gz: f649eb88ed02c4201cc7810836e923932772685eee29f7274f1fe8e3c1202205829607e093c817a52ad50ef12253e2d43415537e40b7b84d3082e73aa99d893e
7
- data.tar.gz: 5ebb0af2860921456ee00f4c5867ae4e68f916977aacee5c915044e95cb53162ae34dc3df6abc11234456cce04abeb5f228aa2bd745b769d2f59b5cab4e94cfe
6
+ metadata.gz: 302b99ff7495bf6c3f4624432e63f1f2668f8b5d2a2ac91bc721f3206baf9595520c192fa4ead326ad7ce3c646253ca7f1a71a48ee1b11080e1898efe4fef5f8
7
+ data.tar.gz: 7b85ae2c2a03f3abfeed96924ab6e0180d17709ec422cd3b0638f7075cc750c25a8118d7654554ecfe80519fdeb505da9aa720f2109fdf7bcacfdf7bf884d141
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'avm/registry/base'
4
+ require 'eac_ruby_utils/core_ext'
5
+
6
+ module Avm
7
+ module Registry
8
+ class WithPath < ::Avm::Registry::Base
9
+ class Cache
10
+ enable_simple_cache
11
+ common_constructor :owner
12
+
13
+ def detect_optional(path)
14
+ return nil if path.root?
15
+ return cached_paths.fetch(path) if cached_paths.key?(path)
16
+
17
+ detected = owner.detect_optional(path)
18
+ detected = detect_optional(path.parent) if detected.blank?
19
+ cached_paths[path] = detected
20
+ detected
21
+ end
22
+
23
+ private
24
+
25
+ def cached_paths_uncached
26
+ {}
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -6,17 +6,37 @@ require 'eac_ruby_utils/core_ext'
6
6
  module Avm
7
7
  module Registry
8
8
  class WithPath < ::Avm::Registry::Base
9
+ require_sub __FILE__
10
+
9
11
  def detect_by_path(path)
10
12
  detect_by_path_optional(path) || raise_not_found(path)
11
13
  end
12
14
 
13
15
  def detect_by_path_optional(path)
14
- current_path = path.to_pathname.expand_path
15
- until current_path.root?
16
- detect_optional(current_path).if_present { |v| return v }
17
- current_path = current_path.parent
16
+ on_cache do
17
+ cache.detect_optional(path)
18
+ end
19
+ end
20
+
21
+ private
22
+
23
+ attr_accessor :cache
24
+
25
+ def on_cache(&block)
26
+ cache.present? ? on_cache_with_cache(&block) : on_cache_with_no_cache(&block)
27
+ end
28
+
29
+ def on_cache_with_cache(&block)
30
+ block.call
31
+ end
32
+
33
+ def on_cache_with_no_cache(&block)
34
+ self.cache = ::Avm::Registry::WithPath::Cache.new(self)
35
+ begin
36
+ block.call
37
+ ensure
38
+ self.cache = nil
18
39
  end
19
- nil
20
40
  end
21
41
  end
22
42
  end
@@ -9,21 +9,40 @@ module Avm
9
9
  module Sources
10
10
  class Base
11
11
  module Configuration
12
+ PARENT_CONFIGURATION_SUFFIX = %w[subs at].freeze
12
13
  CONFIGURATION_FILENAMES = %w[.avm.yml .avm.yaml].freeze
13
14
 
15
+ # @return [EacConfig::NodeEntry]
16
+ def configuration_entry(*entry_args)
17
+ parent_configuration.if_present do |v|
18
+ parent_entry = v.entry(*entry_args)
19
+ return parent_entry if parent_entry.found?
20
+ end
21
+
22
+ configuration.entry(*entry_args)
23
+ end
24
+
25
+ # @return [EacRubyUtils::Envs::Command, nil]
26
+ def configuration_value_to_env_command(value)
27
+ configuration_value_to_shell_words(value).if_present { |v| env.command(v).chdir(path) }
28
+ end
29
+
30
+ # @return [Array<String>, nil]
31
+ def configuration_value_to_shell_words(value)
32
+ return nil if value.blank?
33
+
34
+ value.is_a?(::Enumerable) ? value.map(&:to_s) : ::Shellwords.split(value.to_s)
35
+ end
36
+
14
37
  # @return [Array<String>, nil]
15
38
  def read_configuration_as_shell_words(key)
16
- configuration.entry(key).value.if_present do |v|
17
- v.is_a?(::Enumerable) ? v.map(&:to_s) : ::Shellwords.split(v.to_s)
18
- end
39
+ configuration_value_to_shell_words(configuration_entry(key).value)
19
40
  end
20
41
 
21
42
  # Utility to read a configuration as a [EacRubyUtils::Envs::Command].
22
43
  # @return [EacRubyUtils::Envs::Command]
23
44
  def read_configuration_as_env_command(key)
24
- read_configuration_as_shell_words(key).if_present do |v|
25
- env.command(v).chdir(path)
26
- end
45
+ configuration_value_to_env_command(configuration_entry(key).value)
27
46
  end
28
47
 
29
48
  private
@@ -36,6 +55,16 @@ module Avm
36
55
  configuration_with_filename(CONFIGURATION_FILENAMES.first, false)
37
56
  end
38
57
 
58
+ # @return [String]
59
+ def parent_configuration_prefix
60
+ PARENT_CONFIGURATION_SUFFIX + [relative_path]
61
+ end
62
+
63
+ # @return [EacConfig::PrefixedPathNode]
64
+ def parent_configuration_uncached
65
+ parent.if_present { |v| v.configuration.with_prefix(parent_configuration_prefix) }
66
+ end
67
+
39
68
  # @return [EacConfig::YamlFileNode, nil]
40
69
  def configuration_with_filename(filename, needs_exist)
41
70
  file_path = path.join(filename)
@@ -14,7 +14,7 @@ module Avm
14
14
  end
15
15
 
16
16
  def configured_locale
17
- configuration.entry(LOCALE_KEY).value
17
+ configuration_entry(LOCALE_KEY).value
18
18
  end
19
19
 
20
20
  def default_locale
@@ -6,11 +6,6 @@ module Avm
6
6
  module Sources
7
7
  class Base
8
8
  module Parent
9
- # @return [Avm::Sources::Base]
10
- def parent
11
- parent_by_option || parent_by_search
12
- end
13
-
14
9
  # @return [Avm::Sources::Base]
15
10
  def parent_by_option
16
11
  options[OPTION_PARENT]
@@ -18,12 +13,14 @@ module Avm
18
13
 
19
14
  # @return [Avm::Sources::Base]
20
15
  def parent_by_search
21
- parent_path = path.parent
22
- until parent_path.root?
23
- ::Avm::Registry.sources.detect_optional(parent_path).if_present { |v| return v }
24
- parent_path = parent_path.parent
25
- end
26
- nil
16
+ ::Avm::Registry.sources.detect_by_path_optional(path.parent)
17
+ end
18
+
19
+ private
20
+
21
+ # @return [Avm::Sources::Base]
22
+ def parent_uncached
23
+ parent_by_option || parent_by_search
27
24
  end
28
25
  end
29
26
  end
@@ -22,7 +22,7 @@ module Avm
22
22
 
23
23
  # @return [Array<String>]
24
24
  def configured_paths
25
- source.configuration.entry(configuration_key).value.if_present do |v|
25
+ source.configuration_entry(configuration_key).value.if_present do |v|
26
26
  v.split(SUBS_PATH_SEPARATOR)
27
27
  end
28
28
  end
@@ -1,25 +1,68 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'eac_ruby_utils/core_ext'
4
+ require 'eac_ruby_utils/envs/command'
4
5
 
5
6
  module Avm
6
7
  module Sources
7
8
  class Base
8
9
  module Testing
9
- TEST_COMMAND_KEY = 'test.command'
10
+ DEFAULT_TEST_COMMANDS = {}.freeze
11
+ TEST_KEY = 'test'
12
+ TEST_COMMAND_KEY = "#{TEST_KEY}.command"
13
+ TEST_COMMANDS_KEY = "#{TEST_KEY}.commands"
10
14
 
11
15
  def configured_test_command
12
16
  read_configuration_as_env_command(TEST_COMMAND_KEY)
13
17
  end
14
18
 
15
- # @return [Avm::Sources::Tester]
16
- def tester
17
- tester_class.new(self)
19
+ # @return [Hash<String, EacRubyUtils::Envs::Command>, nil]
20
+ def configured_test_commands
21
+ configured_value_as_test_commands(configuration_entry(TEST_COMMANDS_KEY).value)
18
22
  end
19
23
 
20
- # @return [Class<Avm::Sources::Tester>
21
- def tester_class
22
- Avm::Sources::Tester
24
+ # @return [Hash<String, EacRubyUtils::Envs::Command>, nil]
25
+ def configured_value_as_test_commands(value)
26
+ return nil if value.nil?
27
+
28
+ [::EacRubyUtils::Envs::Command, ::Hash, ::Enumerable].each do |type|
29
+ next unless value.is_a?(type)
30
+
31
+ return send(
32
+ "configured_#{type.name.demodulize.variableize}_value_as_test_commands",
33
+ value
34
+ )
35
+ end
36
+
37
+ raise "Value for test commands should be a Hash or a Enumerable (Actual: #{value})"
38
+ end
39
+
40
+ # @return [Hash<String, EacRubyUtils::Envs::Command>]
41
+ def default_test_commands
42
+ DEFAULT_TEST_COMMANDS
43
+ end
44
+
45
+ # @return [Enumerable<EacRubyUtils::Envs::Command>]
46
+ def test_commands
47
+ configured_test_commands ||
48
+ configured_value_as_test_commands(configured_test_command) ||
49
+ default_test_commands
50
+ end
51
+
52
+ protected
53
+
54
+ def configured_command_value_as_test_commands(value)
55
+ configured_enumerable_value_as_test_commands([value])
56
+ end
57
+
58
+ def configured_enumerable_value_as_test_commands(value)
59
+ configured_hash_value_as_test_commands(
60
+ value.each_with_index.map { |v| ["test_#{v[1]}", v[0]] }.to_h
61
+ )
62
+ end
63
+
64
+ def configured_hash_value_as_test_commands(value)
65
+ value.map { |k, v| [k.to_s.strip, configuration_value_to_env_command(v)] }.to_h
23
66
  end
24
67
  end
25
68
  end
@@ -8,6 +8,8 @@ module Avm
8
8
  module Sources
9
9
  module Tests
10
10
  class Builder
11
+ NO_TEST_TEST_NAME = 'no_test'
12
+
11
13
  require_sub __FILE__
12
14
  enable_immutable
13
15
 
@@ -33,7 +35,7 @@ module Avm
33
35
  # @return [Array<Avm::Sources::Tests::Single>]
34
36
  def available_units
35
37
  @available_units ||= ([main_source] + main_source.subs)
36
- .map { |a_source| create_unit(a_source) }
38
+ .flat_map { |a_source| create_source_units(a_source) }
37
39
  end
38
40
 
39
41
  def available_units_from_main
@@ -45,19 +47,30 @@ module Avm
45
47
  end
46
48
 
47
49
  # @return [Avm::Sources::Tests::Single]
48
- def create_unit(source)
49
- ::Avm::Sources::Tests::Single.new(self, source)
50
+ def create_source_no_test_unit(source)
51
+ ::Avm::Sources::Tests::Single.new(self, source, NO_TEST_TEST_NAME,
52
+ source.env.command('true'))
53
+ end
54
+
55
+ # @return [Array<Avm::Sources::Tests::Single>]
56
+ def create_source_units(source)
57
+ tests = source.test_commands
58
+ return create_source_no_test_unit(source) unless tests.any?
59
+
60
+ tests.map do |test_name, test_command|
61
+ ::Avm::Sources::Tests::Single.new(self, source, test_name, test_command)
62
+ end
50
63
  end
51
64
 
52
65
  # @return [Array<Avm::Sources::Tests::Single>]
53
66
  def create_units(sources)
54
- sources.map { |a_source| create_unit(a_source) }
67
+ sources.flat_map { |a_source| create_source_units(a_source) }
55
68
  end
56
69
 
57
70
  # @return [Avm::Sources::Tests::Single]
58
- def create_unit_by_id(source_id)
59
- r = available_units.find { |unit| unit.id == source_id }
60
- return r if r
71
+ def create_units_by_id(source_id)
72
+ r = available_units.select { |unit| unit.source.relative_path.to_path == source_id.to_s }
73
+ return r if r.any?
61
74
 
62
75
  raise ::ArgumentError, "Source not found with ID=#{source_id}" \
63
76
  "(Available: #{available_units.map(&:id).join(', ')})"
@@ -65,7 +78,7 @@ module Avm
65
78
 
66
79
  # @return [Array<Avm::Sources::Tests::Single>]
67
80
  def select_units_from_ids
68
- include_ids.map { |source_id| create_unit_by_id(source_id) }
81
+ include_ids.flat_map { |source_id| create_units_by_id(source_id) }
69
82
  end
70
83
 
71
84
  # @return [Array<Avm::Sources::Tests::Single>]
@@ -14,9 +14,8 @@ module Avm
14
14
  enable_simple_cache
15
15
  enable_speaker
16
16
 
17
- common_constructor :builder, :source
17
+ common_constructor :builder, :source, :test_name, :test_command
18
18
 
19
- delegate :logs, :result, to: :tester
20
19
  delegate :to_s, to: :id
21
20
 
22
21
  def failed?
@@ -25,11 +24,7 @@ module Avm
25
24
 
26
25
  # @return [String]
27
26
  def id
28
- if main?
29
- MAIN_SOURCE_ID
30
- else
31
- relative_path_from_main_source.to_s
32
- end
27
+ "#{main? ? MAIN_SOURCE_ID : relative_path_from_main_source}\##{test_name}"
33
28
  end
34
29
 
35
30
  def main?
@@ -47,8 +42,32 @@ module Avm
47
42
 
48
43
  private
49
44
 
50
- def tester_uncached
51
- source.tester
45
+ # @return [EacFs::Logs]
46
+ def logs_uncached
47
+ ::EacFs::Logs.new.add(:stdout).add(:stderr)
48
+ end
49
+
50
+ # @return [Avm::Sources::Tests::Result]
51
+ def result_uncached
52
+ if test_command.blank?
53
+ ::Avm::Sources::Tests::Result::NONEXISTENT
54
+ elsif run_test_command
55
+ ::Avm::Sources::Tests::Result::SUCESSFUL
56
+ else
57
+ ::Avm::Sources::Tests::Result::FAILED
58
+ end
59
+ end
60
+
61
+ def run_test_command
62
+ execute_command_and_log(test_command)
63
+ end
64
+
65
+ # @return [true, false]
66
+ def execute_command_and_log(command)
67
+ r = command.execute
68
+ logs[:stdout].write(r[:stdout])
69
+ logs[:stderr].write(r[:stderr])
70
+ r[:exit_code].zero?
52
71
  end
53
72
  end
54
73
  end
data/lib/avm/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Avm
4
- VERSION = '0.23.0'
4
+ VERSION = '0.26.0'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: avm
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.23.0
4
+ version: 0.26.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Eduardo H. Bogoni
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-07-07 00:00:00.000000000 Z
11
+ date: 2022-07-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: eac_cli
@@ -30,6 +30,20 @@ dependencies:
30
30
  - - ">="
31
31
  - !ruby/object:Gem::Version
32
32
  version: 0.27.6
33
+ - !ruby/object:Gem::Dependency
34
+ name: eac_config
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '0.9'
40
+ type: :runtime
41
+ prerelease: false
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - "~>"
45
+ - !ruby/object:Gem::Version
46
+ version: '0.9'
33
47
  - !ruby/object:Gem::Dependency
34
48
  name: eac_docker
35
49
  requirement: !ruby/object:Gem::Requirement
@@ -227,6 +241,7 @@ files:
227
241
  - lib/avm/registry.rb
228
242
  - lib/avm/registry/base.rb
229
243
  - lib/avm/registry/with_path.rb
244
+ - lib/avm/registry/with_path/cache.rb
230
245
  - lib/avm/result.rb
231
246
  - lib/avm/rspec.rb
232
247
  - lib/avm/rspec/setup.rb
@@ -252,7 +267,6 @@ files:
252
267
  - lib/avm/sources/base/testing.rb
253
268
  - lib/avm/sources/configuration.rb
254
269
  - lib/avm/sources/configuration/rubocop.rb
255
- - lib/avm/sources/tester.rb
256
270
  - lib/avm/sources/tests.rb
257
271
  - lib/avm/sources/tests/builder.rb
258
272
  - lib/avm/sources/tests/performer.rb
@@ -1,24 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'eac_ruby_utils/core_ext'
4
-
5
- module Avm
6
- module Sources
7
- class Tester
8
- enable_abstract_methods
9
- common_constructor :source
10
-
11
- abstract_methods :result, :logs
12
-
13
- # @return [EacFs::Logs]
14
- def logs
15
- raise_abstract_method __method__
16
- end
17
-
18
- # @return [Avm::Sources::Tests::Result]
19
- def result
20
- raise_abstract_method __method__
21
- end
22
- end
23
- end
24
- end