hem 1.0.1.beta1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.editorconfig +10 -0
- data/.gitignore +3 -0
- data/.rspec +2 -0
- data/CHANGELOG.md +125 -0
- data/DoD.md +5 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +71 -0
- data/Guardfile +14 -0
- data/Hemfile +43 -0
- data/LICENSE +21 -0
- data/README.md +42 -0
- data/Rakefile +23 -0
- data/bin/hem +64 -0
- data/features/deps.feature +43 -0
- data/features/hem/basic.feature +43 -0
- data/features/hem/help.feature +16 -0
- data/features/hem/subcommands.feature +15 -0
- data/features/seed/plant.feature +64 -0
- data/features/step_definitions/env.rb +6 -0
- data/features/step_definitions/seed.rb +11 -0
- data/features/support/env.rb +6 -0
- data/hem.gemspec +47 -0
- data/lib/hem/asset_applicator.rb +33 -0
- data/lib/hem/asset_applicators/files.rb +5 -0
- data/lib/hem/asset_applicators/sqldump.rb +38 -0
- data/lib/hem/cli.rb +252 -0
- data/lib/hem/config/file.rb +22 -0
- data/lib/hem/config.rb +5 -0
- data/lib/hem/error_handlers/debug.rb +12 -0
- data/lib/hem/error_handlers/exit_code_map.rb +17 -0
- data/lib/hem/error_handlers/friendly.rb +58 -0
- data/lib/hem/errors.rb +89 -0
- data/lib/hem/help_formatter.rb +118 -0
- data/lib/hem/helper/file_locator.rb +44 -0
- data/lib/hem/helper/github.rb +10 -0
- data/lib/hem/helper/http_download.rb +41 -0
- data/lib/hem/helper/shell.rb +101 -0
- data/lib/hem/helper/vm_command.rb +30 -0
- data/lib/hem/lib/github/api.rb +48 -0
- data/lib/hem/lib/github/client.rb +52 -0
- data/lib/hem/lib/host_check/deps.rb +39 -0
- data/lib/hem/lib/host_check/git.rb +76 -0
- data/lib/hem/lib/host_check/ruby.rb +53 -0
- data/lib/hem/lib/host_check/vagrant.rb +45 -0
- data/lib/hem/lib/host_check.rb +34 -0
- data/lib/hem/lib/s3/local/file.rb +40 -0
- data/lib/hem/lib/s3/local/iohandler.rb +36 -0
- data/lib/hem/lib/s3/remote/file.rb +57 -0
- data/lib/hem/lib/s3/remote/iohandler.rb +38 -0
- data/lib/hem/lib/s3/sync.rb +134 -0
- data/lib/hem/lib/seed/project.rb +71 -0
- data/lib/hem/lib/seed/replacer.rb +56 -0
- data/lib/hem/lib/seed/seed.rb +111 -0
- data/lib/hem/lib/self_signed_cert_generator.rb +38 -0
- data/lib/hem/lib/vm/command.rb +131 -0
- data/lib/hem/lib/vm/inspector.rb +73 -0
- data/lib/hem/logging.rb +20 -0
- data/lib/hem/metadata.rb +42 -0
- data/lib/hem/null.rb +31 -0
- data/lib/hem/patches/deepstruct.rb +21 -0
- data/lib/hem/patches/rake.rb +101 -0
- data/lib/hem/patches/rubygems.rb +6 -0
- data/lib/hem/patches/slop.rb +69 -0
- data/lib/hem/paths.rb +96 -0
- data/lib/hem/tasks/assets.rb +92 -0
- data/lib/hem/tasks/config.rb +15 -0
- data/lib/hem/tasks/deps.rb +103 -0
- data/lib/hem/tasks/exec.rb +3 -0
- data/lib/hem/tasks/magento.rb +281 -0
- data/lib/hem/tasks/ops.rb +6 -0
- data/lib/hem/tasks/pr.rb +45 -0
- data/lib/hem/tasks/seed.rb +61 -0
- data/lib/hem/tasks/self.rb +45 -0
- data/lib/hem/tasks/shell_init.rb +25 -0
- data/lib/hem/tasks/system/completions.rb +76 -0
- data/lib/hem/tasks/system.rb +18 -0
- data/lib/hem/tasks/tools.rb +17 -0
- data/lib/hem/tasks/vm.rb +140 -0
- data/lib/hem/ui.rb +182 -0
- data/lib/hem/util.rb +76 -0
- data/lib/hem/version.rb +3 -0
- data/lib/hem.rb +72 -0
- data/lib/hobo/tasks/magento.rb +3 -0
- data/spec/hem/asset_applicator_spec.rb +30 -0
- data/spec/hem/cli_spec.rb +166 -0
- data/spec/hem/config/file_spec.rb +55 -0
- data/spec/hem/error_handlers/debug_spec.rb +43 -0
- data/spec/hem/error_handlers/friendly_spec.rb +97 -0
- data/spec/hem/error_spec.rb +0 -0
- data/spec/hem/help_formatter_spec.rb +162 -0
- data/spec/hem/helpers/file_locator_spec.rb +11 -0
- data/spec/hem/helpers/github_spec.rb +31 -0
- data/spec/hem/helpers/shell_spec.rb +22 -0
- data/spec/hem/helpers/vm_command_spec.rb +96 -0
- data/spec/hem/lib/github/api_spec.rb +92 -0
- data/spec/hem/lib/s3/sync_spec.rb +16 -0
- data/spec/hem/lib/seed/project_spec.rb +80 -0
- data/spec/hem/lib/seed/replacer_spec.rb +45 -0
- data/spec/hem/lib/seed/seed_spec.rb +127 -0
- data/spec/hem/logging_spec.rb +27 -0
- data/spec/hem/metadata_spec.rb +55 -0
- data/spec/hem/null_spec.rb +30 -0
- data/spec/hem/patches/rake_spec.rb +230 -0
- data/spec/hem/paths_spec.rb +75 -0
- data/spec/hem/ui_spec.rb +189 -0
- data/spec/hem/util_spec.rb +74 -0
- data/spec/spec_helper.rb +12 -0
- data/ssl/ca-bundle-s3.crt +3554 -0
- data/test_files/vagrant_fail/vagrant +2 -0
- metadata +339 -0
data/lib/hem/tasks/vm.rb
ADDED
@@ -0,0 +1,140 @@
|
|
1
|
+
desc "VM related commands"
|
2
|
+
project_only
|
3
|
+
namespace :vm do
|
4
|
+
def vagrantfile &block
|
5
|
+
locate "*Vagrantfile" do
|
6
|
+
yield
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
def vagrant_exec *args
|
11
|
+
opts = { :realtime => true, :indent => 2 }
|
12
|
+
color = Hem.ui.supports_color? ? '--color' : '--no-color'
|
13
|
+
|
14
|
+
if Hem.windows?
|
15
|
+
opts[:env] = { 'VAGRANT_HOME' => windows_short(dir) } if ENV['HOME'].match(/\s+/) && !ENV['VAGRANT_HOME']
|
16
|
+
end
|
17
|
+
|
18
|
+
args.unshift 'vagrant'
|
19
|
+
args.push color
|
20
|
+
args.push opts
|
21
|
+
|
22
|
+
shell *args
|
23
|
+
end
|
24
|
+
|
25
|
+
def windows_short dir
|
26
|
+
segments = dir.gsub(/\\/, '/').split('/')
|
27
|
+
segments.map do |segment|
|
28
|
+
if segment.match /\s+/
|
29
|
+
# This may fail in some edge cases but better than naught
|
30
|
+
# See the following link for the correct solution
|
31
|
+
# http://stackoverflow.com/questions/10224572/convert-long-filename-to-short-filename-8-3
|
32
|
+
segment.upcase.gsub(/\s+/, '')[0...6] + '~1'
|
33
|
+
else
|
34
|
+
segment
|
35
|
+
end
|
36
|
+
end.join('/')
|
37
|
+
end
|
38
|
+
|
39
|
+
desc "Start & provision VM"
|
40
|
+
task :up => [ 'assets:download', 'vm:start', 'vm:provision', 'deps:composer', 'assets:apply' ]
|
41
|
+
|
42
|
+
desc "Stop VM"
|
43
|
+
task :stop do
|
44
|
+
vagrantfile do
|
45
|
+
Hem.ui.title "Stopping VM"
|
46
|
+
vagrant_exec 'halt'
|
47
|
+
Hem.ui.separator
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
desc "Rebuild VM"
|
52
|
+
task :rebuild => [ 'vm:destroy', 'vm:up' ]
|
53
|
+
|
54
|
+
desc "Destroy VM"
|
55
|
+
task :destroy do
|
56
|
+
vagrantfile do
|
57
|
+
Hem.ui.title "Destroying VM"
|
58
|
+
vagrant_exec 'destroy', '--force'
|
59
|
+
Hem.ui.separator
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
desc "Start VM without provision"
|
64
|
+
task :start => [ "deps:gems", "deps:chef", "deps:vagrant_plugins" ] do
|
65
|
+
vagrantfile do
|
66
|
+
state = shell("vagrant --machine-readable status | grep ,state, | cut -d, -f4", :capture => true).strip
|
67
|
+
unless state == 'running'
|
68
|
+
Hem.ui.title "Starting vagrant VM"
|
69
|
+
args = ['up', '--no-provision']
|
70
|
+
|
71
|
+
provider = maybe(Hem.user_config.vm.provider)
|
72
|
+
provider ||= maybe(Hem.project_config.vm.provider)
|
73
|
+
|
74
|
+
if provider
|
75
|
+
args.concat ['--provider', provider]
|
76
|
+
end
|
77
|
+
|
78
|
+
vagrant_exec *args
|
79
|
+
Hem.ui.separator
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
desc "Reload VM"
|
85
|
+
task :reload do
|
86
|
+
vagrantfile do
|
87
|
+
Hem.ui.title "Reloading VM"
|
88
|
+
vagrant_exec 'reload', '--no-provision'
|
89
|
+
Hem.ui.separator
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
desc "Provision VM"
|
94
|
+
task :provision => [ "deps:chef" ] do
|
95
|
+
vagrantfile do
|
96
|
+
Hem.ui.title "Provisioning VM"
|
97
|
+
vagrant_exec 'provision'
|
98
|
+
Hem.ui.separator
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
desc "Open an SSH connection"
|
103
|
+
task :ssh do |task|
|
104
|
+
execute = task.opts[:_unparsed]
|
105
|
+
opts = { :psuedo_tty => STDIN.tty? }
|
106
|
+
|
107
|
+
Hem.ui.success "Determining VM connection details..." if STDOUT.tty?
|
108
|
+
command = execute.empty? ? vm_command(nil, opts) : vm_command(execute, opts)
|
109
|
+
Hem.logger.debug "vm:ssh: #{command}"
|
110
|
+
|
111
|
+
Hem.ui.success "Connecting..." if STDOUT.tty?
|
112
|
+
exec command
|
113
|
+
end
|
114
|
+
|
115
|
+
desc "Open a MySQL cli connection"
|
116
|
+
option '-D=', '--db=', 'Database'
|
117
|
+
task :mysql do |task|
|
118
|
+
opts = { :psuedo_tty => STDIN.tty? }
|
119
|
+
opts[:db] = task.opts[:db] if task.opts[:db]
|
120
|
+
|
121
|
+
Hem.ui.success "Determining VM connection details..." if STDOUT.tty?
|
122
|
+
command = vm_mysql(opts)
|
123
|
+
Hem.logger.debug "vm:mysql: #{command}"
|
124
|
+
|
125
|
+
Hem.ui.success "Connecting..." if STDOUT.tty?
|
126
|
+
exec command
|
127
|
+
end
|
128
|
+
|
129
|
+
desc "Open a Redis cli connection"
|
130
|
+
task :redis do
|
131
|
+
opts = { :psuedo_tty => STDIN.tty? }
|
132
|
+
|
133
|
+
Hem.ui.success "Determining VM connection details..." if STDOUT.tty?
|
134
|
+
command = vm_command("redis-cli", opts)
|
135
|
+
Hem.logger.debug "vm:redis: #{command}"
|
136
|
+
|
137
|
+
Hem.ui.success "Connecting..." if STDOUT.tty?
|
138
|
+
exec command
|
139
|
+
end
|
140
|
+
end
|
data/lib/hem/ui.rb
ADDED
@@ -0,0 +1,182 @@
|
|
1
|
+
module Hem
|
2
|
+
class << self
|
3
|
+
attr_accessor :ui
|
4
|
+
end
|
5
|
+
|
6
|
+
class Ui
|
7
|
+
include Hem::Logging
|
8
|
+
|
9
|
+
attr_accessor :interactive
|
10
|
+
|
11
|
+
COLORS = {
|
12
|
+
:debug => [ ],
|
13
|
+
:info => [ ],
|
14
|
+
:warning => [:yellow],
|
15
|
+
:error => [:red],
|
16
|
+
:success => [:green],
|
17
|
+
:opt => [:green],
|
18
|
+
:command => [:green],
|
19
|
+
:special => [:blue],
|
20
|
+
:title => [:green],
|
21
|
+
:help_title => [:yellow],
|
22
|
+
:description => [:bold]
|
23
|
+
}
|
24
|
+
|
25
|
+
def initialize input = $stdin, output = $stdout, error = $stderr
|
26
|
+
require 'highline'
|
27
|
+
HighLine.color_scheme = HighLine::ColorScheme.new COLORS
|
28
|
+
@output_io = output
|
29
|
+
@out = ::HighLine.new input, output
|
30
|
+
@error = ::HighLine.new input, error
|
31
|
+
use_color supports_color?
|
32
|
+
end
|
33
|
+
|
34
|
+
def color_scheme scheme = nil
|
35
|
+
HighLine.color_scheme = scheme if scheme
|
36
|
+
HighLine.color_scheme
|
37
|
+
end
|
38
|
+
|
39
|
+
def supports_color?
|
40
|
+
return @output_io.tty? unless Hem.windows?
|
41
|
+
return (ENV['ANSICON'] || ENV['TERM'] == 'xterm') && @output_io.tty? # ANSICON or MinTTY && output is TTY
|
42
|
+
end
|
43
|
+
|
44
|
+
def use_color opt = nil
|
45
|
+
HighLine.use_color = opt unless opt.nil?
|
46
|
+
HighLine.use_color?
|
47
|
+
end
|
48
|
+
|
49
|
+
def ask question, opts = {}
|
50
|
+
opts = {
|
51
|
+
:validate => nil,
|
52
|
+
:default => nil,
|
53
|
+
:echo => true
|
54
|
+
}.merge(opts)
|
55
|
+
|
56
|
+
unless @interactive
|
57
|
+
raise Hem::NonInteractiveError.new(question) if opts[:default].nil?
|
58
|
+
return opts[:default].to_s
|
59
|
+
end
|
60
|
+
|
61
|
+
question = "#{question} [#{opts[:default]}]" if opts[:default]
|
62
|
+
question += ": "
|
63
|
+
begin
|
64
|
+
answer = @out.ask(question) do |q|
|
65
|
+
q.validate = opts[:validate] if opts[:validate]
|
66
|
+
q.echo = opts[:echo]
|
67
|
+
q.readline
|
68
|
+
end
|
69
|
+
answer = answer.to_s
|
70
|
+
answer.strip.empty? ? opts[:default].to_s : answer.strip
|
71
|
+
rescue EOFError
|
72
|
+
Hem.ui.info ""
|
73
|
+
""
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def ask_choice question, choices, opts = {}
|
78
|
+
unless @interactive
|
79
|
+
raise Hem::NonInteractiveError.new(question) if opts[:default].nil?
|
80
|
+
return opts[:default].to_s
|
81
|
+
end
|
82
|
+
|
83
|
+
question = "#{question} [#{opts[:default]}]" if opts[:default]
|
84
|
+
question += ":"
|
85
|
+
info question
|
86
|
+
|
87
|
+
choice_map = {}
|
88
|
+
choices.to_enum.with_index(1) do |choice, index|
|
89
|
+
choice_map[index.to_s] = choice
|
90
|
+
info "#{index}] #{choice}"
|
91
|
+
end
|
92
|
+
|
93
|
+
begin
|
94
|
+
answer = @out.ask("? ") do |q|
|
95
|
+
q.validate = lambda do |a|
|
96
|
+
s = a.strip
|
97
|
+
s.empty? || (choice_map.keys + choices).include?(s)
|
98
|
+
end
|
99
|
+
q.readline
|
100
|
+
end
|
101
|
+
answer = answer.to_s
|
102
|
+
answer = choice_map[answer] if /^\d+$/.match(answer.strip)
|
103
|
+
answer.strip.empty? ? opts[:default].to_s : answer.strip
|
104
|
+
rescue EOFError
|
105
|
+
Hem.ui.info ""
|
106
|
+
""
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
def editor initial_text
|
111
|
+
editor = Hem.user_config.editor.nil? ? ENV['EDITOR'] : Hem.user_config.editor
|
112
|
+
if editor.nil?
|
113
|
+
raise Hem::UndefinedEditorError.new
|
114
|
+
end
|
115
|
+
|
116
|
+
tmp = Tempfile.new('hem_tmp')
|
117
|
+
begin
|
118
|
+
tmp.write initial_text
|
119
|
+
tmp.close
|
120
|
+
system([editor, tmp.path].join(' '))
|
121
|
+
tmp.open
|
122
|
+
return tmp.read
|
123
|
+
rescue Exception => e
|
124
|
+
raise Hem::Error.new e.message
|
125
|
+
ensure
|
126
|
+
tmp.close
|
127
|
+
tmp.unlink
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
def section title
|
132
|
+
Hem.ui.title title
|
133
|
+
yield
|
134
|
+
Hem.ui.separator
|
135
|
+
end
|
136
|
+
|
137
|
+
def separator
|
138
|
+
info(supports_color? ? "" : "\n")
|
139
|
+
end
|
140
|
+
|
141
|
+
def color *args
|
142
|
+
@out.color *args
|
143
|
+
end
|
144
|
+
|
145
|
+
def debug message
|
146
|
+
say @out, message, :debug
|
147
|
+
end
|
148
|
+
|
149
|
+
def info message
|
150
|
+
say @out, message, :info
|
151
|
+
end
|
152
|
+
|
153
|
+
def warning message
|
154
|
+
say @error, message, :warning
|
155
|
+
end
|
156
|
+
|
157
|
+
def error message
|
158
|
+
say @error, message, :error
|
159
|
+
end
|
160
|
+
|
161
|
+
def success message
|
162
|
+
say @out, message, :success
|
163
|
+
end
|
164
|
+
|
165
|
+
def output message
|
166
|
+
say @out, message, nil
|
167
|
+
end
|
168
|
+
|
169
|
+
def title message
|
170
|
+
say @out, message, :title
|
171
|
+
end
|
172
|
+
|
173
|
+
private
|
174
|
+
|
175
|
+
def say channel, message, color
|
176
|
+
return if message.nil?
|
177
|
+
message = color ? channel.color(message, color) : message
|
178
|
+
channel.say(message) unless logger.level <= Logger::DEBUG
|
179
|
+
logger.debug(message)
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
data/lib/hem/util.rb
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
module Hem
|
2
|
+
class << self
|
3
|
+
|
4
|
+
attr_accessor :project_bar_cache
|
5
|
+
|
6
|
+
def relaunch! env = {}
|
7
|
+
Kernel.exec(env, 'hem', '--skip-host-checks', *$HEM_ARGV)
|
8
|
+
end
|
9
|
+
|
10
|
+
def in_project?
|
11
|
+
!!Hem.project_path
|
12
|
+
end
|
13
|
+
|
14
|
+
def progress file, increment, total, type, opts = {}
|
15
|
+
require 'ruby-progressbar'
|
16
|
+
|
17
|
+
opts = {
|
18
|
+
:title => File.basename(file),
|
19
|
+
:total => total,
|
20
|
+
:format => "%t [%B] %p%% %e"
|
21
|
+
}.merge(opts)
|
22
|
+
|
23
|
+
# Hack to stop newline spam on windows
|
24
|
+
opts[:length] = 79 if Gem::win_platform?
|
25
|
+
|
26
|
+
@progress_bar_cache ||= {}
|
27
|
+
|
28
|
+
if type == :reset
|
29
|
+
type = :update
|
30
|
+
@progress_bar_cache.delete file
|
31
|
+
end
|
32
|
+
|
33
|
+
@progress_bar_cache[file] ||= ProgressBar.create(opts)
|
34
|
+
|
35
|
+
case type
|
36
|
+
when :update
|
37
|
+
@progress_bar_cache[file].progress += increment
|
38
|
+
when :finished
|
39
|
+
@progress_bar_cache[file].finish
|
40
|
+
end
|
41
|
+
|
42
|
+
return @progress_bar_cache[file]
|
43
|
+
end
|
44
|
+
|
45
|
+
def aws_credentials
|
46
|
+
{
|
47
|
+
:access_key_id => maybe(Hem.user_config.aws.access_key_id) || ENV['AWS_ACCESS_KEY_ID'],
|
48
|
+
:secret_access_key => maybe(Hem.user_config.aws.secret_access_key) || ENV['AWS_SECRET_ACCESS_KEY']
|
49
|
+
}
|
50
|
+
end
|
51
|
+
|
52
|
+
def windows?
|
53
|
+
require 'rbconfig'
|
54
|
+
!!(RbConfig::CONFIG['host_os'] =~ /mswin|msys|mingw|cygwin|bccwin|wince|emc/)
|
55
|
+
end
|
56
|
+
|
57
|
+
def system_ruby?
|
58
|
+
require 'rbconfig'
|
59
|
+
File.join(RbConfig::CONFIG["bindir"], RbConfig::CONFIG["ruby_install_name"]).match(/\/rvm\/|\/\.rvm\/|\/\.rbenv/) != nil
|
60
|
+
end
|
61
|
+
|
62
|
+
def chefdk_compat
|
63
|
+
return if maybe(Hem.user_config.hem.disable_chefdk_compat) || ENV['HEM_DISABLE_CHEFDK_COMPAT']
|
64
|
+
return if Hem.windows?
|
65
|
+
which_ruby = File.join(RbConfig::CONFIG["bindir"], RbConfig::CONFIG["ruby_install_name"])
|
66
|
+
if which_ruby =~ /rbenv/
|
67
|
+
split_path = ENV['PATH'].split ':'
|
68
|
+
paths = split_path.reject do |p|
|
69
|
+
p =~ /chefdk/
|
70
|
+
end
|
71
|
+
chef_paths = split_path - paths
|
72
|
+
ENV['PATH'] = (chef_paths + paths).join ':'
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
data/lib/hem/version.rb
ADDED
data/lib/hem.rb
ADDED
@@ -0,0 +1,72 @@
|
|
1
|
+
# External deps
|
2
|
+
require 'slop'
|
3
|
+
require 'rake'
|
4
|
+
require 'deepstruct'
|
5
|
+
require 'logger'
|
6
|
+
|
7
|
+
require 'shellwords'
|
8
|
+
require 'fileutils'
|
9
|
+
|
10
|
+
# DSL enhancements
|
11
|
+
require 'hem/metadata'
|
12
|
+
require 'hem/patches/rake'
|
13
|
+
require 'hem/patches/slop'
|
14
|
+
require 'hem/patches/deepstruct'
|
15
|
+
|
16
|
+
# Basics
|
17
|
+
require 'hem/version'
|
18
|
+
require 'hem/null'
|
19
|
+
require 'hem/paths'
|
20
|
+
require 'hem/errors'
|
21
|
+
require 'hem/logging'
|
22
|
+
require 'hem/ui'
|
23
|
+
require 'hem/util'
|
24
|
+
require 'hem/help_formatter'
|
25
|
+
require 'hem/error_handlers/exit_code_map'
|
26
|
+
require 'hem/error_handlers/debug'
|
27
|
+
require 'hem/error_handlers/friendly'
|
28
|
+
require 'hem/config/file'
|
29
|
+
require 'hem/config'
|
30
|
+
|
31
|
+
# Asset sync
|
32
|
+
require 'hem/lib/s3/sync'
|
33
|
+
require 'hem/lib/s3/local/file'
|
34
|
+
require 'hem/lib/s3/local/iohandler'
|
35
|
+
require 'hem/lib/s3/remote/file'
|
36
|
+
require 'hem/lib/s3/remote/iohandler'
|
37
|
+
|
38
|
+
# Task helpers
|
39
|
+
require 'hem/helper/shell'
|
40
|
+
require 'hem/helper/file_locator'
|
41
|
+
require 'hem/helper/github'
|
42
|
+
require 'hem/helper/http_download'
|
43
|
+
require 'hem/helper/vm_command'
|
44
|
+
|
45
|
+
require 'hem/lib/vm/inspector'
|
46
|
+
require 'hem/lib/vm/command'
|
47
|
+
|
48
|
+
# Asset applicators
|
49
|
+
require 'hem/asset_applicator'
|
50
|
+
require 'hem/asset_applicators/sqldump'
|
51
|
+
require 'hem/asset_applicators/files'
|
52
|
+
|
53
|
+
# Libs
|
54
|
+
require 'hem/lib/seed/project'
|
55
|
+
require 'hem/lib/seed/replacer'
|
56
|
+
require 'hem/lib/seed/seed'
|
57
|
+
require 'hem/lib/self_signed_cert_generator'
|
58
|
+
require 'hem/lib/github/api'
|
59
|
+
require 'hem/lib/github/client'
|
60
|
+
|
61
|
+
# Host checks
|
62
|
+
require 'hem/lib/host_check/git'
|
63
|
+
require 'hem/lib/host_check/vagrant'
|
64
|
+
require 'hem/lib/host_check/ruby'
|
65
|
+
require 'hem/lib/host_check/deps'
|
66
|
+
require 'hem/lib/host_check'
|
67
|
+
|
68
|
+
# App
|
69
|
+
require 'hem/cli'
|
70
|
+
|
71
|
+
# Hobo BC
|
72
|
+
Hobo = Hem
|
@@ -0,0 +1,30 @@
|
|
1
|
+
|
2
|
+
describe Hem::AssetApplicatorRegistry do
|
3
|
+
describe "asset_applicators accessor" do
|
4
|
+
it "should initialize registry if none exists" do
|
5
|
+
Hem.asset_applicators = nil
|
6
|
+
Hem.asset_applicators.should be_an_instance_of Hem::AssetApplicatorRegistry
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should return registry if exists" do
|
10
|
+
Hem.asset_applicators.register "test" do
|
11
|
+
"test"
|
12
|
+
end
|
13
|
+
|
14
|
+
Hem.asset_applicators["test"].should be_an_instance_of Proc
|
15
|
+
Hem.asset_applicators["test"].call.should match "test"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe "register" do
|
20
|
+
it "should store passed block with pattern" do
|
21
|
+
registry = Hem::AssetApplicatorRegistry.new
|
22
|
+
registry.register "abc" do
|
23
|
+
"block"
|
24
|
+
end
|
25
|
+
|
26
|
+
registry["abc"].should be_an_instance_of Proc
|
27
|
+
registry["abc"].call.should match "block"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,166 @@
|
|
1
|
+
|
2
|
+
describe Hem::Cli do
|
3
|
+
cli = nil
|
4
|
+
help = nil
|
5
|
+
hemfile = nil
|
6
|
+
|
7
|
+
def test_args args
|
8
|
+
args.concat([])
|
9
|
+
end
|
10
|
+
|
11
|
+
before do
|
12
|
+
Rake::Task.tasks.each do |task|
|
13
|
+
task.clear
|
14
|
+
end
|
15
|
+
|
16
|
+
Hem.ui = double(Hem::Ui).as_null_object
|
17
|
+
help = double(Hem::HelpFormatter).as_null_object
|
18
|
+
host_check = double(Hem::Lib::HostCheck).as_null_object
|
19
|
+
cli = Hem::Cli.new help: help, host_check: host_check
|
20
|
+
|
21
|
+
hemfile = File.read(File.join(File.dirname(__FILE__), '../../Hemfile'))
|
22
|
+
|
23
|
+
Hem.project_path = nil
|
24
|
+
FakeFS.activate!
|
25
|
+
|
26
|
+
File.write('Hemfile', hemfile)
|
27
|
+
end
|
28
|
+
|
29
|
+
after do
|
30
|
+
FakeFS::FileSystem.clear
|
31
|
+
FakeFS.deactivate!
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should load the hemfile if present" do
|
35
|
+
cli.start test_args([])
|
36
|
+
Rake::Task["test:non-interactive"].should_not be nil
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should load the user hemfile if present" do
|
40
|
+
FileUtils.mkdir_p(File.dirname(Hem.user_hemfile_path))
|
41
|
+
File.write(Hem.user_hemfile_path, "namespace :user do\ntask :user do\nend\nend")
|
42
|
+
cli.start test_args([])
|
43
|
+
Rake::Task["user:user"].should_not be nil
|
44
|
+
end
|
45
|
+
|
46
|
+
it "should present Hemfile path in eval error" do
|
47
|
+
FileUtils.mkdir_p(File.dirname(Hem.hemfile_path))
|
48
|
+
File.write(Hem.hemfile_path, "An invalid hemfile")
|
49
|
+
begin
|
50
|
+
cli.start test_args([])
|
51
|
+
rescue Exception => e
|
52
|
+
e.backtrace[0].should match 'Hemfile'
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
it "should load project config if present" do
|
57
|
+
FileUtils.mkdir_p("tools/hem/")
|
58
|
+
File.write("tools/hem/config.yaml", YAML::dump({ :project => "project_config" }))
|
59
|
+
cli.start test_args([])
|
60
|
+
Hem.project_config.project.should match "project_config"
|
61
|
+
end
|
62
|
+
|
63
|
+
it "should load user config if present" do
|
64
|
+
FileUtils.mkdir_p(Hem.config_path)
|
65
|
+
File.write(Hem.user_config_file, YAML::dump({ :user => "user_config" }))
|
66
|
+
cli.start test_args([])
|
67
|
+
Hem.user_config.user.should match "user_config"
|
68
|
+
end
|
69
|
+
|
70
|
+
it "should set command map on help formatter" do
|
71
|
+
help.should_recieve('command_map=')
|
72
|
+
cli.start test_args(["test", "subcommand"])
|
73
|
+
end
|
74
|
+
|
75
|
+
it "should propagate description metadata" do
|
76
|
+
map = nil
|
77
|
+
allow(help).to receive("command_map=") { |i| map = i }
|
78
|
+
cli.start test_args([])
|
79
|
+
map["test:metadata"].description.should match "description"
|
80
|
+
end
|
81
|
+
|
82
|
+
it "should propagate long description metadata" do
|
83
|
+
map = nil
|
84
|
+
allow(help).to receive("command_map=") { |i| map = i }
|
85
|
+
cli.start test_args([])
|
86
|
+
map["test:metadata"].long_description.should match "long description"
|
87
|
+
end
|
88
|
+
|
89
|
+
it "should propagate arg list metadata" do
|
90
|
+
map = nil
|
91
|
+
allow(help).to receive("command_map=") { |i| map = i }
|
92
|
+
cli.start test_args([])
|
93
|
+
expect(map["test:metadata"].arg_list).to eq [ :arg ]
|
94
|
+
end
|
95
|
+
|
96
|
+
it "should propagate option metadata" do
|
97
|
+
map = nil
|
98
|
+
allow(help).to receive("command_map=") { |i| map = i }
|
99
|
+
cli.start test_args([])
|
100
|
+
map["test:metadata"].options.length.should be 2
|
101
|
+
expect(map["test:metadata"].options.map(&:short)).to eq [ 'o', 'h' ]
|
102
|
+
expect(map["test:metadata"].options.map(&:long)).to eq [ 'option', 'help' ]
|
103
|
+
expect(map["test:metadata"].options.map(&:description)).to eq [ 'Option description', 'Display help' ]
|
104
|
+
end
|
105
|
+
|
106
|
+
it "should propagate hidden metadata" do
|
107
|
+
map = nil
|
108
|
+
allow(help).to receive("command_map=") { |i| map = i }
|
109
|
+
cli.start test_args([])
|
110
|
+
map["test:metadata"].hidden.should be true
|
111
|
+
end
|
112
|
+
|
113
|
+
it "should show help if no args or opts passed" do
|
114
|
+
help.should_receive(:help)
|
115
|
+
cli.start(test_args([]))
|
116
|
+
end
|
117
|
+
|
118
|
+
it "should show help for --help" do
|
119
|
+
help.should_receive(:help)
|
120
|
+
cli.start test_args(["--help"])
|
121
|
+
end
|
122
|
+
|
123
|
+
it "should execute a top level command" do
|
124
|
+
Hem.ui.should_recieve(:info).with("top level")
|
125
|
+
cli.start test_args(["top-level"])
|
126
|
+
end
|
127
|
+
|
128
|
+
it "should execute a subcommand" do
|
129
|
+
Hem.ui.should_recieve(:info).with("Subcommand test")
|
130
|
+
cli.start test_args(["test", "subcommand"])
|
131
|
+
end
|
132
|
+
|
133
|
+
it "should show help for a namespace" do
|
134
|
+
help.should_receive(:help).with(all: nil, target: "test")
|
135
|
+
cli.start test_args(["test"])
|
136
|
+
end
|
137
|
+
|
138
|
+
it "should show command help for --help" do
|
139
|
+
help.should_receive(:help).with(all: nil, target: "test:subcommand")
|
140
|
+
cli.start test_args(["test", "subcommand", "--help"])
|
141
|
+
end
|
142
|
+
|
143
|
+
it "should propagate --all option to help" do
|
144
|
+
help.should_receive(:help).with(all: true, target: "test")
|
145
|
+
cli.start test_args(["test", "--all"])
|
146
|
+
end
|
147
|
+
|
148
|
+
it "should propagate command opts to command" do
|
149
|
+
Hem.ui.should_receive(:info).with("1234")
|
150
|
+
cli.start test_args(["test", "option-test", "--testing=1234"])
|
151
|
+
end
|
152
|
+
|
153
|
+
it "should propagate arguments to command" do
|
154
|
+
Hem.ui.should_receive(:info).with("1234")
|
155
|
+
cli.start test_args(["test", "argument-test", "1234"])
|
156
|
+
end
|
157
|
+
|
158
|
+
it "should propagate unparsed arguments in :_unparsed opt" do
|
159
|
+
Hem.ui.should_receive(:info).with("'ls' '--help'")
|
160
|
+
cli.start ["test", "unparsed", "--", "ls", "--help"]
|
161
|
+
end
|
162
|
+
|
163
|
+
it "should raise an exception if not enough arguments were passed" do
|
164
|
+
expect { cli.start(test_args(["test", "metadata"])) }.to raise_error Hem::MissingArgumentsError
|
165
|
+
end
|
166
|
+
end
|