hem 1.0.1.beta6 → 1.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.
- 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