lib/slugbuilder/builder.rb in slugbuilder-2.0.2 vs lib/slugbuilder/builder.rb in slugbuilder-3.0.0
- old
+ new
@@ -1,9 +1,10 @@
require 'securerandom'
require 'shellwords'
require 'yaml'
require 'fileutils'
+require 'open3'
module Slugbuilder
class Builder
def initialize(repo:, git_ref:, stdout: $stdout)
@stdout = stdout
@@ -31,11 +32,11 @@
# clear environment from previous builds
FileUtils.rm_rf(@env_dir)
FileUtils.mkdir_p(@env_dir)
@buildpacks = buildpacks
- @env = env
+ @env = env.map { |k, v| [k.to_s, v.to_s] }.to_h
@slug_file = slug_name ? "#{slug_name}.tgz" : Shellwords.escape("#{@repo.gsub('/', '.')}.#{@git_ref}.#{@git_sha}.tgz")
wipe_cache if clear_cache
prebuild.call(repo: @repo, git_ref: @git_ref, git_url: @git_url) if prebuild
@@ -59,11 +60,11 @@
if block_given?
yield(repo: @repo, git_ref: @git_ref, git_sha: @git_sha, git_url: @git_url, request_id: @request_id, stats: stats, slug: File.join(@output_dir, @slug_file))
end
return true
rescue => e
- stitle("Failed: #{e}\n#{e.backtrace.join("\n")}")
+ stitle("Failed: #{e}\n")
return false
ensure
restore_env
end
@@ -118,11 +119,11 @@
end
def set_environment
load_env_file("#{@cache_dir}/env")
load_env_file("#{@build_dir}/.env")
- ENV['STACK'] = 'cedar-14'
+ ENV['STACK'] = Slugbuilder.config.heroku_stack
@request_id = SecureRandom.urlsafe_base64(32)
ENV['REQUEST_ID'] = @request_id
ENV['SOURCE_VERSION'] = @git_sha
# write user envs to files
@@ -130,11 +131,11 @@
ENV['HOME'] = @build_dir
ENV['APP_DIR'] = @build_dir
stitle('Build environment')
- ENV.each do |k, v|
+ ENV.to_h.merge(@env).each do |k, v|
stext("#{k}=#{v}")
end
end
def create_dirs
@@ -210,12 +211,12 @@
def run_hook(hook_name)
Dir.chdir(@build_dir) do
script = "#{@build_dir}/bin/#{hook_name}"
if File.exists?(script)
- rc = run(script)
- fail "Failed to run #{script}" if rc != 0
+ rc, errs = run_echo(script)
+ fail "#{errs.join('\n')}\nFailed to run #{script}" if rc != 0
end
end
end
def run_buildpacks(buildpacks)
@@ -235,12 +236,12 @@
end
end
def compile(buildpack)
- rc = run_echo("#{buildpack}/bin/compile '#{@build_dir}' '#{@cache_dir}' '#{@env_dir}'")
- fail "Couldn't compile application using buildpack #{buildpack}" if rc != 0
+ rc, errs = run_echo("#{buildpack}/bin/compile '#{@build_dir}' '#{@cache_dir}' '#{@env_dir}'")
+ fail "#{errs.join('\n')}\nCouldn't compile application using buildpack #{buildpack}" if rc != 0
end
def release(buildpack)
# should create .release
release_file = File.open("#{@build_dir}/.release", 'w')
@@ -252,18 +253,19 @@
fail "Couldn't release application using buildpack #{buildpack}" if rc != 0
end
def build_slug
rc = 1
+ errs = []
# use pigz if available
compression = `which pigz` != '' ? '--use-compress-program=pigz' : ''
if File.exists?("#{@build_dir}/.slugignore")
- rc = run_echo("tar --exclude='.git' #{compression} -X #{@build_dir}/.slugignore -C #{@build_dir} -cf #{File.join(@output_dir, @slug_file)} .")
+ rc, errs = run_echo("tar --exclude='.git' #{compression} -X #{@build_dir}/.slugignore -C #{@build_dir} -cf #{File.join(@output_dir, @slug_file)} .")
else
- rc = run_echo("tar --exclude='.git' #{compression} -C #{@build_dir} -cf #{File.join(@output_dir, @slug_file)} .")
+ rc, errs = run_echo("tar --exclude='.git' #{compression} -C #{@build_dir} -cf #{File.join(@output_dir, @slug_file)} .")
end
- fail "Couldn't create slugfile" if rc != 0
+ fail "#{errs.join('\n')}\nCouldn't create slugfile" if rc != 0
end
def slug_size
@slug_size = File.size(File.join(@output_dir, @slug_file)) / 1024 / 1024
stitle("Slug size is #{@slug_size} Megabytes.")
@@ -327,23 +329,27 @@
yield
((Time.now - t0).to_i * 100) / 100.0
end
def run(cmd)
- IO.popen(cmd) do |io|
- until io.eof?
- data = io.gets
- yield data if block_given?
+ Open3.popen3(cmd) do |stdin, stdout, stderr, thread|
+ until stdout.eof? && stderr.eof?
+ out = stdout.gets
+ err = stderr.gets
+ yield(out, err) if block_given?
end
+ thread.value.exitstatus
end
- $?.exitstatus
end
def run_echo(cmd)
- run(cmd) do |line|
- build_output << line
- @stdout.print(line)
+ errors = []
+ status = run(cmd) do |stdout, stderr|
+ build_output << stdout if stdout
+ errors << stderr if stderr
+ @stdout.print(stdout)
end
+ [status, errors]
end
def load_export_env(file)
if File.exists?(file)
exports = IO.read(file).split('export')