155 lines
3.5 KiB
Ruby
Raw Normal View History

require 'cxxstdlib'
require 'ostruct'
require 'options'
require 'utils/json'
# Inherit from OpenStruct to gain a generic initialization method that takes a
# hash and creates an attribute for each key and value. `Tab.new` probably
# should not be called directly, instead use one of the class methods like
2013-01-23 00:26:20 -06:00
# `Tab.create`.
class Tab < OpenStruct
2013-01-23 00:26:20 -06:00
FILENAME = 'INSTALL_RECEIPT.json'
def self.create f, compiler, stdlib, args
build = f.build.dup
build.args = args
Tab.new :used_options => build.used_options,
:unused_options => build.unused_options,
2013-01-23 00:26:20 -06:00
:tabfile => f.prefix.join(FILENAME),
:built_as_bottle => !!ARGV.build_bottle?,
:poured_from_bottle => false,
:tapped_from => f.tap,
:time => Time.now.to_i,
2014-06-30 19:15:03 -05:00
:HEAD => Homebrew.git_head,
:compiler => compiler,
:stdlib => stdlib
end
def self.from_file path
2014-06-29 23:15:13 -05:00
attributes = Utils::JSON.load(File.read(path))
attributes[:tabfile] = path
new(attributes)
end
def self.for_keg keg
2013-01-23 00:26:20 -06:00
path = keg.join(FILENAME)
if path.exist?
2014-06-29 22:26:14 -05:00
from_file(path)
else
2014-06-29 22:26:14 -05:00
dummy_tab
end
end
def self.for_name name
for_formula(Formulary.factory(name))
end
def self.for_formula f
paths = []
if f.opt_prefix.symlink? && f.opt_prefix.directory?
paths << f.opt_prefix.resolved_path
end
if f.linked_keg.symlink? && f.linked_keg.directory?
paths << f.linked_keg.resolved_path
end
if f.rack.directory? && (dirs = f.rack.subdirs).length == 1
paths << dirs.first
end
paths << f.prefix
path = paths.map { |pn| pn.join(FILENAME) }.find(&:file?)
if path
from_file(path)
else
dummy_tab(f)
end
end
2013-01-23 00:26:20 -06:00
def self.dummy_tab f=nil
Tab.new :used_options => [],
2013-01-23 00:26:20 -06:00
:unused_options => (f.build.as_flags rescue []),
:built_as_bottle => false,
:poured_from_bottle => false,
:tapped_from => "",
:time => nil,
:HEAD => nil,
2014-06-29 00:56:29 -05:00
:stdlib => nil,
:compiler => :clang
end
def with? name
if options.include? "with-#{name}"
used_options.include? "with-#{name}"
elsif options.include? "without-#{name}"
not used_options.include? "without-#{name}"
else
false
end
end
def include? opt
used_options.include? opt
end
def universal?
used_options.include? "universal"
end
def used_options
Options.coerce(super)
end
def unused_options
Options.coerce(super)
end
def options
used_options + unused_options
end
def cxxstdlib
# Older tabs won't have these values, so provide sensible defaults
lib = stdlib.to_sym if stdlib
cc = compiler || MacOS.default_compiler
CxxStdlib.new(lib, cc.to_sym)
end
def to_json
Utils::JSON.dump({
2013-06-22 16:51:09 -05:00
:used_options => used_options.map(&:to_s),
:unused_options => unused_options.map(&:to_s),
:built_as_bottle => built_as_bottle,
:poured_from_bottle => poured_from_bottle,
:tapped_from => tapped_from,
:time => time,
:HEAD => self.HEAD,
:stdlib => (stdlib.to_s if stdlib),
:compiler => (compiler.to_s if compiler)})
end
def write
2014-03-22 11:13:33 -05:00
tabfile.atomic_write(to_json)
end
def to_s
s = []
case poured_from_bottle
when true then s << "Poured from bottle"
when false then s << "Built from source"
end
unless used_options.empty?
s << "Installed" if s.empty?
s << "with:"
s << used_options.to_a.join(", ")
end
s.join(" ")
end
end