150 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
			
		
		
	
	
			150 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
| 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
 | |
| # `Tab.create`.
 | |
| class Tab < OpenStruct
 | |
|   FILENAME = 'INSTALL_RECEIPT.json'
 | |
| 
 | |
|   def self.create f, compiler, stdlib, args
 | |
|     build = f.build.dup
 | |
|     build.args = args
 | |
| 
 | |
|     sha = HOMEBREW_REPOSITORY.cd do
 | |
|       `git rev-parse --verify -q HEAD 2>/dev/null`.chuzzle
 | |
|     end
 | |
| 
 | |
|     Tab.new :used_options => build.used_options,
 | |
|             :unused_options => build.unused_options,
 | |
|             :tabfile => f.prefix.join(FILENAME),
 | |
|             :built_as_bottle => !!ARGV.build_bottle?,
 | |
|             :poured_from_bottle => false,
 | |
|             :tapped_from => f.tap,
 | |
|             :time => Time.now.to_i,
 | |
|             :HEAD => sha,
 | |
|             :compiler => compiler,
 | |
|             :stdlib => stdlib
 | |
|   end
 | |
| 
 | |
|   def self.from_file path
 | |
|     tab = Tab.new Utils::JSON.load(File.read(path))
 | |
|     tab.tabfile = path.realpath
 | |
|     tab
 | |
|   end
 | |
| 
 | |
|   def self.for_keg keg
 | |
|     path = keg.join(FILENAME)
 | |
| 
 | |
|     if path.exist?
 | |
|       self.from_file(path)
 | |
|     else
 | |
|       self.dummy_tab
 | |
|     end
 | |
|   end
 | |
| 
 | |
|   def self.for_name name
 | |
|     for_formula(Formula.factory(name))
 | |
|   end
 | |
| 
 | |
|   def self.for_formula f
 | |
|     paths = [f.opt_prefix, f.linked_keg]
 | |
| 
 | |
|     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
 | |
| 
 | |
|   def self.dummy_tab f=nil
 | |
|     Tab.new :used_options => [],
 | |
|             :unused_options => (f.build.as_flags rescue []),
 | |
|             :built_as_bottle => false,
 | |
|             :poured_from_bottle => false,
 | |
|             :tapped_from => "",
 | |
|             :time => nil,
 | |
|             :HEAD => 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({
 | |
|       :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
 | |
|     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
 | 
