class Cutlass::PackBuild

Build an image with `pack` and cloud native buildpacks

begin
  build = PackBuild.new(app_dir: dir, buildpacks: ["heroku/ruby"], builder: "heroku/buildpacks:18")
  build.call

  build.stdout # => "...Successfully built image"
  build.success? # => true
ensure
  build.teardown
end

Attributes

app_dir[R]
builder[R]
buildpacks[R]
config[R]
env_arguments[R]
exception_on_failure[R]
image_name[R]

Public Class Methods

new( app_dir:, config: {}, builder: nil, buildpacks: [], image_name: Cutlass.default_image_name, exception_on_failure: true ) click to toggle source
# File lib/cutlass/pack_build.rb, line 23
def initialize(
  app_dir:,
  config: {},
  builder: nil,
  buildpacks: [],
  image_name: Cutlass.default_image_name,
  exception_on_failure: true
)
  @app_dir = app_dir
  @builder = builder
  @image_name = image_name
  @env_arguments = config.map { |key, value| "--env #{key}=#{value}" }.join(" ")
  @exception_on_failure = exception_on_failure
  @image = nil
  @result = nil

  @buildpacks = Array(buildpacks).map do |buildpack|
    if buildpack.respond_to?(:name)
      buildpack.name
    else
      buildpack
    end
  end
end

Public Instance Methods

builder_arg() click to toggle source
# File lib/cutlass/pack_build.rb, line 110
def builder_arg
  "-B #{builder}" if builder
end
call() click to toggle source
# File lib/cutlass/pack_build.rb, line 71
def call
  puts pack_command if Cutlass.debug?
  call_pack

  puts @result.stdout if Cutlass.debug?
  puts @result.stderr if Cutlass.debug?
  self
end
failed?() click to toggle source
# File lib/cutlass/pack_build.rb, line 80
def failed?
  !success?
end
image_id() click to toggle source
# File lib/cutlass/pack_build.rb, line 48
def image_id
  raise "No image ID, container was not successfully built, #{error_message}" if @image.nil?
  @image.id
end
pack_command() click to toggle source
# File lib/cutlass/pack_build.rb, line 114
def pack_command
  "pack build #{image_name} --path #{app_dir} #{builder_arg} --buildpack #{buildpacks.join(",")} #{env_arguments} #{"-v" if Cutlass.debug?}"
end
result() click to toggle source
# File lib/cutlass/pack_build.rb, line 53
def result
  raise "Must execute method `call` first" unless @result

  @result
end
stderr() click to toggle source
# File lib/cutlass/pack_build.rb, line 67
def stderr
  result.stderr
end
stdout() click to toggle source
# File lib/cutlass/pack_build.rb, line 63
def stdout
  result.stdout
end
success?() click to toggle source
# File lib/cutlass/pack_build.rb, line 84
def success?
  result.success?
end
teardown() click to toggle source
# File lib/cutlass/pack_build.rb, line 59
def teardown
  @image&.remove(force: true)
end

Private Instance Methods

call_pack() click to toggle source
# File lib/cutlass/pack_build.rb, line 88
        def call_pack
  @result = BashResult.run(pack_command)

  if @result.success?
    @image = Docker::Image.get(image_name)
  else
    @image = nil

    raise error_message if exception_on_failure
  end
end
error_message() click to toggle source
# File lib/cutlass/pack_build.rb, line 100
            def error_message
      <<~EOM
        Pack exited with status code #{@result.status}, indicating a build failed

        command: #{pack_command}
        stdout: #{stdout}
        stderr: #{stderr}
      EOM
    end