| 
									
										
										
										
											2013-07-27 00:11:45 -07:00
										 |  |  | require 'cxxstdlib' | 
					
						
							| 
									
										
										
										
											2011-09-22 20:07:39 -07:00
										 |  |  | require 'ostruct' | 
					
						
							| 
									
										
										
										
											2013-01-23 00:26:23 -06:00
										 |  |  | require 'options' | 
					
						
							| 
									
										
										
										
											2013-06-22 16:51:08 -05:00
										 |  |  | require 'utils/json' | 
					
						
							| 
									
										
										
										
											2011-09-22 20:07:39 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | # 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`. | 
					
						
							| 
									
										
										
										
											2011-09-22 20:07:39 -07:00
										 |  |  | class Tab < OpenStruct | 
					
						
							| 
									
										
										
										
											2013-01-23 00:26:20 -06:00
										 |  |  |   FILENAME = 'INSTALL_RECEIPT.json' | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-30 20:27:46 -05:00
										 |  |  |   def self.create(formula, compiler, stdlib, build) | 
					
						
							| 
									
										
										
										
											2015-02-18 20:05:50 -05:00
										 |  |  |     attributes = { | 
					
						
							| 
									
										
										
										
											2015-02-21 18:32:52 -05:00
										 |  |  |       "used_options" => build.used_options.as_flags, | 
					
						
							|  |  |  |       "unused_options" => build.unused_options.as_flags, | 
					
						
							|  |  |  |       "tabfile" => formula.prefix.join(FILENAME), | 
					
						
							| 
									
										
										
										
											2015-03-07 23:53:33 -05:00
										 |  |  |       "built_as_bottle" => build.bottle?, | 
					
						
							| 
									
										
										
										
											2015-02-21 18:32:52 -05:00
										 |  |  |       "poured_from_bottle" => false, | 
					
						
							|  |  |  |       "time" => Time.now.to_i, | 
					
						
							|  |  |  |       "HEAD" => Homebrew.git_head, | 
					
						
							|  |  |  |       "compiler" => compiler, | 
					
						
							|  |  |  |       "stdlib" => stdlib, | 
					
						
							|  |  |  |       "source" => { | 
					
						
							|  |  |  |         "path" => formula.path.to_s, | 
					
						
							| 
									
										
										
										
											2015-03-13 00:41:10 -04:00
										 |  |  |         "tap" => formula.tap, | 
					
						
							| 
									
										
										
										
											2015-02-18 20:05:50 -05:00
										 |  |  |       }, | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     new(attributes) | 
					
						
							| 
									
										
										
										
											2011-09-22 20:07:39 -07:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-09-23 08:36:40 -07:00
										 |  |  |   def self.from_file path | 
					
						
							| 
									
										
										
										
											2015-05-23 18:08:07 +08:00
										 |  |  |     from_file_content(File.read(path), path) | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def self.from_file_content content, path | 
					
						
							|  |  |  |     attributes = Utils::JSON.load(content) | 
					
						
							| 
									
										
										
										
											2015-02-21 18:32:52 -05:00
										 |  |  |     attributes["tabfile"] = path | 
					
						
							| 
									
										
										
										
											2015-03-13 00:41:10 -04:00
										 |  |  |     attributes["source"] ||= {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     tapped_from = attributes["tapped_from"] | 
					
						
							|  |  |  |     unless tapped_from.nil? || tapped_from == "path or URL" | 
					
						
							|  |  |  |       attributes["source"]["tap"] = attributes.delete("tapped_from") | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-29 23:15:13 -05:00
										 |  |  |     new(attributes) | 
					
						
							| 
									
										
										
										
											2011-09-23 08:36:40 -07:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-01 15:22:36 -06:00
										 |  |  |   def self.for_keg keg | 
					
						
							| 
									
										
										
										
											2013-01-23 00:26:20 -06:00
										 |  |  |     path = keg.join(FILENAME) | 
					
						
							| 
									
										
										
										
											2012-01-01 15:22:36 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if path.exist? | 
					
						
							| 
									
										
										
										
											2014-06-29 22:26:14 -05:00
										 |  |  |       from_file(path) | 
					
						
							| 
									
										
										
										
											2012-01-01 15:22:36 -06:00
										 |  |  |     else | 
					
						
							| 
									
										
										
										
											2015-02-21 12:15:39 -05:00
										 |  |  |       empty | 
					
						
							| 
									
										
										
										
											2012-01-01 15:22:36 -06:00
										 |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-06-26 10:37:09 -07:00
										 |  |  |   def self.for_name name | 
					
						
							| 
									
										
										
										
											2014-06-22 15:00:15 -05:00
										 |  |  |     for_formula(Formulary.factory(name)) | 
					
						
							| 
									
										
										
										
											2013-06-26 10:37:09 -07:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-16 13:01:48 +01:00
										 |  |  |   def self.remap_deprecated_options deprecated_options, options | 
					
						
							|  |  |  |     deprecated_options.each do |deprecated_option| | 
					
						
							| 
									
										
										
										
											2014-12-26 11:58:09 -05:00
										 |  |  |       option = options.find { |o| o.name == deprecated_option.old } | 
					
						
							| 
									
										
										
										
											2014-10-16 13:01:48 +01:00
										 |  |  |       next unless option | 
					
						
							|  |  |  |       options -= [option] | 
					
						
							|  |  |  |       options << Option.new(deprecated_option.current, option.description) | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |     options | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-09-23 08:36:40 -07:00
										 |  |  |   def self.for_formula f | 
					
						
							| 
									
										
										
										
											2014-06-29 19:19:24 -05:00
										 |  |  |     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 | 
					
						
							| 
									
										
										
										
											2014-03-22 11:34:26 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     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 | 
					
						
							| 
									
										
										
										
											2014-10-16 13:01:48 +01:00
										 |  |  |       tab = from_file(path) | 
					
						
							|  |  |  |       used_options = remap_deprecated_options(f.deprecated_options, tab.used_options) | 
					
						
							|  |  |  |       tab.used_options = used_options.as_flags | 
					
						
							| 
									
										
										
										
											2014-03-22 11:34:26 -05:00
										 |  |  |     else | 
					
						
							| 
									
										
										
										
											2015-02-21 12:15:39 -05:00
										 |  |  |       tab = empty | 
					
						
							|  |  |  |       tab.unused_options = f.options.as_flags | 
					
						
							| 
									
										
										
										
											2015-03-13 00:41:10 -04:00
										 |  |  |       tab.source = { "path" => f.path.to_s, "tap" => f.tap } | 
					
						
							| 
									
										
										
										
											2014-03-22 11:34:26 -05:00
										 |  |  |     end | 
					
						
							| 
									
										
										
										
											2015-02-21 12:15:39 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     tab | 
					
						
							| 
									
										
										
										
											2011-09-23 08:36:40 -07:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-21 12:15:39 -05:00
										 |  |  |   def self.empty | 
					
						
							| 
									
										
										
										
											2015-02-18 20:05:50 -05:00
										 |  |  |     attributes = { | 
					
						
							| 
									
										
										
										
											2015-02-21 18:32:52 -05:00
										 |  |  |       "used_options" => [], | 
					
						
							|  |  |  |       "unused_options" => [], | 
					
						
							|  |  |  |       "built_as_bottle" => false, | 
					
						
							|  |  |  |       "poured_from_bottle" => false, | 
					
						
							|  |  |  |       "time" => nil, | 
					
						
							|  |  |  |       "HEAD" => nil, | 
					
						
							|  |  |  |       "stdlib" => nil, | 
					
						
							|  |  |  |       "compiler" => "clang", | 
					
						
							|  |  |  |       "source" => { | 
					
						
							|  |  |  |         "path" => nil, | 
					
						
							| 
									
										
										
										
											2015-03-13 00:41:10 -04:00
										 |  |  |         "tap" => nil, | 
					
						
							| 
									
										
										
										
											2015-02-18 20:05:50 -05:00
										 |  |  |       }, | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     new(attributes) | 
					
						
							| 
									
										
										
										
											2012-01-01 15:22:36 -06:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-09 00:20:15 -05:00
										 |  |  |   def with? val | 
					
						
							|  |  |  |     name = val.respond_to?(:option_name) ? val.option_name : val | 
					
						
							| 
									
										
										
										
											2014-08-09 16:26:59 -05:00
										 |  |  |     include?("with-#{name}") || unused_options.include?("without-#{name}") | 
					
						
							| 
									
										
										
										
											2013-01-23 00:26:24 -06:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-30 21:04:17 -05:00
										 |  |  |   def without? name | 
					
						
							|  |  |  |     not with? name | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-23 00:26:24 -06:00
										 |  |  |   def include? opt | 
					
						
							| 
									
										
										
										
											2011-09-23 08:36:40 -07:00
										 |  |  |     used_options.include? opt | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-23 00:26:24 -06:00
										 |  |  |   def universal? | 
					
						
							| 
									
										
										
										
											2014-08-03 18:17:12 -05:00
										 |  |  |     include?("universal") | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def cxx11? | 
					
						
							|  |  |  |     include?("c++11") | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def build_32_bit? | 
					
						
							|  |  |  |     include?("32-bit") | 
					
						
							| 
									
										
										
										
											2013-01-23 00:26:24 -06:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-23 00:26:23 -06:00
										 |  |  |   def used_options | 
					
						
							| 
									
										
										
										
											2014-08-13 11:09:57 -05:00
										 |  |  |     Options.create(super) | 
					
						
							| 
									
										
										
										
											2013-01-23 00:26:23 -06:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def unused_options | 
					
						
							| 
									
										
										
										
											2014-08-13 11:09:57 -05:00
										 |  |  |     Options.create(super) | 
					
						
							| 
									
										
										
										
											2013-01-23 00:26:23 -06:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-07-27 00:11:45 -07:00
										 |  |  |   def cxxstdlib | 
					
						
							|  |  |  |     # Older tabs won't have these values, so provide sensible defaults | 
					
						
							| 
									
										
										
										
											2013-10-07 00:25:26 -07:00
										 |  |  |     lib = stdlib.to_sym if stdlib | 
					
						
							| 
									
										
										
										
											2013-07-27 00:11:45 -07:00
										 |  |  |     cc = compiler || MacOS.default_compiler | 
					
						
							| 
									
										
										
										
											2014-08-02 19:29:59 -05:00
										 |  |  |     CxxStdlib.create(lib, cc.to_sym) | 
					
						
							| 
									
										
										
										
											2013-07-27 00:11:45 -07:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-15 00:52:57 -05:00
										 |  |  |   def build_bottle? | 
					
						
							|  |  |  |     built_as_bottle && !poured_from_bottle | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-11 20:23:22 -07:00
										 |  |  |   def bottle? | 
					
						
							|  |  |  |     built_as_bottle | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-13 00:41:10 -04:00
										 |  |  |   def tap | 
					
						
							|  |  |  |     source["tap"] | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-27 09:57:41 +01:00
										 |  |  |   def tap=(tap) | 
					
						
							|  |  |  |     source["tap"] = tap | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-09-22 20:07:39 -07:00
										 |  |  |   def to_json | 
					
						
							| 
									
										
										
										
											2015-02-18 20:05:50 -05:00
										 |  |  |     attributes = { | 
					
						
							| 
									
										
										
										
											2015-02-21 18:32:52 -05:00
										 |  |  |       "used_options" => used_options.as_flags, | 
					
						
							|  |  |  |       "unused_options" => unused_options.as_flags, | 
					
						
							|  |  |  |       "built_as_bottle" => built_as_bottle, | 
					
						
							|  |  |  |       "poured_from_bottle" => poured_from_bottle, | 
					
						
							|  |  |  |       "time" => time, | 
					
						
							|  |  |  |       "HEAD" => self.HEAD, | 
					
						
							|  |  |  |       "stdlib" => (stdlib.to_s if stdlib), | 
					
						
							|  |  |  |       "compiler" => (compiler.to_s if compiler), | 
					
						
							| 
									
										
										
										
											2015-03-13 00:41:10 -04:00
										 |  |  |       "source" => source, | 
					
						
							| 
									
										
										
										
											2015-02-18 20:05:50 -05:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Utils::JSON.dump(attributes) | 
					
						
							| 
									
										
										
										
											2011-09-22 20:07:39 -07:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def write | 
					
						
							| 
									
										
										
										
											2014-03-22 11:13:33 -05:00
										 |  |  |     tabfile.atomic_write(to_json) | 
					
						
							| 
									
										
										
										
											2011-09-22 20:07:39 -07:00
										 |  |  |   end | 
					
						
							| 
									
										
										
										
											2013-03-27 23:07:25 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |   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 | 
					
						
							| 
									
										
										
										
											2011-09-22 20:07:39 -07:00
										 |  |  | end |