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,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'eac_ruby_utils/core_ext'
4
+ require 'eac_launcher/git/remote'
5
+
6
+ module EacLauncher
7
+ module Git
8
+ class Base < ::EacLauncher::Paths::Real
9
+ # @return [EacLauncher::Git::Remote]
10
+ def remote(name)
11
+ ::EacLauncher::Git::Remote.new(self, name)
12
+ end
13
+
14
+ def remote_hashs(remote_name)
15
+ remote(remote_name).ls
16
+ end
17
+
18
+ def remote_exist?(remote_name)
19
+ remote(remote_name).exist?
20
+ end
21
+
22
+ def assert_remote_url(remote_name, url)
23
+ r = git.remote(remote_name)
24
+ if !r.url || r.url != url
25
+ r.remove if r.url
26
+ git.add_remote(remote_name, url)
27
+ end
28
+ r
29
+ end
30
+
31
+ def remote_branch_sha(remote_name, branch_name)
32
+ remote_hashs(remote_name)["refs/heads/#{branch_name}"]
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_support/core_ext/object'
4
+
5
+ module EacLauncher
6
+ module Git
7
+ class Base < ::EacLauncher::Paths::Real
8
+ module Subrepo
9
+ def subrepo_status(subrepo_path)
10
+ s = execute!('subrepo', 'status', subrepo_path.gsub(%r{\A/}, ''))
11
+ raise s.strip.to_s if s.include?('is not a subrepo')
12
+
13
+ r = subrepo_status_parse_output(s)
14
+ raise "Empty subrepo status for |#{s}|\n" unless r.any?
15
+
16
+ r
17
+ end
18
+
19
+ def subrepo_remote_url(subrepo_path)
20
+ h = subrepo_status(subrepo_path)
21
+ url = h['Remote URL']
22
+ return url if url.present?
23
+
24
+ raise "Remote URL is blank for subrepo \"#{subrepo_path}\" (Subrepo status: #{h})"
25
+ end
26
+
27
+ private
28
+
29
+ def subrepo_status_parse_output(output)
30
+ r = {}.with_indifferent_access
31
+ output.each_line do |l|
32
+ m = /\A([^\:]+)\:(.*)\z/.match(l.strip)
33
+ next unless m && m[2].present?
34
+
35
+ r[m[1].strip] = m[2].strip
36
+ end
37
+ r
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'eac_ruby_utils/envs'
4
+ require 'git'
5
+ require 'eac_launcher/paths/real'
6
+
7
+ module EacLauncher
8
+ module Git
9
+ class Base < ::EacLauncher::Paths::Real
10
+ module Underlying
11
+ def execute!(*args)
12
+ args, options = build_args(args)
13
+ ::EacRubyUtils::Envs.local.command(*args).execute!(options)
14
+ end
15
+
16
+ def system!(*args)
17
+ args, options = build_args(args)
18
+ ::EacRubyUtils::Envs.local.command(*args).system!(options)
19
+ end
20
+
21
+ def init
22
+ git
23
+ self
24
+ end
25
+
26
+ private
27
+
28
+ def build_args(args)
29
+ options = {}
30
+ if args.last.is_a?(Hash)
31
+ options = args.last
32
+ args.pop
33
+ end
34
+ args = args.first if args.first.is_a?(Array)
35
+ [['git', '-C', self, '--no-pager'] + args, options]
36
+ end
37
+
38
+ def git_uncached
39
+ FileUtils.mkdir_p(self)
40
+ if File.exist?(subpath('.git'))
41
+ ::Git.open(self)
42
+ else
43
+ ::Git.init(self)
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EacLauncher
4
+ module Git
5
+ class Error < StandardError
6
+ def initialize(git_instance, message)
7
+ super("#{message} (Repository: #{git_instance})")
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'eac_launcher/git/base'
4
+
5
+ module EacLauncher
6
+ module Git
7
+ class MirrorUpdate < ::EacLauncher::Paths::Real
8
+ include ::EacRubyUtils::SimpleCache
9
+
10
+ def initialize(target_path, source_path, source_rev)
11
+ super(target_path)
12
+ @target_git = ::EacLauncher::Git::Base.new(self)
13
+ @source_git = ::EacLauncher::Git::Base.new(source_path)
14
+ @source_rev = source_rev
15
+ run
16
+ end
17
+
18
+ private
19
+
20
+ def run
21
+ fetch_remote_source
22
+ reset_source_rev
23
+ end
24
+
25
+ def fetch_remote_source
26
+ @target_git.git
27
+ @target_git.assert_remote_url('origin', @source_git)
28
+ @target_git.fetch('origin', tags: true)
29
+ end
30
+
31
+ def reset_source_rev
32
+ @target_git.reset_hard(@source_git.rev_parse(@source_rev, true))
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,118 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'eac_ruby_utils/simple_cache'
4
+ require 'eac_ruby_utils/simple_cache'
5
+ require 'eac_launcher/publish/base'
6
+
7
+ module EacLauncher
8
+ module Git
9
+ class PublishBase < ::EacLauncher::Publish::Base
10
+ include ::EacRubyUtils::SimpleCache
11
+ include ::EacRubyUtils::Console::Speaker
12
+
13
+ CHECKERS = %w[remote_url remote_fetch publish_remote_no_exist remote_equal remote_following
14
+ local_following].freeze
15
+
16
+ REMOTE_UNAVAILABLE_MESSAGES = ['could not resolve host', 'connection timed out',
17
+ 'no route to host'].map(&:downcase).freeze
18
+
19
+ protected
20
+
21
+ def internal_check
22
+ CHECKERS.each do |checker|
23
+ result = send("#{checker}_check_result")
24
+ return result if result
25
+ end
26
+ divergent_result_check_result
27
+ rescue ::StandardError => e
28
+ raise e unless remote_unavailable_error?(e)
29
+
30
+ ::EacLauncher::Publish::CheckResult.blocked(e.message)
31
+ end
32
+
33
+ private
34
+
35
+ def remote_url_check_result
36
+ remote = sgit.remote(remote_name)
37
+ return if remote.exist? && remote.url.present?
38
+
39
+ ::EacLauncher::Publish::CheckResult.blocked("Remote \"#{remote_name}\" has blank path")
40
+ end
41
+
42
+ def remote_fetch_check_result
43
+ remote_fetch
44
+ nil
45
+ end
46
+
47
+ def remote_unavailable_error?(error)
48
+ error_message = error.message.downcase
49
+ REMOTE_UNAVAILABLE_MESSAGES.any? do |message|
50
+ error_message.include?(message)
51
+ end
52
+ end
53
+
54
+ def publish_remote_no_exist_check_result
55
+ return nil if sgit.remote_exist?(remote_name)
56
+
57
+ ::EacLauncher::Publish::CheckResult.blocked('Remote does not exist')
58
+ end
59
+
60
+ def remote_equal_check_result
61
+ return nil unless remote_sha.present? && remote_sha == local_sha
62
+
63
+ ::EacLauncher::Publish::CheckResult.updated('Remote equal')
64
+ end
65
+
66
+ def remote_following_check_result
67
+ return nil unless remote_sha.present? && sgit.descendant?(remote_sha, local_sha)
68
+
69
+ ::EacLauncher::Publish::CheckResult.outdated('Remote following')
70
+ end
71
+
72
+ def divergent_result_check_result
73
+ ::EacLauncher::Publish::CheckResult.blocked(
74
+ "Divergent (L: #{local_sha}, R: #{remote_sha})"
75
+ )
76
+ end
77
+
78
+ def local_following?
79
+ return true if remote_sha.blank?
80
+
81
+ sgit.descendant?(local_sha, remote_sha)
82
+ end
83
+
84
+ def local_following_check_result
85
+ ::EacLauncher::Publish::CheckResult.pending('Local following')
86
+ end
87
+
88
+ def sgit_uncached
89
+ ::EacLauncher::Git::Base.new(instance.warped)
90
+ end
91
+
92
+ def publish
93
+ info 'Pushing...'
94
+ sgit.push(remote_name, 'HEAD:master',
95
+ dryrun: !::EacLauncher::Context.current.publish_options[:confirm])
96
+ info 'Pushed!'
97
+ end
98
+
99
+ def local_sha
100
+ sgit.git.object('HEAD').sha
101
+ end
102
+
103
+ def remote_sha_uncached
104
+ remote_fetch
105
+ b = sgit.git.branches["#{remote_name}/master"]
106
+ b ? b.gcommit.sha : nil
107
+ end
108
+
109
+ def remote_fetch_uncached
110
+ sgit.fetch(remote_name)
111
+ end
112
+
113
+ def remote_name
114
+ ::EacLauncher::Git::WarpBase::TARGET_REMOTE
115
+ end
116
+ end
117
+ end
118
+ end
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'eac_ruby_utils/core_ext'
4
+
5
+ module EacLauncher
6
+ module Git
7
+ class Remote
8
+ common_constructor :git, :name
9
+
10
+ def exist?
11
+ git.execute!('remote').each_line.any? { |line| line.strip == name }
12
+ end
13
+
14
+ def ls
15
+ git.execute!(['ls-remote', name]).each_line.map do |line|
16
+ x = line.strip.split(/\s+/)
17
+ [x[1], x[0]]
18
+ end.to_h
19
+ end
20
+
21
+ # +git remote add ...+
22
+ def add(url)
23
+ git.execute!('remote', 'add', name, url)
24
+ end
25
+
26
+ # +git remote rm ...+
27
+ def remove
28
+ git.execute!('remote', 'rm', name)
29
+ end
30
+
31
+ # +git remote get-url ...+
32
+ def url
33
+ git.execute!('remote', 'get-url', name).strip.if_present(nil)
34
+ end
35
+
36
+ # git remote set-url ...
37
+ def url_set(url)
38
+ git.execute!('remote', 'set-url', name, url)
39
+ end
40
+
41
+ # Add or set URL if +url+ is present, remove remote if is blank.
42
+ def url=(url)
43
+ if exist? && url.blank?
44
+ remove
45
+ elsif exist? && self.url != url
46
+ url_set(url)
47
+ elsif !exist?
48
+ add(url)
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'eac_launcher/instances/error'
4
+
5
+ module EacLauncher
6
+ module Git
7
+ module SubWarpBase
8
+ private
9
+
10
+ def parent_instance_uncached
11
+ r = find_parent_instance(instance.parent)
12
+ return r if r
13
+
14
+ ::EacLauncher::Instances::Error.new('Git parent not found')
15
+ end
16
+
17
+ def find_parent_instance(current)
18
+ if ::EacLauncher::Stereotype.git_stereotypes.any? { |s| current.stereotype?(s) }
19
+ return current
20
+ end
21
+
22
+ current.parent ? find_parent_instance(current.parent) : nil
23
+ end
24
+
25
+ def to_parent_git_path
26
+ instance.logical.gsub(%r{\A#{Regexp.quote(parent_instance.logical)}/}, '')
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'eac_launcher/git/mirror_update'
4
+ require 'eac_launcher/vendor/github'
5
+ require 'eac_launcher/stereotypes/git/publish'
6
+
7
+ module EacLauncher
8
+ module Git
9
+ # Métodos abstratos:
10
+ # * source_instance
11
+ # * source_remote_name
12
+ # * current_ref
13
+ class WarpBase < ::EacLauncher::Paths::Real
14
+ include ::EacRubyUtils::SimpleCache
15
+
16
+ TARGET_REMOTE = ::EacLauncher::Stereotypes::Git::Publish::PUBLISH_GIT_REMOTE_NAME
17
+
18
+ def initialize(instance)
19
+ @instance = instance
20
+ cache_git.git.reset_hard(current_ref)
21
+ cache_git.remote(TARGET_REMOTE).url = target_remote_url
22
+ super(path)
23
+ end
24
+
25
+ protected
26
+
27
+ attr_reader :instance
28
+
29
+ def update
30
+ ::EacLauncher::Git::MirrorUpdate.new(
31
+ path,
32
+ source_instance.real,
33
+ source_instance.options.git_current_revision
34
+ )
35
+ end
36
+
37
+ def path
38
+ instance.cache_path('git_repository')
39
+ end
40
+
41
+ def source_git_uncached
42
+ ::EacLauncher::Git::Base.new(source_instance.real)
43
+ end
44
+
45
+ def cache_git_uncached
46
+ ::EacLauncher::Git::Base.new(update)
47
+ end
48
+
49
+ def target_remote_url
50
+ ::EacLauncher::Vendor::Github.to_ssh_url(source_git.git.remote(source_remote_name).url)
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'eac_launcher/instances/base'
4
+ require 'eac_launcher/instances/error'
5
+ require 'eac_launcher/instances/runner_helper'
6
+ require 'eac_launcher/instances/settings'