# frozen_string_literal: true
require 'pathname'
require 'json'
# Cartage, a package builder.
class Cartage
# Generate and mount the full metadata reporter, Cartage::Rack.
def self.Rack(root_path = nil, &filter)
Cartage::Rack.send(:new, root_path, &filter)
end
# Cartage::Rack is a simple application that reads an application's static
# release metadata and returns it as an (optionally filtered)
# +application/json+ value, or as a +text/plain+ string if called with
# +.text+ or +.txt+.
class Rack
VERSION = '2.2' #:nodoc:
class << self
# When +true+, Cartage::Rack and Cartage::Rack::Simple will raise an
# exception if there is no metadata file (release-metadata.json or
# +release_hashref+). May be explicitly turned off.
#
# Defaults to +true+ except in development or test environments (based on
# $RAILS_ENV, $APP_ENV and $RACK_ENV).
def require_metadata(value = (arg = false; nil)) # rubocop:disable Style/Semicolon
@require_metadata = value unless arg == false
@require_metadata || default_require_metadata
end
private
def default_require_metadata
environment = ENV['RAILS_ENV'] || ENV['APP_ENV'] || ENV['RACK_ENV'] || 'development'
environment !~ /\A(?:development|test)\z/i
end
end
def initialize(root_path = nil, &filter) # :nodoc:
@metadata = Cartage::Rack::Metadata.new(root_path, filter: filter)
end
def call(env) #:nodoc:
type, body = resolve_content(env)
[ '200', { 'Content-Type' => type }, [ body ] ]
end
def inspect #:nodoc:
"#{self.class} for #{@metadata.inspect}"
end
private
def resolve_content(env)
content = @metadata.resolve
case env['PATH_INFO']
when /\.te?xt\z/
type = 'text/plain'
body = [
"name: #{dig(content, 'package', 'name')}",
"environment: #{dig(content, 'env', 'name')}",
"hashref: #{dig(content, 'package', 'hashref')}"
]
value = dig(content, 'package', 'timestamp')
body << "timestamp: #{value}" if value
repo = dig(content, 'package', 'repo')
body << "#{repo['type']}: #{repo['url']}" if repo
body = body.join("\n")
else
type = 'application/json'
body = content.to_json
end
[ type, body ]
end
attr_reader :metadata
#:nocov:
def dig(hash, key, *rest)
if hash.respond_to?(:dig)
hash.dig(key, *rest)
else
DIGGER.call(hash, key, *rest)
end
end
DIGGER = ->(h, k, *r) { #:nodoc:
v = h[k]
if v.nil? || r.empty?
v
else
DIGGER.call(v, *r)
end
}
private_constant :DIGGER
#:nocov:
end
end
require_relative 'rack/simple'
require_relative 'rack/metadata'