hem 1.0.1.beta1
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 +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
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
desc "Dependency related tasks"
|
|
2
|
+
hidden true
|
|
3
|
+
namespace :deps do
|
|
4
|
+
|
|
5
|
+
desc "Install Gem dependencies"
|
|
6
|
+
task :gems do
|
|
7
|
+
locate "*Gemfile" do
|
|
8
|
+
required = shell("bundle", "check", :exit_status => true) != 0
|
|
9
|
+
if required
|
|
10
|
+
Hem.ui.title "Installing Gem dependencies"
|
|
11
|
+
shell "bundle", "install", realtime: true, indent: 2
|
|
12
|
+
Hem.ui.separator
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
desc "Install composer dependencies"
|
|
18
|
+
task :composer do
|
|
19
|
+
if File.exists? File.join(Hem.project_path, "composer.json")
|
|
20
|
+
Rake::Task["tools:composer"].invoke
|
|
21
|
+
Hem.ui.title "Installing composer dependencies"
|
|
22
|
+
Dir.chdir Hem.project_path do
|
|
23
|
+
ansi = Hem.ui.supports_color? ? '--ansi' : ''
|
|
24
|
+
args = [ "php bin/composer.phar install #{ansi} --prefer-dist", { realtime: true, indent: 2 } ]
|
|
25
|
+
complete = false
|
|
26
|
+
|
|
27
|
+
unless maybe(Hem.project_config.tasks.deps.composer.disable_host_run)
|
|
28
|
+
check = Hem::Lib::HostCheck.check(:filter => /php_present/)
|
|
29
|
+
|
|
30
|
+
if check[:php_present] == :ok
|
|
31
|
+
begin
|
|
32
|
+
shell *args
|
|
33
|
+
complete = true
|
|
34
|
+
rescue Hem::ExternalCommandError
|
|
35
|
+
Hem.ui.warning "Installing composer dependencies locally failed!"
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
if !complete
|
|
41
|
+
vm_shell *args
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
Hem.ui.success "Composer dependencies installed"
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
Hem.ui.separator
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
desc "Install vagrant plugins"
|
|
52
|
+
task :vagrant_plugins => [ "deps:gems" ] do
|
|
53
|
+
plugins = shell "vagrant plugin list", :capture => true
|
|
54
|
+
locate "*Vagrantfile" do
|
|
55
|
+
to_install = []
|
|
56
|
+
File.read("Vagrantfile").split("\n").each do |line|
|
|
57
|
+
if line.match /#\s*Hem.vagrant_plugin (.*)/ or line.match /#\s*Hobo.vagrant_plugin (.*)/
|
|
58
|
+
to_install << $1
|
|
59
|
+
else
|
|
60
|
+
next if line.match /^\s*#/
|
|
61
|
+
next unless line.match /Vagrant\.require_plugin (.*)/
|
|
62
|
+
to_install << $1
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
to_install.each do |plugin|
|
|
67
|
+
plugin.gsub!(/['"]*/, '')
|
|
68
|
+
next if plugins.include? "#{plugin} "
|
|
69
|
+
Hem.ui.title "Installing vagrant plugin: #{plugin}"
|
|
70
|
+
shell "vagrant", "plugin", "install", plugin, :realtime => true, :indent => 2
|
|
71
|
+
Hem.ui.separator
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
desc "Install chef dependencies"
|
|
77
|
+
task :chef => [ "deps:gems" ] do
|
|
78
|
+
locate "*Cheffile" do
|
|
79
|
+
Hem.ui.title "Installing chef dependencies via librarian"
|
|
80
|
+
bundle_shell "librarian-chef", "install", "--verbose", :realtime => true, :indent => 2 do |line|
|
|
81
|
+
line =~ /Installing.*</ ? line.strip + "\n" : nil
|
|
82
|
+
end
|
|
83
|
+
Hem.ui.separator
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
locate "*Berksfile" do
|
|
87
|
+
Hem.ui.title "Installing chef dependencies via berkshelf"
|
|
88
|
+
executor = (shell("bash -c 'which berks'", :capture => true).strip =~ /chefdk/) ?
|
|
89
|
+
lambda { |*args| shell *args } :
|
|
90
|
+
lambda { |*args| bundle_shell *args }
|
|
91
|
+
|
|
92
|
+
executor.call "berks", "install", :realtime => true, :indent => 2
|
|
93
|
+
version = executor.call "berks", "-v", :capture => true
|
|
94
|
+
if version =~ /^[3-9]/
|
|
95
|
+
shell "rm -rf cookbooks"
|
|
96
|
+
executor.call "berks", "vendor", "cookbooks"
|
|
97
|
+
else
|
|
98
|
+
executor.call "berks", "install", "--path", "cookbooks"
|
|
99
|
+
end
|
|
100
|
+
Hem.ui.separator
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
end
|
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
namespace :tools do
|
|
2
|
+
desc "Fetches the n98-magerun utility"
|
|
3
|
+
task :n98magerun do
|
|
4
|
+
FileUtils.mkdir_p "bin"
|
|
5
|
+
vm_shell '"wget" --no-check-certificate "https://raw.github.com/netz98/n98-magerun/master/n98-magerun.phar" -O bin/n98-magerun.phar'
|
|
6
|
+
FileUtils.chmod 0755, "bin/n98-magerun.phar"
|
|
7
|
+
end
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
desc "Magento related tasks"
|
|
11
|
+
namespace :magento do
|
|
12
|
+
|
|
13
|
+
desc "Patch tasks"
|
|
14
|
+
namespace :patches do
|
|
15
|
+
def magento_path
|
|
16
|
+
unless @magento_path
|
|
17
|
+
files = locate('*app/Mage.php')
|
|
18
|
+
unless files.length > 0
|
|
19
|
+
raise Hem::UserError.new "Could not find app/Mage.php in the git repository, this command should only be run for Magento projects"
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
/(?:(.*)\/)app\/Mage\.php/.match(files[0])
|
|
23
|
+
@magento_path = $1
|
|
24
|
+
end
|
|
25
|
+
@magento_path
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def detect_clean
|
|
29
|
+
status = shell('git status -z', :capture => true, :strip => false)
|
|
30
|
+
status.split("\u0000").each do |line|
|
|
31
|
+
match = line.match(/^([\s\S]{2})\s+(.*)$/)
|
|
32
|
+
next if match.nil?
|
|
33
|
+
|
|
34
|
+
if ![' ', '?'].include?($1[0]) || $2.start_with?(magento_path)
|
|
35
|
+
raise Hem::UserError.new "Please remove all files from the git index, and stash all changes in '#{magento_path}' before continuing"
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def detect_version
|
|
41
|
+
config_dirty = false
|
|
42
|
+
magento_version_file = "#{magento_path}/app/Mage.php"
|
|
43
|
+
|
|
44
|
+
if Hem.project_config[:magento_edition].nil?
|
|
45
|
+
magento_edition = nil
|
|
46
|
+
if magento_version_file
|
|
47
|
+
args = [ "php -r \"require '#{magento_version_file}'; echo Mage::getEdition();\""]
|
|
48
|
+
|
|
49
|
+
magento_edition = vm_shell(*args, :capture => true).to_s.downcase
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
edition_options = ['community', 'enterprise', 'professional', 'go']
|
|
53
|
+
|
|
54
|
+
unless edition_options.include? magento_edition
|
|
55
|
+
raise Hem::Error.new "Invalid Magento edition '#{magento_edition}' was found when calling Mage::getEdition(), skipping patches"
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
Hem.project_config[:magento_edition] = magento_edition
|
|
59
|
+
config_dirty = true
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
if Hem.project_config[:magento_version].nil?
|
|
63
|
+
magento_version = nil
|
|
64
|
+
if magento_version_file
|
|
65
|
+
args = [ "php -r \"require '#{magento_version_file}'; echo Mage::getVersion();\""]
|
|
66
|
+
|
|
67
|
+
magento_version = vm_shell(*args, :capture => true)
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
version_regex = /^\d+(\.\d+){3}$/
|
|
71
|
+
|
|
72
|
+
unless version_regex.match(magento_version)
|
|
73
|
+
raise Hem::Error.new "Invalid Magento version '#{magento_version}' was found when calling Mage::getVersion(), skipping patches"
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
Hem.project_config[:magento_version] = magento_version
|
|
77
|
+
config_dirty = true
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
if config_dirty
|
|
81
|
+
Hem::Config::File.save(Hem.project_config_file, Hem.project_config)
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def detect_tools
|
|
86
|
+
use_vm = shell("which which", :exit_status => true) != 0
|
|
87
|
+
|
|
88
|
+
tools = ['patch', 'sed']
|
|
89
|
+
tools_command = tools.map {|tool| "which #{tool}"}.join " && "
|
|
90
|
+
status = 0
|
|
91
|
+
|
|
92
|
+
unless use_vm
|
|
93
|
+
status = shell(tools_command, :exit_status => true)
|
|
94
|
+
use_vm = status != 0
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
if use_vm
|
|
98
|
+
status = vm_shell(tools_command, :exit_status => true)
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
if status != 0
|
|
102
|
+
raise Hem::UserError.new "Please make sure '#{tools.join(',')}' is installed on your host or VM before continuing"
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
use_vm
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
desc "Apply patches to Magento"
|
|
109
|
+
task "apply" do
|
|
110
|
+
detect_clean
|
|
111
|
+
detect_version
|
|
112
|
+
|
|
113
|
+
config = Hem.project_config
|
|
114
|
+
|
|
115
|
+
sync = Hem::Lib::S3::Sync.new(Hem.aws_credentials)
|
|
116
|
+
|
|
117
|
+
patches_path = "#{Hem.project_path}/tools/patches"
|
|
118
|
+
incoming_path = "#{patches_path}/incoming"
|
|
119
|
+
|
|
120
|
+
Hem.ui.success("Downloading Magento #{config[:magento_edition].capitalize} #{config[:magento_version]} patches")
|
|
121
|
+
changes = sync.sync(
|
|
122
|
+
"s3://inviqa-assets-magento/#{config[:magento_edition]}/patches/#{config[:magento_version]}/",
|
|
123
|
+
"#{incoming_path}/",
|
|
124
|
+
:delete => false
|
|
125
|
+
)
|
|
126
|
+
Hem.ui.separator
|
|
127
|
+
|
|
128
|
+
use_vm = false
|
|
129
|
+
use_vm = detect_tools if Dir.glob("#{incoming_path}/*.sh").length > 0
|
|
130
|
+
|
|
131
|
+
patch_files = Dir.glob("#{incoming_path}/*.{sh,patch,diff}")
|
|
132
|
+
|
|
133
|
+
Hem.ui.success("#{patch_files.length} new patches found")
|
|
134
|
+
|
|
135
|
+
Hem.ui.separator
|
|
136
|
+
|
|
137
|
+
patch_files.each do |file|
|
|
138
|
+
filename = File.basename(file)
|
|
139
|
+
base_filename = File.basename(filename, File.extname(filename))
|
|
140
|
+
|
|
141
|
+
if File.exist?("#{patches_path}/#{filename}")
|
|
142
|
+
Hem.ui.debug("Patch #{filename} has already been applied, so skipping it")
|
|
143
|
+
|
|
144
|
+
File.delete file
|
|
145
|
+
next
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
if File.exist?("#{patches_path}/#{base_filename}.skip")
|
|
149
|
+
File.delete file
|
|
150
|
+
next
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
Hem.ui.success("Applying patch #{filename}")
|
|
154
|
+
|
|
155
|
+
yaml_file = File.join(File.dirname(file), base_filename + ".yaml")
|
|
156
|
+
|
|
157
|
+
metadata = {
|
|
158
|
+
'commit_message' => "Apply Magento patch #{filename}"
|
|
159
|
+
}
|
|
160
|
+
if File.exist?(yaml_file)
|
|
161
|
+
metadata = Hem::Config::File.load(yaml_file)
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
Hem.ui.info(metadata['description']) unless metadata['description'].nil?
|
|
165
|
+
|
|
166
|
+
patch_options = %w( yes never skip )
|
|
167
|
+
answer = Hem.ui.ask_choice('Do you want to apply this patch?', patch_options)
|
|
168
|
+
|
|
169
|
+
if answer == 'skip'
|
|
170
|
+
next
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
if answer == 'never'
|
|
174
|
+
File.delete file
|
|
175
|
+
File.write("#{patches_path}/#{base_filename}.skip", '')
|
|
176
|
+
|
|
177
|
+
shell "git add '#{patches_path}/#{base_filename}.skip'"
|
|
178
|
+
shell "git commit -m 'Add a skip file for patch #{filename}'"
|
|
179
|
+
next
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
if /\.sh$/.match(file)
|
|
183
|
+
File.rename file, "#{magento_path}/#{filename}"
|
|
184
|
+
file = "#{magento_path}/#{filename}"
|
|
185
|
+
if use_vm
|
|
186
|
+
vm_shell "cd #{magento_path} && sh #{filename}", :realtime => true, :indent => 2
|
|
187
|
+
else
|
|
188
|
+
shell "cd #{magento_path} && sh #{filename}", :realtime => true, :indent => 2
|
|
189
|
+
end
|
|
190
|
+
else
|
|
191
|
+
shell "git apply --directory #{magento_path} #{file}"
|
|
192
|
+
end
|
|
193
|
+
File.rename file, "#{patches_path}/#{filename}"
|
|
194
|
+
shell "git add #{magento_path}"
|
|
195
|
+
shell "git add #{patches_path}/#{filename}"
|
|
196
|
+
|
|
197
|
+
if File.exist?(yaml_file)
|
|
198
|
+
yaml_filename = File.basename(yaml_file)
|
|
199
|
+
File.rename yaml_file, "#{patches_path}/#{yaml_filename}"
|
|
200
|
+
shell "git add #{patches_path}/#{yaml_filename}"
|
|
201
|
+
end
|
|
202
|
+
shell "git commit -m #{metadata['commit_message'].shellescape}"
|
|
203
|
+
|
|
204
|
+
Hem.ui.separator
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
Hem.ui.success("Finished applying #{patch_files.length} patches")
|
|
208
|
+
end
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
desc "Setup script tasks"
|
|
212
|
+
namespace :'setup-scripts' do
|
|
213
|
+
desc "Run magento setup scripts"
|
|
214
|
+
task :run => ['tools:n98magerun'] do
|
|
215
|
+
Hem.ui.success "Running setup scripts"
|
|
216
|
+
vm_shell("bin/n98-magerun.phar cache:clean config", :realtime => true, :indent => 2)
|
|
217
|
+
vm_shell("bin/n98-magerun.phar sys:setup:incremental -n", :realtime => true, :indent => 2)
|
|
218
|
+
Hem.ui.separator
|
|
219
|
+
end
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
desc "Cache tasks"
|
|
223
|
+
namespace :cache do
|
|
224
|
+
desc "Clear cache"
|
|
225
|
+
task :clear => ['tools:n98magerun'] do
|
|
226
|
+
Hem.ui.success "Clearing magento cache"
|
|
227
|
+
vm_shell("bin/n98-magerun.phar cache:flush", :realtime => true, :indent => 2)
|
|
228
|
+
Hem.ui.separator
|
|
229
|
+
end
|
|
230
|
+
end
|
|
231
|
+
|
|
232
|
+
desc "Configuration related tasks"
|
|
233
|
+
namespace :config do
|
|
234
|
+
desc "Configure magento base URLs"
|
|
235
|
+
task :'configure-urls' => ['tools:n98magerun'] do
|
|
236
|
+
Hem.ui.success "Configuring magento base urls"
|
|
237
|
+
domain = Hem.project_config.hostname
|
|
238
|
+
vm_shell("bin/n98-magerun.phar config:set web/unsecure/base_url 'http://#{domain}/'", :realtime => true, :indent => 2)
|
|
239
|
+
vm_shell("bin/n98-magerun.phar config:set web/secure/base_url 'https://#{domain}/'", :realtime => true, :indent => 2)
|
|
240
|
+
Hem.ui.separator
|
|
241
|
+
end
|
|
242
|
+
|
|
243
|
+
desc "Enable magento errors"
|
|
244
|
+
task :'enable-errors' do
|
|
245
|
+
error_config = File.join(Hem.project_path, 'public/errors/local.xml')
|
|
246
|
+
|
|
247
|
+
FileUtils.cp(
|
|
248
|
+
error_config + ".sample",
|
|
249
|
+
error_config
|
|
250
|
+
) unless File.exists? error_config
|
|
251
|
+
end
|
|
252
|
+
|
|
253
|
+
desc "Create admin user"
|
|
254
|
+
task :'create-admin-user' do
|
|
255
|
+
initialized = vm_shell("bin/n98-magerun.phar admin:user:list | grep admin", :exit_status => true) == 0
|
|
256
|
+
unless initialized
|
|
257
|
+
Hem.ui.success "Creating admin user"
|
|
258
|
+
vm_shell("bin/n98-magerun.phar admin:user:create admin '' admin admin admin", :realtime => true, :indent => 2)
|
|
259
|
+
Hem.ui.separator
|
|
260
|
+
end
|
|
261
|
+
end
|
|
262
|
+
|
|
263
|
+
desc "Enable rewrites"
|
|
264
|
+
task :'enable-rewrites' do
|
|
265
|
+
Hem.ui.success "Enabling rewrites"
|
|
266
|
+
vm_shell("bin/n98-magerun.phar config:set web/seo/use_rewrites 1", :realtime => true, :indent => 2)
|
|
267
|
+
Hem.ui.separator
|
|
268
|
+
end
|
|
269
|
+
end
|
|
270
|
+
|
|
271
|
+
desc "Initializes magento specifics on the virtual machine after a fresh build"
|
|
272
|
+
task :'initialize-vm' => [
|
|
273
|
+
'magento:config:enable-errors',
|
|
274
|
+
'tools:n98magerun',
|
|
275
|
+
'magento:setup-scripts:run',
|
|
276
|
+
'magento:config:configure-urls',
|
|
277
|
+
'magento:config:create-admin-user',
|
|
278
|
+
'magento:config:enable-rewrites',
|
|
279
|
+
'magento:cache:clear'
|
|
280
|
+
]
|
|
281
|
+
end
|
data/lib/hem/tasks/pr.rb
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
desc 'Perform pull request operations'
|
|
2
|
+
namespace :pr do
|
|
3
|
+
desc 'Create a new pull request'
|
|
4
|
+
task :create do
|
|
5
|
+
source_branch = Hem.ui.ask 'Source branch', default: (Hem::Helper.shell 'git rev-parse --abbrev-ref HEAD', :capture => true)
|
|
6
|
+
target_branch = Hem.ui.ask 'Target branch', default: 'develop'
|
|
7
|
+
|
|
8
|
+
pr_content = <<-prbody
|
|
9
|
+
# The line below this comment is the title of your pull request. Keep it short and on a single line.
|
|
10
|
+
PR_TITLE
|
|
11
|
+
|
|
12
|
+
# All text below this comment will appear as the body of the pull request.
|
|
13
|
+
# If your project has a DoD.md in the project root, it will be automatically included.
|
|
14
|
+
# Any line starting with a hash (comment) will be ignored
|
|
15
|
+
|
|
16
|
+
PR_DOD
|
|
17
|
+
prbody
|
|
18
|
+
|
|
19
|
+
pr_content['PR_TITLE'] = Hem::Helper.shell 'git log -1 --pretty=%B', :capture => true
|
|
20
|
+
|
|
21
|
+
dod_path = Hem::Helper.locate('DoD.md')
|
|
22
|
+
|
|
23
|
+
if dod_path && !dod_path.empty?
|
|
24
|
+
dod_file = File.open dod_path[0]
|
|
25
|
+
pr_content['PR_DOD'] = dod_file.read
|
|
26
|
+
dod_file.close
|
|
27
|
+
else
|
|
28
|
+
pr_content['PR_DOD'] = '# No DoD.md file found, add one to your project root.'
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
pr_body = Hem.ui.editor(pr_content).lines.reject{ |line| line[0] == '#' }.join
|
|
32
|
+
|
|
33
|
+
pr_title = pr_body.lines.to_a[0]
|
|
34
|
+
|
|
35
|
+
pr_body = pr_body.lines.to_a[1..-1].join
|
|
36
|
+
|
|
37
|
+
git_parts = Hem::Helper.parse_github_url(Hem.project_config.git_url)
|
|
38
|
+
repo = "#{git_parts[:owner]}/#{git_parts[:repo]}"
|
|
39
|
+
|
|
40
|
+
api = Hem::Lib::Github::Api.new
|
|
41
|
+
pr_url = api.create_pull_request(repo, target_branch, source_branch, pr_title, pr_body)
|
|
42
|
+
|
|
43
|
+
Hem::ui.success "Pull request created: #{pr_url}"
|
|
44
|
+
end
|
|
45
|
+
end
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
|
|
2
|
+
desc "Project seed commands"
|
|
3
|
+
namespace :seed do
|
|
4
|
+
|
|
5
|
+
desc "Create a new project from a seed repository"
|
|
6
|
+
|
|
7
|
+
option '-g=', '--git-url=', 'Git repository for project'
|
|
8
|
+
option '-s=', '--seed=', 'Seed name or URL to use'
|
|
9
|
+
option '-b=', '--branch=', 'Seed branch to use'
|
|
10
|
+
option '-d=', '--data=', 'Seed data to save to the project hem configuration', :as => Hash
|
|
11
|
+
|
|
12
|
+
task :plant, [ :name ] do |t, args|
|
|
13
|
+
name = args[:name]
|
|
14
|
+
|
|
15
|
+
Hem.project_path = File.join(Dir.pwd, name)
|
|
16
|
+
|
|
17
|
+
raise Hem::UserError.new "Name must match sprint zero guidelines" unless name.match /[a-z0-9\-]+/
|
|
18
|
+
raise Hem::UserError.new "#{Hem.project_path} already exists!" if File.exists? Hem.project_path
|
|
19
|
+
|
|
20
|
+
config = {
|
|
21
|
+
:name => name,
|
|
22
|
+
:project_path => Hem.project_path,
|
|
23
|
+
:git_url => t.opts[:'git-url'] || Hem.ui.ask("Repository URL", default: "git@github.com:inviqa/#{name}"),
|
|
24
|
+
:ref => t.opts[:branch] || 'master'
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
seed_options = %w( default magento symfony custom )
|
|
28
|
+
|
|
29
|
+
seed_name = t.opts[:seed] || Hem.ui.ask_choice('Project seed', seed_options, default: 'default')
|
|
30
|
+
use_short_seed_name = true
|
|
31
|
+
|
|
32
|
+
if seed_name == 'custom'
|
|
33
|
+
seed_name = Hem.ui.ask('Please enter a git url or a path to a local git checkout containing the seed')
|
|
34
|
+
use_short_seed_name = false
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
config[:seed] = {
|
|
38
|
+
:name => File.basename(seed_name, '.git'),
|
|
39
|
+
:url => Hem::Lib::Seed::Seed.name_to_url(seed_name, :use_short_seed_name => use_short_seed_name)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
unless t.opts[:data].nil?
|
|
43
|
+
data = t.opts[:data].inject({}){|hash,(k,v)| hash[k.to_sym] = v; hash}
|
|
44
|
+
config.merge!(data)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
seed = Hem::Lib::Seed::Seed.new(
|
|
48
|
+
File.join(Hem.seed_cache_path, config[:seed][:name]),
|
|
49
|
+
config[:seed][:url]
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
config[:vm_ip] = seed.vm_ip
|
|
53
|
+
|
|
54
|
+
Hem::Lib::Seed::Project.new().setup(seed, config)
|
|
55
|
+
|
|
56
|
+
Hem.ui.separator
|
|
57
|
+
Hem.ui.success "Your new project is available in #{Hem.project_path}."
|
|
58
|
+
Hem.ui.success "You will need to review the initial commit and if all is well, push the repository to github using `git push origin --all`."
|
|
59
|
+
Hem.ui.separator
|
|
60
|
+
end
|
|
61
|
+
end
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
desc "Internal hem debugging tools"
|
|
2
|
+
hidden true
|
|
3
|
+
namespace 'self' do
|
|
4
|
+
|
|
5
|
+
desc "REPL"
|
|
6
|
+
task :repl do
|
|
7
|
+
require 'pry'
|
|
8
|
+
Pry.config.prompt = if STDIN.tty?
|
|
9
|
+
proc { 'hem > '}
|
|
10
|
+
else
|
|
11
|
+
proc { '' }
|
|
12
|
+
end
|
|
13
|
+
pry
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
desc "Tasks for debugging hem"
|
|
17
|
+
namespace 'debug' do
|
|
18
|
+
desc "Display project paths"
|
|
19
|
+
project_only
|
|
20
|
+
task "paths" do
|
|
21
|
+
Hem.ui.info "<%=color('Project path:', :green)%> " + Hem.project_path
|
|
22
|
+
{
|
|
23
|
+
:gemfile => "*Gemfile",
|
|
24
|
+
:vagrantfile => "*Vagrantfile",
|
|
25
|
+
:cheffile => "*Cheffile",
|
|
26
|
+
:berksfile => "*Berksfile",
|
|
27
|
+
:'composer.json' => "composer.json"
|
|
28
|
+
}.each do |k,v|
|
|
29
|
+
path = nil
|
|
30
|
+
locate v do |file, full_file|
|
|
31
|
+
path = full_file
|
|
32
|
+
end
|
|
33
|
+
Hem.ui.info "<%=color('#{k.to_s}:', :green) %> #{path.nil? ? "none" : path}"
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
desc "Locate"
|
|
38
|
+
project_only
|
|
39
|
+
task "locate", [ :arg ] do |task, args|
|
|
40
|
+
locate args[:arg] do |file, full_file|
|
|
41
|
+
puts full_file
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
namespace 'shell-init' do
|
|
2
|
+
def posix_export_path
|
|
3
|
+
Hem.ui.output %Q(export PATH="#{ENV['PATH']}")
|
|
4
|
+
end
|
|
5
|
+
|
|
6
|
+
def fish_export_path
|
|
7
|
+
Hem.ui.output %Q(set -gx PATH "#{ENV['PATH'].split(':').join('" "')}" 2>/dev/null;)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
task 'bash' do
|
|
11
|
+
posix_export_path
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
task 'sh' do
|
|
15
|
+
posix_export_path
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
task 'zsh' do
|
|
19
|
+
posix_export_path
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
task 'fish' do
|
|
23
|
+
fish_export_path
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
desc "System configuration related commands"
|
|
2
|
+
namespace :system do
|
|
3
|
+
|
|
4
|
+
desc "Shell completion related commands"
|
|
5
|
+
namespace :completions do
|
|
6
|
+
|
|
7
|
+
desc "Install shell completion helpers"
|
|
8
|
+
option '-f', '--fish', 'Install completions for FISH'
|
|
9
|
+
option '-b', '--bash', 'Install completions for Bash'
|
|
10
|
+
option '-z', '--zsh', 'Install completions for ZSH'
|
|
11
|
+
task "install" do |task|
|
|
12
|
+
if task.opts[:fish]
|
|
13
|
+
script = <<-EOF
|
|
14
|
+
function __hem_completion -d "Create hem completions"
|
|
15
|
+
set -l cache_dir "/tmp/fish_hem_completion_cache"
|
|
16
|
+
mkdir -p $cache_dir
|
|
17
|
+
set -l hashed_pwd (ruby -r 'digest' -e 'puts Digest::MD5.hexdigest(`pwd`)')
|
|
18
|
+
set -l hem_cache_file "$cache_dir/$hashed_pwd"
|
|
19
|
+
|
|
20
|
+
if not test -f "$hem_cache_file"
|
|
21
|
+
hem system completions fish --skip-host-checks > "$hem_cache_file"
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
cat "$hem_cache_file"
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
function __hem_scope_test -d "Hem scoped completion test"
|
|
28
|
+
set cmd (commandline -opc)
|
|
29
|
+
if [ "$cmd" = "$argv" ]
|
|
30
|
+
return 0
|
|
31
|
+
end
|
|
32
|
+
return 1
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
eval (__hem_completion)
|
|
36
|
+
EOF
|
|
37
|
+
target = File.join(ENV['HOME'], '.config/fish/completions/hem.fish')
|
|
38
|
+
FileUtils.mkdir_p(File.dirname(target))
|
|
39
|
+
File.write(target, script)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
if task.opts[:bash]
|
|
43
|
+
raise "Bash completions not yet implemented"
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
if task.opts[:zsh]
|
|
47
|
+
raise "ZSH completions not yet implemented"
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
desc "Display FISH shell completion commands"
|
|
52
|
+
task :fish do
|
|
53
|
+
Hem.cli.slop.options.each do |option|
|
|
54
|
+
short = option.short.nil? ? '' : "-s #{option.short}"
|
|
55
|
+
long = option.long.nil? ? '' : "-l #{option.long}"
|
|
56
|
+
arg = option.config[:argument] ? '' : '-x'
|
|
57
|
+
puts "complete #{arg} -c hem #{short} #{long} --description '#{option.description}';"
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
map = Hem.cli.help_formatter.command_map
|
|
61
|
+
map.each do |k, v|
|
|
62
|
+
next if v.description.nil? || v.description.empty?
|
|
63
|
+
k = k.split(':')
|
|
64
|
+
k.unshift 'hem'
|
|
65
|
+
c = k.pop
|
|
66
|
+
puts "complete -x -c hem -n '__hem_scope_test #{k.join(' ')}' -a #{c} --description '#{v.description}';"
|
|
67
|
+
v.options.each do |option|
|
|
68
|
+
short = option.short.nil? ? '' : "-s #{option.short}"
|
|
69
|
+
long = option.long.nil? ? '' : "-l #{option.long}"
|
|
70
|
+
arg = option.config[:argument] ? '' : '-x'
|
|
71
|
+
puts "complete #{arg} -c hem -n '__hem_scope_test #{k.concat([c]).join(' ')}' #{short} #{long} --description '#{option.description}';"
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
desc "System configuration related commands"
|
|
2
|
+
namespace :system do
|
|
3
|
+
|
|
4
|
+
desc "Check system configuration for potential problems"
|
|
5
|
+
task :check do
|
|
6
|
+
Hem::Lib::HostCheck.check.each do |k,v|
|
|
7
|
+
name = k.to_s.gsub('_', ' ')
|
|
8
|
+
name[0] = name[0].upcase
|
|
9
|
+
|
|
10
|
+
if v == :ok
|
|
11
|
+
Hem.ui.success "#{name}: OK"
|
|
12
|
+
else
|
|
13
|
+
Hem.ui.error "#{name}: FAILED\n"
|
|
14
|
+
Hem.ui.warning v.advice.gsub(/^/, ' ')
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
desc "Tasks to retrieve common tools"
|
|
2
|
+
hidden
|
|
3
|
+
namespace :tools do
|
|
4
|
+
|
|
5
|
+
desc "Fetch composer"
|
|
6
|
+
task :composer do
|
|
7
|
+
bin_file = File.join(Hem.project_bin_path, "composer.phar")
|
|
8
|
+
unless File.exists?(bin_file)
|
|
9
|
+
Hem.ui.success "Getting composer"
|
|
10
|
+
FileUtils.mkdir_p File.dirname(bin_file)
|
|
11
|
+
vm_shell "cd bin && php -r \"readfile('https://getcomposer.org/installer');\" | php", :realtime => true, :indent => 2
|
|
12
|
+
else
|
|
13
|
+
Hem.ui.success "Composer already available in bin/composer.phar"
|
|
14
|
+
end
|
|
15
|
+
Hem.ui.separator
|
|
16
|
+
end
|
|
17
|
+
end
|