avm-tools 0.45.0 → 0.46.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 (60) hide show
  1. checksums.yaml +4 -4
  2. data/lib/avm/stereotypes/eac_webapp_base0/instance.rb +3 -3
  3. data/lib/avm/tools/runner/launcher.rb +12 -0
  4. data/lib/avm/tools/version.rb +1 -1
  5. data/lib/eac_launcher.rb +17 -0
  6. data/lib/eac_launcher/context.rb +81 -0
  7. data/lib/eac_launcher/context/instance_discovery.rb +54 -0
  8. data/lib/eac_launcher/context/instance_manager.rb +94 -0
  9. data/lib/eac_launcher/context/settings.rb +51 -0
  10. data/lib/eac_launcher/git.rb +7 -0
  11. data/lib/eac_launcher/git/base.rb +94 -0
  12. data/lib/eac_launcher/git/base/_remotes.rb +36 -0
  13. data/lib/eac_launcher/git/base/subrepo.rb +42 -0
  14. data/lib/eac_launcher/git/base/underlying.rb +49 -0
  15. data/lib/eac_launcher/git/error.rb +11 -0
  16. data/lib/eac_launcher/git/mirror_update.rb +36 -0
  17. data/lib/eac_launcher/git/publish_base.rb +118 -0
  18. data/lib/eac_launcher/git/remote.rb +53 -0
  19. data/lib/eac_launcher/git/sub_warp_base.rb +30 -0
  20. data/lib/eac_launcher/git/warp_base.rb +54 -0
  21. data/lib/eac_launcher/instances.rb +6 -0
  22. data/lib/eac_launcher/instances/base.rb +91 -0
  23. data/lib/eac_launcher/instances/base/cache.rb +41 -0
  24. data/lib/eac_launcher/instances/error.rb +8 -0
  25. data/lib/eac_launcher/instances/runner_helper.rb +42 -0
  26. data/lib/eac_launcher/instances/settings.rb +23 -0
  27. data/lib/eac_launcher/paths.rb +4 -0
  28. data/lib/eac_launcher/paths/logical.rb +80 -0
  29. data/lib/eac_launcher/paths/real.rb +42 -0
  30. data/lib/eac_launcher/project.rb +16 -0
  31. data/lib/eac_launcher/publish.rb +4 -0
  32. data/lib/eac_launcher/publish/base.rb +45 -0
  33. data/lib/eac_launcher/publish/check_result.rb +65 -0
  34. data/lib/eac_launcher/ruby.rb +3 -0
  35. data/lib/eac_launcher/ruby/gem.rb +4 -0
  36. data/lib/eac_launcher/ruby/gem/build.rb +123 -0
  37. data/lib/eac_launcher/ruby/gem/specification.rb +61 -0
  38. data/lib/eac_launcher/runner.rb +21 -0
  39. data/lib/eac_launcher/runner/instances.rb +41 -0
  40. data/lib/eac_launcher/runner/projects.rb +46 -0
  41. data/lib/eac_launcher/runner/publish.rb +59 -0
  42. data/lib/eac_launcher/stereotype.rb +52 -0
  43. data/lib/eac_launcher/stereotypes.rb +14 -0
  44. data/lib/eac_launcher/stereotypes/git.rb +21 -0
  45. data/lib/eac_launcher/stereotypes/git/publish.rb +13 -0
  46. data/lib/eac_launcher/stereotypes/git/warp.rb +25 -0
  47. data/lib/eac_launcher/stereotypes/git_subrepo.rb +30 -0
  48. data/lib/eac_launcher/stereotypes/git_subrepo/publish.rb +12 -0
  49. data/lib/eac_launcher/stereotypes/git_subrepo/warp.rb +85 -0
  50. data/lib/eac_launcher/stereotypes/git_subtree.rb +47 -0
  51. data/lib/eac_launcher/stereotypes/git_subtree/publish.rb +10 -0
  52. data/lib/eac_launcher/stereotypes/git_subtree/warp.rb +27 -0
  53. data/lib/eac_launcher/stereotypes/rails.rb +21 -0
  54. data/lib/eac_launcher/stereotypes/redmine_plugin.rb +21 -0
  55. data/lib/eac_launcher/stereotypes/ruby_gem.rb +27 -0
  56. data/lib/eac_launcher/stereotypes/ruby_gem/publish.rb +127 -0
  57. data/lib/eac_launcher/vendor.rb +3 -0
  58. data/lib/eac_launcher/vendor/github.rb +18 -0
  59. data/lib/eac_launcher/version.rb +5 -0
  60. metadata +101 -5
@@ -0,0 +1,91 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'base/cache'
4
+
5
+ module EacLauncher
6
+ module Instances
7
+ module Base
8
+ class << self
9
+ def extend_object(object)
10
+ object.extend ::EacRubyUtils::SimpleCache
11
+ object.extend ::EacRubyUtils::Console::Speaker
12
+ object.extend ::EacLauncher::Instances::Base::Cache
13
+ super
14
+ end
15
+
16
+ def instanciate(path, parent)
17
+ unless path.is_a?(::EacLauncher::Instances::Base)
18
+ raise "#{path} is not a project" unless path.project?
19
+
20
+ path.extend(::EacLauncher::Instances::Base)
21
+ path.parent = parent
22
+ end
23
+ path
24
+ end
25
+ end
26
+
27
+ attr_accessor :parent
28
+
29
+ def name
30
+ logical
31
+ end
32
+
33
+ def stereotype?(stereotype)
34
+ stereotypes.include?(stereotype)
35
+ end
36
+
37
+ def to_parent_path
38
+ return self unless @parent
39
+
40
+ logical.gsub(/\A#{Regexp.quote(@parent.logical)}/, '')
41
+ end
42
+
43
+ def project?
44
+ stereotypes.any?
45
+ end
46
+
47
+ def publish_run
48
+ stereotypes.each do |s|
49
+ next unless publish?(s)
50
+
51
+ infov(name, "publishing #{s.stereotype_name_in_color}")
52
+ s.publish_class.new(self).run
53
+ end
54
+ end
55
+
56
+ def publish_check
57
+ stereotypes.each do |s|
58
+ next unless publish?(s)
59
+
60
+ puts "#{name.to_s.cyan}|#{s.stereotype_name_in_color}|" \
61
+ "#{s.publish_class.new(self).check}"
62
+ end
63
+ end
64
+
65
+ def project_name
66
+ ::File.basename(logical)
67
+ end
68
+
69
+ def included?
70
+ !::EacLauncher::Context.current.settings.excluded_projects.include?(project_name)
71
+ end
72
+
73
+ def to_h
74
+ super.to_h.merge(parent: parent ? parent.logical : nil)
75
+ end
76
+
77
+ private
78
+
79
+ def publish?(stereotype)
80
+ return false unless stereotype.publish_class
81
+
82
+ filter = ::EacLauncher::Context.current.publish_options[:stereotype]
83
+ filter.blank? ? true : filter == stereotype.name.demodulize
84
+ end
85
+
86
+ def options_uncached
87
+ ::EacLauncher::Context.current.settings.instance_settings(self)
88
+ end
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EacLauncher
4
+ module Instances
5
+ module Base
6
+ module Cache
7
+ def cache_path(subpath)
8
+ File.join(cache_root, subpath)
9
+ end
10
+
11
+ def cache_key(key, &block)
12
+ v = cache_key_get(key)
13
+ return v if v.present? || block.nil?
14
+
15
+ v = yield
16
+ cache_key_write(key, v)
17
+ v
18
+ end
19
+
20
+ private
21
+
22
+ def cache_key_get(key)
23
+ File.file?(cache_key_path(key)) ? File.read(cache_key_path(key)) : nil
24
+ end
25
+
26
+ def cache_key_write(key, value)
27
+ FileUtils.mkdir_p(File.dirname(cache_key_path(key)))
28
+ File.write(cache_key_path(key), value)
29
+ end
30
+
31
+ def cache_key_path(key)
32
+ File.join(cache_root, 'keys', key.parameterize)
33
+ end
34
+
35
+ def cache_root
36
+ File.join(::EacLauncher::Context.current.cache_root, name.parameterize)
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EacLauncher
4
+ module Instances
5
+ class Error < StandardError
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'eac_ruby_utils/console/docopt_runner'
4
+ require 'eac_ruby_utils/console/speaker'
5
+
6
+ module EacLauncher
7
+ module Instances
8
+ class RunnerHelper < ::EacRubyUtils::Console::DocoptRunner
9
+ include ::EacRubyUtils::Console::Speaker
10
+
11
+ def context
12
+ @context ||= ::EacLauncher::Context.current
13
+ end
14
+
15
+ def find_instances(instance_name)
16
+ context.instances.select { |instance| instance_match?(instance, instance_name) }
17
+ end
18
+
19
+ def instance_match?(instance, instance_name)
20
+ ::File.fnmatch?(instance_name, instance.name)
21
+ end
22
+
23
+ def instances
24
+ if options['--all']
25
+ context.instances
26
+ elsif options['--pending']
27
+ context.pending_instances
28
+ else
29
+ options['<instance_path>'].flat_map { |p| find_instances(p) }
30
+ end
31
+ end
32
+
33
+ def instance_stereotypes(instance)
34
+ instance.stereotypes.map(&:stereotype_name_in_color).join(', ')
35
+ end
36
+
37
+ def instance_label(instance)
38
+ "#{instance.name} [#{instance_stereotypes(instance)}]"
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EacLauncher
4
+ module Instances
5
+ class Settings
6
+ def initialize(data)
7
+ @data = ActiveSupport::HashWithIndifferentAccess.new(data.is_a?(Hash) ? data : {})
8
+ end
9
+
10
+ def git_current_revision
11
+ @data[__method__] || 'origin/master'
12
+ end
13
+
14
+ def git_publish_remote
15
+ @data[__method__] || 'publish'
16
+ end
17
+
18
+ def publishable?
19
+ @data.key?(:publishable) ? @data[:publishable] : true
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'eac_launcher/paths/logical'
4
+ require 'eac_launcher/paths/real'
@@ -0,0 +1,80 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'eac_launcher/paths/real'
4
+ require 'eac_launcher/stereotypes'
5
+
6
+ module EacLauncher
7
+ module Paths
8
+ class Logical
9
+ include ::EacRubyUtils::SimpleCache
10
+
11
+ class << self
12
+ def from_h(context, hash)
13
+ parent_path = hash[:parent_path] ? from_h(context, hash[:parent_path]) : nil
14
+ new(context, parent_path, hash[:real], hash[:logical])
15
+ end
16
+ end
17
+
18
+ attr_reader :context, :real, :logical, :parent_path
19
+
20
+ def initialize(context, parent_path, real, logical)
21
+ @context = context
22
+ @parent_path = parent_path
23
+ @real = ::EacLauncher::Paths::Real.new(real)
24
+ @logical = logical
25
+ end
26
+
27
+ def to_s
28
+ logical
29
+ end
30
+
31
+ def to_h
32
+ { logical: logical, real: real.to_s, parent_path: parent_path ? parent_path.to_h : nil }
33
+ end
34
+
35
+ def project?
36
+ stereotypes.any?
37
+ end
38
+
39
+ def children
40
+ r = []
41
+ Dir.entries(warped).each do |c|
42
+ c_path = ::File.join(warped, c)
43
+ next unless ::File.directory?(c_path)
44
+ next if c.start_with?('.')
45
+
46
+ r << build_child(c)
47
+ end
48
+ r
49
+ end
50
+
51
+ def included?
52
+ !context.settings.excluded_paths.include?(logical)
53
+ end
54
+
55
+ private
56
+
57
+ def stereotypes_uncached
58
+ ::EacLauncher::Stereotype.stereotypes.select { |s| s.match?(self) }
59
+ end
60
+
61
+ def build_child(name)
62
+ ::EacLauncher::Paths::Logical.new(
63
+ context,
64
+ self,
65
+ ::File.join(warped, name),
66
+ ::File.join(logical, name)
67
+ )
68
+ end
69
+
70
+ def warped_uncached
71
+ if is_a?(::EacLauncher::Instances::Base)
72
+ stereotypes.each do |s|
73
+ return s.warp_class.new(self) if s.warp_class
74
+ end
75
+ end
76
+ real
77
+ end
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EacLauncher
4
+ module Paths
5
+ class Real < String
6
+ def initialize(path)
7
+ raise "Argument path is not a string: \"#{path}\"|#{path.class}" unless path.is_a?(String)
8
+
9
+ super(path)
10
+ end
11
+
12
+ def subpath(relative_path)
13
+ ::EacLauncher::Paths::Real.new(::File.expand_path(relative_path, self))
14
+ end
15
+
16
+ def basename
17
+ ::File.basename(self)
18
+ end
19
+
20
+ def dirname
21
+ return nil if self == '/'
22
+
23
+ self.class.new(::File.dirname(self))
24
+ end
25
+
26
+ def find_file_with_extension(extension)
27
+ r = find_files_with_extension(extension)
28
+ return r.first if r.any?
29
+
30
+ raise "Extension \"#{extension}\" not found in directory \"#{self}\""
31
+ end
32
+
33
+ def find_files_with_extension(extension)
34
+ r = []
35
+ ::Dir.entries(self).each do |i|
36
+ r << ::File.expand_path(i, self) if i =~ /#{::Regexp.quote(extension)}\z/
37
+ end
38
+ r
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EacLauncher
4
+ class Project
5
+ attr_reader :name, :instances
6
+
7
+ def initialize(name, instances)
8
+ @name = name
9
+ @instances = instances.to_a
10
+ end
11
+
12
+ def to_s
13
+ name
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'eac_launcher/publish/base'
4
+ require 'eac_launcher/publish/check_result'
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'eac_launcher/instances/error'
4
+
5
+ module EacLauncher
6
+ module Publish
7
+ class Base
8
+ attr_reader :instance
9
+
10
+ def initialize(instance)
11
+ @instance = instance
12
+ end
13
+
14
+ def run
15
+ s = check
16
+ info("Check: #{s}")
17
+ return unless s.status == ::EacLauncher::Publish::CheckResult::STATUS_PENDING
18
+
19
+ publish
20
+ end
21
+
22
+ def check
23
+ s = check_with_rescue
24
+ ::EacLauncher::Context.current.instance_manager.publish_state_set(
25
+ instance, stereotype.stereotype_name, s.status
26
+ )
27
+ s
28
+ end
29
+
30
+ private
31
+
32
+ def stereotype
33
+ self.class.name.deconstantize.constantize
34
+ end
35
+
36
+ def check_with_rescue
37
+ internal_check
38
+ rescue ::EacLauncher::Instances::Error => e
39
+ ::EacLauncher::Publish::CheckResult.blocked("Error: #{e}")
40
+ rescue ::EacLauncher::Git::Error => e
41
+ ::EacLauncher::Publish::CheckResult.blocked("Git error: #{e}")
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,65 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_support/concern' # Missing on "eac/listable"
4
+ require 'active_support/hash_with_indifferent_access'
5
+ require 'eac_ruby_utils/listable'
6
+
7
+ module EacLauncher
8
+ module Publish
9
+ class CheckResult
10
+ include ::EacRubyUtils::Listable
11
+
12
+ lists.add_string :status, :updated, :pending, :blocked, :outdated
13
+
14
+ lists.status.values.each do |status| # rubocop:disable Style/HashEachMethods
15
+ class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1
16
+ def self.#{status}(message)
17
+ new('#{status}', message)
18
+ end
19
+ RUBY_EVAL
20
+ end
21
+
22
+ class << self
23
+ def pending_status?(status)
24
+ [STATUS_PENDING].include?(status)
25
+ end
26
+
27
+ def updated_color
28
+ 'green'
29
+ end
30
+
31
+ def pending_color
32
+ 'yellow'
33
+ end
34
+
35
+ def blocked_color
36
+ 'red'
37
+ end
38
+
39
+ def outdated_color
40
+ 'light_blue'
41
+ end
42
+ end
43
+
44
+ attr_reader :status, :message
45
+
46
+ def initialize(status, message)
47
+ raise "Status \"#{status}\" not in #{self.class.lists.status.values}" unless
48
+ self.class.lists.status.values.include?(status)
49
+
50
+ @status = status
51
+ @message = message
52
+ end
53
+
54
+ def to_s
55
+ message.light_white.send("on_#{background_color}")
56
+ end
57
+
58
+ private
59
+
60
+ def background_color
61
+ self.class.send("#{status}_color")
62
+ end
63
+ end
64
+ end
65
+ end