eac_launcher 0.1.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 (40) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +14 -0
  3. data/README.rdoc +3 -0
  4. data/exe/eac_launcher_instance +33 -0
  5. data/exe/eac_launcher_projects +43 -0
  6. data/exe/eac_launcher_publish +49 -0
  7. data/lib/eac_launcher.rb +44 -0
  8. data/lib/eac_launcher/context.rb +63 -0
  9. data/lib/eac_launcher/context/settings.rb +36 -0
  10. data/lib/eac_launcher/git/base.rb +105 -0
  11. data/lib/eac_launcher/git/base/subrepo.rb +18 -0
  12. data/lib/eac_launcher/git/base/underlying.rb +38 -0
  13. data/lib/eac_launcher/git/mirror_update.rb +32 -0
  14. data/lib/eac_launcher/git/publish_base.rb +69 -0
  15. data/lib/eac_launcher/git/transpose_base.rb +48 -0
  16. data/lib/eac_launcher/instances/base.rb +110 -0
  17. data/lib/eac_launcher/instances/base/cache.rb +38 -0
  18. data/lib/eac_launcher/instances/runner_helper.rb +37 -0
  19. data/lib/eac_launcher/instances/settings.rb +17 -0
  20. data/lib/eac_launcher/path.rb +25 -0
  21. data/lib/eac_launcher/project.rb +14 -0
  22. data/lib/eac_launcher/publish/base.rb +12 -0
  23. data/lib/eac_launcher/publish/check_result.rb +42 -0
  24. data/lib/eac_launcher/stereotype.rb +44 -0
  25. data/lib/eac_launcher/stereotypes/git.rb +17 -0
  26. data/lib/eac_launcher/stereotypes/git/publish.rb +9 -0
  27. data/lib/eac_launcher/stereotypes/git/transpose.rb +21 -0
  28. data/lib/eac_launcher/stereotypes/git_subrepo.rb +25 -0
  29. data/lib/eac_launcher/stereotypes/git_subrepo/publish.rb +8 -0
  30. data/lib/eac_launcher/stereotypes/git_subrepo/transpose.rb +87 -0
  31. data/lib/eac_launcher/stereotypes/git_subtree.rb +31 -0
  32. data/lib/eac_launcher/stereotypes/git_subtree/publish.rb +8 -0
  33. data/lib/eac_launcher/stereotypes/git_subtree/transpose.rb +27 -0
  34. data/lib/eac_launcher/stereotypes/rails.rb +17 -0
  35. data/lib/eac_launcher/stereotypes/redmine_plugin.rb +17 -0
  36. data/lib/eac_launcher/stereotypes/ruby_gem.rb +21 -0
  37. data/lib/eac_launcher/stereotypes/ruby_gem/publish.rb +109 -0
  38. data/lib/eac_launcher/vendor/github.rb +13 -0
  39. data/lib/eac_launcher/version.rb +5 -0
  40. metadata +194 -0
@@ -0,0 +1,44 @@
1
+ module EacLauncher
2
+ module Stereotype
3
+ class << self
4
+ attr_reader :stereotypes
5
+
6
+ def included(base)
7
+ @stereotypes ||= []
8
+ @stereotypes << base
9
+ base.extend(ClassMethods)
10
+ end
11
+
12
+ def nogit_stereotypes
13
+ stereotypes.reject { |c| c.name.demodulize.downcase.match('git') }
14
+ end
15
+ end
16
+
17
+ module ClassMethods
18
+ def stereotype_name
19
+ name.gsub(/^.*::/, '')
20
+ end
21
+
22
+ def stereotype_name_in_color
23
+ stereotype_name.send(color)
24
+ end
25
+
26
+ def publish_class
27
+ sub_class('Publish')
28
+ end
29
+
30
+ def transpose_class
31
+ sub_class('Transpose')
32
+ end
33
+
34
+ private
35
+
36
+ def sub_class(sub_class_name)
37
+ klass = const_get(sub_class_name)
38
+ klass.is_a?(Class) ? klass : nil
39
+ rescue NameError
40
+ nil
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,17 @@
1
+ module EacLauncher
2
+ module Stereotypes
3
+ class Git
4
+ include EacLauncher::Stereotype
5
+
6
+ class << self
7
+ def match?(path)
8
+ File.directory?(path.subpath('.git'))
9
+ end
10
+
11
+ def color
12
+ :white
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,9 @@
1
+ module EacLauncher
2
+ module Stereotypes
3
+ class Git
4
+ class Publish < ::EacLauncher::Git::PublishBase
5
+ PUBLISH_GIT_REMOTE_NAME = 'publish'.freeze
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,21 @@
1
+ module EacLauncher
2
+ module Stereotypes
3
+ class Git
4
+ class Transpose < ::EacLauncher::Git::TransposeBase
5
+ private
6
+
7
+ def current_ref
8
+ 'HEAD'
9
+ end
10
+
11
+ def source_instance
12
+ instance
13
+ end
14
+
15
+ def source_remote_name
16
+ ::EacLauncher::Stereotypes::Git::Publish::PUBLISH_GIT_REMOTE_NAME
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,25 @@
1
+ module EacLauncher
2
+ module Stereotypes
3
+ class GitSubrepo
4
+ include EacLauncher::Stereotype
5
+
6
+ class << self
7
+ def match?(path)
8
+ File.exist?(path.subpath('.gitrepo')) && subrepo_url(path) != 'none'
9
+ end
10
+
11
+ def color
12
+ :light_cyan
13
+ end
14
+
15
+ def subrepo_url(path)
16
+ File.read(path.subpath('.gitrepo')).each_line do |l|
17
+ m = /remote\s*=\s(.+)/.match(l)
18
+ return m[1] if m
19
+ end
20
+ raise "\"remote = ... \" not found (Path: #{path})"
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,8 @@
1
+ module EacLauncher
2
+ module Stereotypes
3
+ class GitSubrepo
4
+ class Publish < ::EacLauncher::Git::PublishBase
5
+ end
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,87 @@
1
+ module EacLauncher
2
+ module Stereotypes
3
+ class GitSubrepo
4
+ class Transpose < ::EacLauncher::Path
5
+ include ::Eac::SimpleCache
6
+
7
+ attr_reader :instance
8
+
9
+ def initialize(instance)
10
+ @instance = instance
11
+ check_parent
12
+ init_aux
13
+ fetch
14
+ push
15
+ reset
16
+ assert_target_remote
17
+ super(cache_git)
18
+ end
19
+
20
+ private
21
+
22
+ def check_parent
23
+ return if parent_cache_git.descendant?('HEAD', subrepo_parent_hash)
24
+ raise "Subrepo parent hash \"#{subrepo_parent_hash}\" not found in " \
25
+ "\"#{parent_cache_git}\""
26
+ end
27
+
28
+ def subrepo_parent_hash
29
+ h = parent_cache_git.subrepo_status(instance.to_parent_path)['Pull Parent']
30
+ return h if h.present?
31
+ raise 'Subrepo parent hash is blank'
32
+ end
33
+
34
+ def init_aux
35
+ ::EacLauncher::Git::Base.new(aux_path).init_bare
36
+ end
37
+
38
+ def parent_instance
39
+ instance.parent
40
+ end
41
+
42
+ def parent_git_uncached
43
+ ::EacLauncher::Git::Base.new(instance.parent)
44
+ end
45
+
46
+ def parent_cache_git_uncached
47
+ ::EacLauncher::Git::Base.new(parent_instance.current_cache)
48
+ end
49
+
50
+ def aux_path
51
+ instance.cache_path('subrepo_aux_git_repository')
52
+ end
53
+
54
+ def cache_git_uncached
55
+ ::EacLauncher::Git::Base.new(instance.cache_path('git_repository'))
56
+ end
57
+
58
+ def fetch
59
+ parent_cache_git.execute!('subrepo', 'fetch', subrepo_subdir)
60
+ end
61
+
62
+ def push
63
+ parent_cache_git.execute!('subrepo', 'push', subrepo_subdir, '-r', aux_path, '-f')
64
+ end
65
+
66
+ def subrepo_subdir
67
+ instance.to_parent_path.gsub(%r{\A/+}, '')
68
+ end
69
+
70
+ def reset
71
+ ::EacLauncher::Git::MirrorUpdate.new(cache_git, aux_path, 'master')
72
+ end
73
+
74
+ def assert_target_remote
75
+ cache_git.assert_remote_url(::EacLauncher::Git::TransposeBase::TARGET_REMOTE,
76
+ target_remote_url)
77
+ end
78
+
79
+ def target_remote_url
80
+ ::EacLauncher::Vendor::Github.to_ssh_url(
81
+ parent_git.git.remote("subrepo/#{subrepo_subdir}").url
82
+ )
83
+ end
84
+ end
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,31 @@
1
+ module EacLauncher
2
+ module Stereotypes
3
+ class GitSubtree
4
+ include EacLauncher::Stereotype
5
+
6
+ class << self
7
+ def match?(path)
8
+ return false if ::EacLauncher::Stereotypes::Git.match?(path) ||
9
+ ::EacLauncher::Stereotypes::GitSubrepo.match?(path)
10
+ return false unless other_nogit_stereotype?(path)
11
+ parent = parent_git(path.parent)
12
+ return false unless parent
13
+ ::Git.open(parent).remote(File.basename(path)).url ? true : false
14
+ end
15
+
16
+ def color
17
+ :green
18
+ end
19
+
20
+ def parent_git(p)
21
+ return nil unless p
22
+ ::EacLauncher::Stereotypes::Git.match?(p) ? p : parent_git(p.parent)
23
+ end
24
+
25
+ def other_nogit_stereotype?(path)
26
+ EacLauncher::Stereotype.nogit_stereotypes.any? { |s| s.match?(path) }
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,8 @@
1
+ module EacLauncher
2
+ module Stereotypes
3
+ class GitSubtree
4
+ class Publish < ::EacLauncher::Git::PublishBase
5
+ end
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,27 @@
1
+ module EacLauncher
2
+ module Stereotypes
3
+ class GitSubtree
4
+ class Transpose < ::EacLauncher::Git::TransposeBase
5
+ private
6
+
7
+ def current_ref
8
+ instance.cache_key("git_subtree.parent.#{cache_git.git.object('HEAD').sha}") do
9
+ cache_git.subtree_split(to_parent_path)
10
+ end
11
+ end
12
+
13
+ def source_instance
14
+ instance.parent
15
+ end
16
+
17
+ def source_remote_name
18
+ instance.project_name
19
+ end
20
+
21
+ def to_parent_path
22
+ instance.to_parent_path.gsub(%r{\A/+}, '')
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,17 @@
1
+ module EacLauncher
2
+ module Stereotypes
3
+ class Rails
4
+ include EacLauncher::Stereotype
5
+
6
+ class << self
7
+ def match?(path)
8
+ File.exist?(path.subpath('config.ru')) && File.basename(path) != 'dummy'
9
+ end
10
+
11
+ def color
12
+ :magenta
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ module EacLauncher
2
+ module Stereotypes
3
+ class RedminePlugin
4
+ include EacLauncher::Stereotype
5
+
6
+ class << self
7
+ def match?(path)
8
+ File.exist?(path.subpath('init.rb'))
9
+ end
10
+
11
+ def color
12
+ :light_magenta
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,21 @@
1
+ module EacLauncher
2
+ module Stereotypes
3
+ class RubyGem
4
+ include EacLauncher::Stereotype
5
+
6
+ class << self
7
+ def match?(path)
8
+ Dir.glob(File.join(path, '*.gemspec')).any?
9
+ end
10
+
11
+ def color
12
+ :red
13
+ end
14
+
15
+ def load_gemspec(file)
16
+ ::Gem::Specification.load(file)
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,109 @@
1
+ module EacLauncher
2
+ module Stereotypes
3
+ class RubyGem
4
+ class Publish < ::EacLauncher::Publish::Base
5
+ include ::Eac::SimpleCache
6
+ include ::EacRubyUtils::Console::Speaker
7
+
8
+ def initialize(instance)
9
+ @source = instance.current_cache
10
+ end
11
+
12
+ def check
13
+ if new_and_unpublishing_new?
14
+ ::EacLauncher::Publish::CheckResult.blocked(
15
+ "#{gem_spec.full_name} does not exist in RubyGems"
16
+ )
17
+ elsif version_already_pushed?
18
+ ::EacLauncher::Publish::CheckResult.updated("#{gem_spec.full_name} already pushed")
19
+ else
20
+ ::EacLauncher::Publish::CheckResult.pending("#{gem_spec.full_name} not found " \
21
+ 'in RubyGems')
22
+ end
23
+ end
24
+
25
+ private
26
+
27
+ def gem_spec_uncached
28
+ ::EacLauncher::Stereotypes::RubyGem.load_gemspec(gemspec)
29
+ end
30
+
31
+ def publish
32
+ Dir.mktmpdir do |dir|
33
+ @tempdir = ::EacLauncher::Path.new(dir)
34
+ build_gem
35
+ check_gem
36
+ push_gem
37
+ end
38
+ end
39
+
40
+ def new_and_unpublishing_new?
41
+ !gem_exist_in_rubygems? && !::EacLauncher::Context.current.publish_options[:new]
42
+ end
43
+
44
+ def gem_exist_in_rubygems?
45
+ gem_versions.any?
46
+ end
47
+
48
+ def version_already_pushed?
49
+ gem_versions.any? { |v| v['number'] == gem_spec.version.version }
50
+ end
51
+
52
+ def gem_versions_uncached
53
+ http = Curl.get("https://rubygems.org/api/v1/versions/#{gem_spec.name}.json")
54
+ return JSON.parse!(http.body_str) if /\A2/ =~ http.status
55
+ return [] if /\A4/ =~ http.status
56
+ raise "#{http} code error: #{http.status}"
57
+ end
58
+
59
+ def build_gem
60
+ info("Building gem #{gem_spec}...")
61
+ clear_gems
62
+ Dir.chdir @source do
63
+ EacRubyUtils::Envs.local.command('gem', 'build', gemspec).system
64
+ end
65
+ source = @source.find_file_with_extension('.gem')
66
+ FileUtils.mv(source, File.join(@tempdir, File.basename(source)))
67
+ ensure
68
+ clear_gems
69
+ end
70
+
71
+ def clear_gems
72
+ @source.find_files_with_extension('.gem').each do |f|
73
+ FileUtils.rm_rf(f)
74
+ end
75
+ end
76
+
77
+ def check_gem
78
+ Dir.mktmpdir do |dir|
79
+ Dir.chdir dir do
80
+ EacRubyUtils::Envs.local.command('gem', 'unpack', gem).system
81
+ gs = File.join(dir, File.basename(gem, '.gem'))
82
+ if (Dir.entries(gs) - %w[. ..]).empty?
83
+ raise "\"#{dir}\" (Unpacked from #{gem}) has no source code"
84
+ end
85
+ end
86
+ end
87
+ end
88
+
89
+ def push_gem
90
+ info("Pushing gem #{gem_spec}...")
91
+ if ::EacLauncher::Context.current.publish_options[:confirm]
92
+ EacRubyUtils::Envs.local.command('gem', 'push', gem).system
93
+ info('Pushed!')
94
+ else
95
+ warn('Not pushed because not confirmed')
96
+ end
97
+ end
98
+
99
+ def gemspec_uncached
100
+ @source.find_file_with_extension('.gemspec')
101
+ end
102
+
103
+ def gem
104
+ @tempdir.find_file_with_extension('.gem')
105
+ end
106
+ end
107
+ end
108
+ end
109
+ end