eac_launcher 0.1.0

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