hem 1.0.1.beta6 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +32 -45
- data/Hemfile +4 -2
- data/README.md +4 -0
- data/bin/hem +5 -6
- data/hem.gemspec +15 -15
- data/lib/hem.rb +47 -45
- data/lib/hem/asset_applicators/files.rb +1 -1
- data/lib/hem/cli.rb +36 -29
- data/lib/hem/error_handlers/debug.rb +1 -1
- data/lib/hem/error_handlers/friendly.rb +3 -3
- data/lib/hem/errors.rb +23 -12
- data/lib/hem/help_formatter.rb +12 -3
- data/lib/hem/helper/argument_parser.rb +30 -0
- data/lib/hem/helper/command.rb +2 -1
- data/lib/hem/helper/file_locator.rb +34 -7
- data/lib/hem/helper/shell.rb +0 -1
- data/lib/hem/helper/vm_command.rb +2 -2
- data/lib/hem/lib/host_check/vagrant.rb +2 -3
- data/lib/hem/lib/s3/sync.rb +2 -2
- data/lib/hem/lib/seed/project.rb +10 -13
- data/lib/hem/lib/seed/replacer.rb +9 -31
- data/lib/hem/lib/seed/template.rb +21 -0
- data/lib/hem/lib/vm/inspector.rb +1 -1
- data/lib/hem/patches/deepstruct.rb +4 -0
- data/lib/hem/patches/rake.rb +42 -11
- data/lib/hem/plugins.rb +129 -0
- data/lib/hem/setup.rb +6 -0
- data/lib/hem/tasks.rb +15 -0
- data/lib/hem/tasks/deps.rb +13 -14
- data/lib/hem/tasks/exec.rb +4 -2
- data/lib/hem/tasks/magento.rb +13 -275
- data/lib/hem/tasks/mysql.rb +16 -0
- data/lib/hem/tasks/ops.rb +2 -1
- data/lib/hem/tasks/plugin.rb +16 -0
- data/lib/hem/tasks/redis.rb +26 -0
- data/lib/hem/tasks/seed.rb +4 -2
- data/lib/hem/tasks/self.rb +7 -6
- data/lib/hem/tasks/tools.rb +1 -1
- data/lib/hem/tasks/vm.rb +8 -16
- data/lib/hem/util.rb +6 -16
- data/lib/hem/version.rb +12 -1
- data/lib/hobo/tasks/magento.rb +2 -1
- data/spec/hem/cli_spec.rb +1 -0
- data/spec/hem/helpers/argument_parser_spec.rb +57 -0
- data/spec/hem/lib/seed/project_spec.rb +1 -0
- data/spec/hem/lib/seed/replacer_spec.rb +12 -13
- data/spec/hem/lib/seed/seed_spec.rb +1 -0
- metadata +50 -42
- data/lib/hem/lib/github/api.rb +0 -48
- data/lib/hem/lib/github/client.rb +0 -52
- data/lib/hem/tasks/pr.rb +0 -45
@@ -3,7 +3,7 @@ module Hem
|
|
3
3
|
class Debug
|
4
4
|
include Hem::ErrorHandlers::ExitCodeMap
|
5
5
|
|
6
|
-
def handle error
|
6
|
+
def handle _, error
|
7
7
|
Hem.ui.error "\n(#{error.class}) #{error.message}\n\n#{(error.backtrace || []).join("\n")}"
|
8
8
|
return EXIT_CODES[error.class.to_s] || DEFAULT_EXIT_CODE
|
9
9
|
end
|
@@ -3,7 +3,7 @@ module Hem
|
|
3
3
|
class Friendly
|
4
4
|
include Hem::ErrorHandlers::ExitCodeMap
|
5
5
|
|
6
|
-
def handle error
|
6
|
+
def handle cli, error
|
7
7
|
require 'tmpdir'
|
8
8
|
log_file = File.join(Dir.tmpdir, 'hem_error.log')
|
9
9
|
|
@@ -27,10 +27,10 @@ module Hem
|
|
27
27
|
ERROR
|
28
28
|
when "Hem::InvalidCommandOrOpt"
|
29
29
|
Hem.ui.error "\n#{error.message}"
|
30
|
-
Hem.ui.info
|
30
|
+
Hem.ui.info cli.help_formatter.help
|
31
31
|
when "Hem::MissingArgumentsError"
|
32
32
|
Hem.ui.error "\n#{error.message}"
|
33
|
-
Hem.ui.info
|
33
|
+
Hem.ui.info cli.help_formatter.help(target: error.command)
|
34
34
|
when "Hem::UserError"
|
35
35
|
Hem.ui.error "\n#{error.message}\n"
|
36
36
|
when "Hem::ProjectOnlyError"
|
data/lib/hem/errors.rb
CHANGED
@@ -2,6 +2,19 @@ module Hem
|
|
2
2
|
class Error < StandardError
|
3
3
|
attr_reader :exit_code
|
4
4
|
end
|
5
|
+
|
6
|
+
class HemVersionError < Error
|
7
|
+
def initialize requirements
|
8
|
+
super("
|
9
|
+
This Hem project has specified that it requires the Hem
|
10
|
+
version to satisfy the following version requirements:
|
11
|
+
#{requirements.join("\n")}
|
12
|
+
You are running Hem #{VERSION}, which does not satisfy
|
13
|
+
these requirements. Please upgrade Hem to the latest
|
14
|
+
version, or relax the Hemfile's version constraints if
|
15
|
+
you're already using the latest Hem version.")
|
16
|
+
end
|
17
|
+
end
|
5
18
|
|
6
19
|
class RubyVersionError < Error
|
7
20
|
def initialize
|
@@ -17,24 +30,28 @@ module Hem
|
|
17
30
|
end
|
18
31
|
|
19
32
|
class InvalidCommandOrOpt < Error
|
20
|
-
attr_accessor :command
|
21
|
-
def initialize command
|
33
|
+
attr_accessor :command
|
34
|
+
def initialize command
|
22
35
|
@command = command
|
23
|
-
@cli = cli
|
24
36
|
super("Invalid command or option specified: '#{command}'")
|
25
37
|
end
|
26
38
|
end
|
27
39
|
|
28
40
|
class MissingArgumentsError < Error
|
29
|
-
attr_accessor :command
|
30
|
-
def initialize command, args
|
41
|
+
attr_accessor :command
|
42
|
+
def initialize command, args
|
31
43
|
@command = command
|
32
44
|
@args = args
|
33
|
-
@cli = cli
|
34
45
|
super("Not enough arguments for #{command}")
|
35
46
|
end
|
36
47
|
end
|
37
48
|
|
49
|
+
class PluginsAlreadySetupError < Error
|
50
|
+
def initialize
|
51
|
+
super("Hem's plugins have already been set up. Additional plugins can't be defined after.")
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
38
55
|
class ExternalCommandError < Error
|
39
56
|
attr_accessor :command, :exit_code, :output
|
40
57
|
|
@@ -80,10 +97,4 @@ module Hem
|
|
80
97
|
super('You need to define a preferred editor, either in your hem config or with the EDITOR environment variable')
|
81
98
|
end
|
82
99
|
end
|
83
|
-
|
84
|
-
class GithubAuthenticationError < Error
|
85
|
-
end
|
86
|
-
|
87
|
-
class GithubApiError < Error
|
88
|
-
end
|
89
100
|
end
|
data/lib/hem/help_formatter.rb
CHANGED
@@ -91,16 +91,25 @@ module Hem
|
|
91
91
|
def usage source, command = nil
|
92
92
|
banner = source.banner
|
93
93
|
if banner.nil?
|
94
|
-
arg_list = (source.arg_list ||
|
95
|
-
"<#{arg}>"
|
94
|
+
arg_list = (source.arg_list || {}).map do |arg, options|
|
95
|
+
arg_text = "<#{arg}>"
|
96
|
+
if options[:as] == Array
|
97
|
+
arg_text = "#{arg_text}..."
|
98
|
+
end
|
99
|
+
if options[:optional]
|
100
|
+
arg_text = "[#{arg_text}]"
|
101
|
+
end
|
102
|
+
arg_text
|
96
103
|
end
|
97
104
|
|
98
105
|
banner = "#{File.basename($0, '.*')}"
|
99
106
|
banner << " [command]" if source.commands.any? && command.nil?
|
100
107
|
banner << " #{command.split(':').join(' ')}" if command
|
101
|
-
banner << " #{arg_list.join(' ')}" if arg_list.size > 0
|
102
108
|
banner << " [options]"
|
109
|
+
banner << " #{arg_list.join(' ')}" if arg_list.size > 0
|
103
110
|
end
|
111
|
+
|
112
|
+
banner
|
104
113
|
end
|
105
114
|
|
106
115
|
def section title, contents, align_to = false
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Hem
|
2
|
+
module Helper
|
3
|
+
def convert_args task_name, args, arg_list
|
4
|
+
original_args = args.dup
|
5
|
+
task_args = []
|
6
|
+
arg_list.each do |_, options|
|
7
|
+
if args.empty?
|
8
|
+
if !options[:optional]
|
9
|
+
raise ::Hem::MissingArgumentsError.new(task_name, original_args)
|
10
|
+
else
|
11
|
+
task_args << options[:default]
|
12
|
+
end
|
13
|
+
elsif options[:as] == Array
|
14
|
+
task_args << args.dup
|
15
|
+
args.clear
|
16
|
+
else
|
17
|
+
task_args << args.shift
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
unless args.empty?
|
22
|
+
raise ::Hem::InvalidCommandOrOpt.new(args.join(' '))
|
23
|
+
end
|
24
|
+
|
25
|
+
task_args
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
include Hem::Helper
|
data/lib/hem/helper/command.rb
CHANGED
@@ -1,10 +1,27 @@
|
|
1
1
|
module Hem
|
2
2
|
module Helper
|
3
|
-
|
3
|
+
extend self
|
4
|
+
|
5
|
+
def locate(name, patterns = nil, opts = {}, &block)
|
6
|
+
opts = {
|
7
|
+
type: 'git',
|
8
|
+
patterns: patterns || [name, "**/#{name}"],
|
9
|
+
path: Hem.project_path,
|
10
|
+
}.merge(opts)
|
11
|
+
|
4
12
|
match = nil
|
5
13
|
|
6
|
-
|
7
|
-
|
14
|
+
unless Hem.project_config[:locate].nil? || Hem.project_config[:locate][name].nil?
|
15
|
+
opts = opts.merge(Hem.project_config[:locate][name].to_hash_sym)
|
16
|
+
end
|
17
|
+
|
18
|
+
Dir.chdir opts[:path] do
|
19
|
+
case opts[:type]
|
20
|
+
when 'git'
|
21
|
+
match = locate_git(opts[:patterns], &block)
|
22
|
+
when 'files'
|
23
|
+
match = locate_files(opts[:patterns], &block)
|
24
|
+
end
|
8
25
|
end
|
9
26
|
|
10
27
|
return match unless block_given?
|
@@ -16,20 +33,30 @@ module Hem
|
|
16
33
|
|
17
34
|
private
|
18
35
|
|
19
|
-
def
|
20
|
-
|
36
|
+
def locate_files patterns, &block
|
37
|
+
paths = patterns.inject([]) do |result, pattern|
|
38
|
+
result + Dir.glob(pattern)
|
39
|
+
end
|
40
|
+
locate_loop paths, &block
|
41
|
+
end
|
42
|
+
|
43
|
+
def locate_git patterns, &block
|
44
|
+
args = [ 'git', 'ls-files', *patterns ]
|
21
45
|
output = Hem::Helper.shell *args, :capture => true
|
22
46
|
paths = output.split("\n")
|
23
|
-
found = false
|
24
47
|
paths.each do |path|
|
25
48
|
path.strip!
|
26
49
|
end
|
50
|
+
locate_loop paths, &block
|
51
|
+
end
|
27
52
|
|
53
|
+
def locate_loop paths, &block
|
28
54
|
return paths unless block_given?
|
29
55
|
|
56
|
+
found = false
|
30
57
|
paths.each do |path|
|
31
58
|
Dir.chdir File.dirname(path) do
|
32
|
-
Hem::Logging.logger.debug "helper.locator: Found #{path}
|
59
|
+
Hem::Logging.logger.debug "helper.locator: Found #{path}"
|
33
60
|
yield File.basename(path), path
|
34
61
|
end
|
35
62
|
|
data/lib/hem/helper/shell.rb
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
module Hem
|
2
2
|
module Helper
|
3
3
|
def vm_shell command, opts = {}
|
4
|
-
Hem.ui.warning "Using vm_shell is deprecated and will be removed in a future release. Please use
|
4
|
+
Hem.ui.warning "Using vm_shell is deprecated and will be removed in a future release. Please use run instead"
|
5
5
|
opts['run_environment'] = 'vm'
|
6
|
-
|
6
|
+
run command, opts
|
7
7
|
end
|
8
8
|
|
9
9
|
def vm_mysql opts = {}
|
@@ -2,14 +2,13 @@ module Hem
|
|
2
2
|
module Lib
|
3
3
|
module HostCheck
|
4
4
|
def vagrant_version opts
|
5
|
-
require 'semantic'
|
6
5
|
begin
|
7
6
|
return unless get_run_environment == 'vm'
|
8
7
|
|
9
8
|
version = shell "vagrant --version", :capture => true
|
10
9
|
version.gsub!(/^Vagrant[^0-9]+/, '')
|
11
|
-
version = ::
|
12
|
-
minimum_version = ::
|
10
|
+
version = Gem::Version.new(version.strip)
|
11
|
+
minimum_version = Gem::Version.new("1.3.5")
|
13
12
|
|
14
13
|
advice = <<-EOF
|
15
14
|
The version of vagrant which you are using (#{version}) is less than the minimum required (#{minimum_version}).
|
data/lib/hem/lib/s3/sync.rb
CHANGED
@@ -101,11 +101,11 @@ module Hem
|
|
101
101
|
# We allow this one to be skipped as there are obviously no assets to sync
|
102
102
|
rescue Aws::S3::Errors::AccessDenied
|
103
103
|
Hem.ui.error " Your AWS key does not have access to the #{Hem.project_config.asset_bucket} S3 bucket!"
|
104
|
-
Hem.ui.error " Please request access to this bucket from your
|
104
|
+
Hem.ui.error " Please request access to this bucket from your Amazon AWS account administrators"
|
105
105
|
raise exception
|
106
106
|
rescue Aws::Errors::MissingCredentialsError
|
107
107
|
Hem.ui.warning " AWS credentials not set!"
|
108
|
-
Hem.ui.warning " Please request credentials from
|
108
|
+
Hem.ui.warning " Please request credentials from your Amazon AWS account administrators and configure them with `hem config`"
|
109
109
|
raise exception
|
110
110
|
end
|
111
111
|
end
|
data/lib/hem/lib/seed/project.rb
CHANGED
@@ -6,8 +6,8 @@ module Hem
|
|
6
6
|
@opts = {
|
7
7
|
:replacer => Replacer.new,
|
8
8
|
:config_class => Hem::Config::File,
|
9
|
-
:ssl_cert_generator => Hem::Lib::SelfSignedCertGenerator
|
10
9
|
}.merge! opts
|
10
|
+
@replace_done = false
|
11
11
|
end
|
12
12
|
|
13
13
|
def setup seed, config
|
@@ -17,27 +17,24 @@ module Hem
|
|
17
17
|
seed.export project_path, config
|
18
18
|
|
19
19
|
Dir.chdir(project_path) do
|
20
|
-
Hem.detect_project_type project_path
|
21
|
-
@opts[:project_config_file] = Hem.project_config_file
|
22
|
-
|
23
20
|
config[:seed][:version] = seed.version
|
24
21
|
config[:hostname] = "#{config[:name]}.dev"
|
25
22
|
config[:asset_bucket] = "inviqa-assets-#{config[:name]}"
|
26
23
|
config[:vm] = {
|
27
24
|
:project_mount_path => "/vagrant"
|
28
25
|
}
|
29
|
-
config[:
|
30
|
-
config[:chef_ssl] = {}
|
31
|
-
config[:ssl].each do |k, v|
|
32
|
-
config[:chef_ssl][k] = v.gsub("\n", "\\n")
|
33
|
-
end
|
26
|
+
config[:tmp] = {}
|
34
27
|
|
35
|
-
|
28
|
+
Hem.project_path = project_path
|
36
29
|
load_seed_init(config)
|
37
30
|
|
31
|
+
@opts[:replacer].replace(config[:project_path], Hem.project_config)
|
32
|
+
|
38
33
|
config.delete :project_path
|
39
|
-
config.delete :
|
40
|
-
|
34
|
+
config.delete :tmp
|
35
|
+
|
36
|
+
Hem.detect_project_type project_path
|
37
|
+
@opts[:project_config_file] = Hem.project_config_file
|
41
38
|
@opts[:config_class].save @opts[:project_config_file], config
|
42
39
|
end
|
43
40
|
|
@@ -50,7 +47,7 @@ module Hem
|
|
50
47
|
Hem.project_config = DeepStruct.wrap(config)
|
51
48
|
seed_init_file = File.join(config[:project_path], 'seedinit.rb')
|
52
49
|
if File.exists?(seed_init_file)
|
53
|
-
|
50
|
+
instance_eval File.read(seed_init_file), seed_init_file
|
54
51
|
File.unlink(seed_init_file)
|
55
52
|
end
|
56
53
|
end
|
@@ -2,14 +2,9 @@ module Hem
|
|
2
2
|
module Lib
|
3
3
|
module Seed
|
4
4
|
class Replacer
|
5
|
-
# Matching files/directories to be excluded from replacements
|
6
|
-
EXCLUDES = ["\\.git/", "^./bin", "^./lib", "^./spec"]
|
7
|
-
|
8
5
|
def replace(path, tokens)
|
9
|
-
|
10
|
-
|
11
|
-
elsif !tokens.instance_of? Array
|
12
|
-
raise "Invalid token list (expected Array or Hash)"
|
6
|
+
unless !tokens.instance_of?(Hash)
|
7
|
+
raise "Invalid token list (expected Hash)"
|
13
8
|
end
|
14
9
|
|
15
10
|
return search_replace(path, tokens)
|
@@ -18,36 +13,19 @@ module Hem
|
|
18
13
|
private
|
19
14
|
|
20
15
|
def search_replace(path, tokens, &block)
|
21
|
-
require '
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
Find.prune if candidate =~ excludes # Skip excluded
|
16
|
+
require 'erb'
|
17
|
+
|
18
|
+
template = Template.new(tokens)
|
19
|
+
Hem::Helper.locate('*.erb', nil, path: path, type: 'files').each do |candidate|
|
26
20
|
next unless FileTest.file? candidate # Skip unless file
|
27
21
|
|
28
22
|
content = File.read(candidate)
|
29
23
|
next unless content.force_encoding("UTF-8").valid_encoding? # Skip unless file can be valid UTF-8
|
30
24
|
|
31
|
-
|
32
|
-
tokens.each do |token, replacement|
|
33
|
-
token = "{{#{token.join('.')}}}"
|
34
|
-
match = content.match(token)
|
35
|
-
if match
|
36
|
-
content.gsub!(token, replacement)
|
37
|
-
files.push(candidate)
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
File.write(candidate, content) if files.include? candidate
|
42
|
-
end
|
43
|
-
return files.uniq
|
44
|
-
end
|
25
|
+
content = template.render(content, candidate)
|
45
26
|
|
46
|
-
|
47
|
-
|
48
|
-
return {k => hash} unless hash.is_a?(Hash)
|
49
|
-
hash.inject({}) do |h, v|
|
50
|
-
h.merge! flat_hash(v[-1], k + [v[0]])
|
27
|
+
File.delete(candidate)
|
28
|
+
File.write(candidate.sub('.erb', ''), content)
|
51
29
|
end
|
52
30
|
end
|
53
31
|
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Hem
|
2
|
+
module Lib
|
3
|
+
module Seed
|
4
|
+
class Template
|
5
|
+
def initialize(config)
|
6
|
+
@config = config
|
7
|
+
end
|
8
|
+
|
9
|
+
def config
|
10
|
+
@config
|
11
|
+
end
|
12
|
+
|
13
|
+
def render(content, filename)
|
14
|
+
erb = ERB.new(content)
|
15
|
+
erb.filename = filename
|
16
|
+
erb.result binding
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
data/lib/hem/lib/vm/inspector.rb
CHANGED