eac_launcher 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/Gemfile +14 -0
- data/README.rdoc +3 -0
- data/exe/eac_launcher_instance +33 -0
- data/exe/eac_launcher_projects +43 -0
- data/exe/eac_launcher_publish +49 -0
- data/lib/eac_launcher.rb +44 -0
- data/lib/eac_launcher/context.rb +63 -0
- data/lib/eac_launcher/context/settings.rb +36 -0
- data/lib/eac_launcher/git/base.rb +105 -0
- data/lib/eac_launcher/git/base/subrepo.rb +18 -0
- data/lib/eac_launcher/git/base/underlying.rb +38 -0
- data/lib/eac_launcher/git/mirror_update.rb +32 -0
- data/lib/eac_launcher/git/publish_base.rb +69 -0
- data/lib/eac_launcher/git/transpose_base.rb +48 -0
- data/lib/eac_launcher/instances/base.rb +110 -0
- data/lib/eac_launcher/instances/base/cache.rb +38 -0
- data/lib/eac_launcher/instances/runner_helper.rb +37 -0
- data/lib/eac_launcher/instances/settings.rb +17 -0
- data/lib/eac_launcher/path.rb +25 -0
- data/lib/eac_launcher/project.rb +14 -0
- data/lib/eac_launcher/publish/base.rb +12 -0
- data/lib/eac_launcher/publish/check_result.rb +42 -0
- data/lib/eac_launcher/stereotype.rb +44 -0
- data/lib/eac_launcher/stereotypes/git.rb +17 -0
- data/lib/eac_launcher/stereotypes/git/publish.rb +9 -0
- data/lib/eac_launcher/stereotypes/git/transpose.rb +21 -0
- data/lib/eac_launcher/stereotypes/git_subrepo.rb +25 -0
- data/lib/eac_launcher/stereotypes/git_subrepo/publish.rb +8 -0
- data/lib/eac_launcher/stereotypes/git_subrepo/transpose.rb +87 -0
- data/lib/eac_launcher/stereotypes/git_subtree.rb +31 -0
- data/lib/eac_launcher/stereotypes/git_subtree/publish.rb +8 -0
- data/lib/eac_launcher/stereotypes/git_subtree/transpose.rb +27 -0
- data/lib/eac_launcher/stereotypes/rails.rb +17 -0
- data/lib/eac_launcher/stereotypes/redmine_plugin.rb +17 -0
- data/lib/eac_launcher/stereotypes/ruby_gem.rb +21 -0
- data/lib/eac_launcher/stereotypes/ruby_gem/publish.rb +109 -0
- data/lib/eac_launcher/vendor/github.rb +13 -0
- data/lib/eac_launcher/version.rb +5 -0
- 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,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,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,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,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
|