Class: Tab
Overview
Rather than calling new
directly, use one of the class methods like Tab.create.
Constant Summary collapse
- FILENAME =
"INSTALL_RECEIPT.json"
Instance Attribute Summary collapse
-
#aliases ⇒ Object
Returns the value of attribute aliases.
-
#arch ⇒ Object
Returns the value of attribute arch.
-
#built_as_bottle ⇒ Object
Returns the value of attribute built_as_bottle.
-
#built_on ⇒ Object
Returns the value of attribute built_on.
-
#changed_files ⇒ Object
Returns the value of attribute changed_files.
-
#compiler ⇒ Object
-
#homebrew_version ⇒ Object
Returns the value of attribute homebrew_version.
-
#installed_as_dependency ⇒ Object
Returns the value of attribute installed_as_dependency.
-
#installed_on_request ⇒ Object
Returns the value of attribute installed_on_request.
-
#loaded_from_api ⇒ Object
Returns the value of attribute loaded_from_api.
-
#poured_from_bottle ⇒ Object
Returns the value of attribute poured_from_bottle.
-
#runtime_dependencies ⇒ Object
-
#source ⇒ Object
Returns the value of attribute source.
-
#source_modified_time ⇒ Time
-
#stdlib ⇒ Object
Returns the value of attribute stdlib.
-
#tabfile ⇒ Object
Returns the value of attribute tabfile.
-
#time ⇒ Object
Returns the value of attribute time.
-
#unused_options ⇒ Object
-
#used_options ⇒ Object
Class Method Summary collapse
-
.create(formula, compiler, stdlib) ⇒ Object
Instantiates a Tab for a new installation of a formula.
-
.empty ⇒ Object
-
.for_formula(formula) ⇒ Object
Returns a Tab for an already installed formula, or a fake one if the formula is not installed.
-
.for_keg(keg) ⇒ Object
-
.for_name(name) ⇒ Object
Returns a Tab for the named formula’s installation, or a fake one if the formula is not installed.
-
.from_file(path) ⇒ Object
Returns the Tab for an install receipt at
path
. -
.from_file_content(content, path) ⇒ Object
Like Tab.from_file, but bypass the cache.
-
.remap_deprecated_options(deprecated_options, options) ⇒ Object
-
.runtime_deps_hash(formula, deps) ⇒ Object
Instance Method Summary collapse
-
#any_args_or_options? ⇒ Boolean
-
#bottle? ⇒ Boolean
-
#built_bottle? ⇒ Boolean
-
#cxxstdlib ⇒ Object
-
#head? ⇒ Boolean
-
#head_version ⇒ Object
-
#include?(opt) ⇒ Boolean
-
#initialize(attributes = {}) ⇒ Tab
constructor
A new instance of Tab.
-
#parsed_homebrew_version ⇒ Object
-
#spec ⇒ Object
-
#stable? ⇒ Boolean
-
#stable_version ⇒ Object
-
#tap ⇒ Object
-
#tap=(tap) ⇒ Object
-
#to_bottle_hash ⇒ Object
A subset of to_json that we care about for bottles.
-
#to_json(options = nil) ⇒ Object
-
#to_s ⇒ String
-
#version_scheme ⇒ Object
-
#versions ⇒ Object
-
#with?(val) ⇒ Boolean
-
#without?(val) ⇒ Boolean
-
#write ⇒ Object
Methods included from Cachable
Constructor Details
#initialize(attributes = {}) ⇒ Tab
Returns a new instance of Tab.
236 237 238 |
# File 'tab.rb', line 236 def initialize(attributes = {}) attributes.each { |key, value| instance_variable_set("@#{key}", value) } end |
Instance Attribute Details
#aliases ⇒ Object
Returns the value of attribute aliases.
16 17 18 |
# File 'tab.rb', line 16 def aliases @aliases end |
#arch ⇒ Object
Returns the value of attribute arch.
16 17 18 |
# File 'tab.rb', line 16 def arch @arch end |
#built_as_bottle ⇒ Object
Returns the value of attribute built_as_bottle.
16 17 18 |
# File 'tab.rb', line 16 def built_as_bottle @built_as_bottle end |
#built_on ⇒ Object
Returns the value of attribute built_on.
16 17 18 |
# File 'tab.rb', line 16 def built_on @built_on end |
#changed_files ⇒ Object
Returns the value of attribute changed_files.
16 17 18 |
# File 'tab.rb', line 16 def changed_files @changed_files end |
#compiler ⇒ Object
276 277 278 |
# File 'tab.rb', line 276 def compiler @compiler || DevelopmentTools.default_compiler end |
#homebrew_version ⇒ Object
Returns the value of attribute homebrew_version.
16 17 18 |
# File 'tab.rb', line 16 def homebrew_version @homebrew_version end |
#installed_as_dependency ⇒ Object
Returns the value of attribute installed_as_dependency.
16 17 18 |
# File 'tab.rb', line 16 def installed_as_dependency @installed_as_dependency end |
#installed_on_request ⇒ Object
Returns the value of attribute installed_on_request.
16 17 18 |
# File 'tab.rb', line 16 def installed_on_request @installed_on_request end |
#loaded_from_api ⇒ Object
Returns the value of attribute loaded_from_api.
16 17 18 |
# File 'tab.rb', line 16 def loaded_from_api @loaded_from_api end |
#poured_from_bottle ⇒ Object
Returns the value of attribute poured_from_bottle.
16 17 18 |
# File 'tab.rb', line 16 def poured_from_bottle @poured_from_bottle end |
#runtime_dependencies ⇒ Object
286 287 288 289 290 |
# File 'tab.rb', line 286 def runtime_dependencies # Homebrew versions prior to 1.1.6 generated incorrect runtime dependency # lists. @runtime_dependencies if parsed_homebrew_version >= "1.1.6" end |
#source ⇒ Object
Returns the value of attribute source.
16 17 18 |
# File 'tab.rb', line 16 def source @source end |
#source_modified_time ⇒ Time
337 338 339 |
# File 'tab.rb', line 337 def source_modified_time Time.at(@source_modified_time || 0) end |
#stdlib ⇒ Object
Returns the value of attribute stdlib.
16 17 18 |
# File 'tab.rb', line 16 def stdlib @stdlib end |
#tabfile ⇒ Object
Returns the value of attribute tabfile.
16 17 18 |
# File 'tab.rb', line 16 def tabfile @tabfile end |
#time ⇒ Object
Returns the value of attribute time.
16 17 18 |
# File 'tab.rb', line 16 def time @time end |
Class Method Details
.create(formula, compiler, stdlib) ⇒ Object
Instantiates a Tab for a new installation of a formula.
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
# File 'tab.rb', line 22 def self.create(formula, compiler, stdlib) build = formula.build runtime_deps = formula.runtime_dependencies(undeclared: false) attributes = { "homebrew_version" => HOMEBREW_VERSION, "used_options" => build..as_flags, "unused_options" => build..as_flags, "tabfile" => formula.prefix/FILENAME, "built_as_bottle" => build.bottle?, "installed_as_dependency" => false, "installed_on_request" => false, "poured_from_bottle" => false, "loaded_from_api" => false, "time" => Time.now.to_i, "source_modified_time" => formula.source_modified_time.to_i, "compiler" => compiler, "stdlib" => stdlib, "aliases" => formula.aliases, "runtime_dependencies" => Tab.runtime_deps_hash(formula, runtime_deps), "arch" => Hardware::CPU.arch, "source" => { "path" => formula.specified_path.to_s, "tap" => formula.tap&.name, "tap_git_head" => nil, # Filled in later if possible "spec" => formula.active_spec_sym.to_s, "versions" => { "stable" => formula.stable&.version&.to_s, "head" => formula.head&.version&.to_s, "version_scheme" => formula.version_scheme, }, }, "built_on" => DevelopmentTools.build_system_info, } # We can only get `tap_git_head` if the tap is installed locally attributes["source"]["tap_git_head"] = formula.tap.git_head if formula.tap&.installed? new(attributes) end |
.empty ⇒ Object
189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 |
# File 'tab.rb', line 189 def self.empty attributes = { "homebrew_version" => HOMEBREW_VERSION, "used_options" => [], "unused_options" => [], "built_as_bottle" => false, "installed_as_dependency" => false, "installed_on_request" => false, "poured_from_bottle" => false, "loaded_from_api" => false, "time" => nil, "source_modified_time" => 0, "stdlib" => nil, "compiler" => DevelopmentTools.default_compiler, "aliases" => [], "runtime_dependencies" => nil, "arch" => nil, "source" => { "path" => nil, "tap" => nil, "tap_git_head" => nil, "spec" => "stable", "versions" => { "stable" => nil, "head" => nil, "version_scheme" => 0, }, }, "built_on" => DevelopmentTools.generic_build_system_info, } new(attributes) end |
.for_formula(formula) ⇒ Object
Returns a Tab for an already installed formula, or a fake one if the formula is not installed.
151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 |
# File 'tab.rb', line 151 def self.for_formula(formula) paths = [] paths << formula.opt_prefix.resolved_path if formula.opt_prefix.symlink? && formula.opt_prefix.directory? paths << formula.linked_keg.resolved_path if formula.linked_keg.symlink? && formula.linked_keg.directory? if (dirs = formula.installed_prefixes).length == 1 paths << dirs.first end paths << formula.latest_installed_prefix path = paths.map { |pathname| pathname/FILENAME }.find(&:file?) if path tab = from_file(path) = (formula., tab.) tab. = .as_flags else # Formula is not installed. Return a fake tab. tab = empty tab. = formula..as_flags tab.source = { "path" => formula.specified_path.to_s, "tap" => formula.tap&.name, "spec" => formula.active_spec_sym.to_s, "versions" => { "stable" => formula.stable&.version&.to_s, "head" => formula.head&.version&.to_s, "version_scheme" => formula.version_scheme, }, } end tab end |
.for_keg(keg) ⇒ Object
119 120 121 122 123 124 125 126 127 128 129 130 |
# File 'tab.rb', line 119 def self.for_keg(keg) path = keg/FILENAME tab = if path.exist? from_file(path) else empty end tab.tabfile = path tab end |
.for_name(name) ⇒ Object
Returns a Tab for the named formula’s installation, or a fake one if the formula is not installed.
134 135 136 |
# File 'tab.rb', line 134 def self.for_name(name) for_formula(Formulary.factory(name)) end |
.from_file(path) ⇒ Object
Returns the Tab for an install receipt at path
.
Results are cached.
64 65 66 67 68 69 70 71 |
# File 'tab.rb', line 64 def self.from_file(path) cache.fetch(path) do |p| content = File.read(p) return empty if content.blank? cache[p] = from_file_content(content, p) end end |
.from_file_content(content, path) ⇒ Object
Like from_file, but bypass the cache.
74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 |
# File 'tab.rb', line 74 def self.from_file_content(content, path) attributes = begin JSON.parse(content) rescue JSON::ParserError => e raise e, "Cannot parse #{path}: #{e}", e.backtrace end attributes["tabfile"] = path attributes["source_modified_time"] ||= 0 attributes["source"] ||= {} tapped_from = attributes["tapped_from"] if !tapped_from.nil? && tapped_from != "path or URL" attributes["source"]["tap"] = attributes.delete("tapped_from") end if attributes["source"]["tap"] == "mxcl/master" || attributes["source"]["tap"] == "Homebrew/homebrew" attributes["source"]["tap"] = "homebrew/core" end if attributes["source"]["spec"].nil? version = PkgVersion.parse path.to_s.split("/").second_to_last attributes["source"]["spec"] = if version.head? "head" else "stable" end end if attributes["source"]["versions"].nil? attributes["source"]["versions"] = { "stable" => nil, "head" => nil, "version_scheme" => 0, } end # Tabs created with Homebrew 1.5.13 through 4.0.17 inclusive created empty string versions in some cases. ["stable", "head"].each do |spec| attributes["source"]["versions"][spec] = attributes["source"]["versions"][spec].presence end new(attributes) end |
.remap_deprecated_options(deprecated_options, options) ⇒ Object
138 139 140 141 142 143 144 145 146 147 |
# File 'tab.rb', line 138 def self.(, ) .each do |deprecated_option| option = .find { |o| o.name == deprecated_option.old } next unless option -= [option] << Option.new(deprecated_option.current, option.description) end end |
.runtime_deps_hash(formula, deps) ⇒ Object
223 224 225 226 227 228 229 230 231 232 233 234 |
# File 'tab.rb', line 223 def self.runtime_deps_hash(formula, deps) deps.map do |dep| f = dep.to_formula { "full_name" => f.full_name, "version" => f.version.to_s, "revision" => f.revision, "pkg_version" => f.pkg_version.to_s, "declared_directly" => formula.deps.include?(dep), } end end |
Instance Method Details
#any_args_or_options? ⇒ Boolean
240 241 242 |
# File 'tab.rb', line 240 def !.empty? || !.empty? end |
#bottle? ⇒ Boolean
302 303 304 |
# File 'tab.rb', line 302 def bottle? built_as_bottle end |
#built_bottle? ⇒ Boolean
298 299 300 |
# File 'tab.rb', line 298 def built_bottle? built_as_bottle && !poured_from_bottle end |
#cxxstdlib ⇒ Object
292 293 294 295 296 |
# File 'tab.rb', line 292 def cxxstdlib # Older tabs won't have these values, so provide sensible defaults lib = stdlib.to_sym if stdlib CxxStdlib.create(lib, compiler.to_sym) end |
#head? ⇒ Boolean
260 261 262 |
# File 'tab.rb', line 260 def head? spec == :head end |
#head_version ⇒ Object
328 329 330 |
# File 'tab.rb', line 328 def head_version versions["head"]&.then(&Version.method(:new)) end |
#include?(opt) ⇒ Boolean
256 257 258 |
# File 'tab.rb', line 256 def include?(opt) .include? opt end |
#parsed_homebrew_version ⇒ Object
280 281 282 283 284 |
# File 'tab.rb', line 280 def parsed_homebrew_version return Version::NULL if homebrew_version.nil? Version.new(homebrew_version) end |
#spec ⇒ Object
316 317 318 |
# File 'tab.rb', line 316 def spec source["spec"].to_sym end |
#stable? ⇒ Boolean
264 265 266 |
# File 'tab.rb', line 264 def stable? spec == :stable end |
#stable_version ⇒ Object
324 325 326 |
# File 'tab.rb', line 324 def stable_version versions["stable"]&.then(&Version.method(:new)) end |
#tap ⇒ Object
306 307 308 309 |
# File 'tab.rb', line 306 def tap tap_name = source["tap"] Tap.fetch(tap_name) if tap_name end |
#tap=(tap) ⇒ Object
311 312 313 314 |
# File 'tab.rb', line 311 def tap=(tap) tap_name = tap.respond_to?(:name) ? tap.name : tap source["tap"] = tap_name end |
#to_bottle_hash ⇒ Object
A subset of to_json that we care about for bottles.
368 369 370 371 372 373 374 375 376 377 378 379 380 381 |
# File 'tab.rb', line 368 def to_bottle_hash attributes = { "homebrew_version" => homebrew_version, "changed_files" => changed_files&.map(&:to_s), "source_modified_time" => source_modified_time.to_i, "stdlib" => stdlib&.to_s, "compiler" => compiler&.to_s, "runtime_dependencies" => runtime_dependencies, "arch" => arch, "built_on" => built_on, } attributes.delete("stdlib") if attributes["stdlib"].blank? attributes end |
#to_json(options = nil) ⇒ Object
341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 |
# File 'tab.rb', line 341 def to_json( = nil) attributes = { "homebrew_version" => homebrew_version, "used_options" => .as_flags, "unused_options" => .as_flags, "built_as_bottle" => built_as_bottle, "poured_from_bottle" => poured_from_bottle, "loaded_from_api" => loaded_from_api, "installed_as_dependency" => installed_as_dependency, "installed_on_request" => installed_on_request, "changed_files" => changed_files&.map(&:to_s), "time" => time, "source_modified_time" => source_modified_time.to_i, "stdlib" => stdlib&.to_s, "compiler" => compiler&.to_s, "aliases" => aliases, "runtime_dependencies" => runtime_dependencies, "source" => source, "arch" => arch, "built_on" => built_on, } attributes.delete("stdlib") if attributes["stdlib"].blank? JSON.pretty_generate(attributes, ) end |
#to_s ⇒ String
393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 |
# File 'tab.rb', line 393 def to_s s = [] s << if poured_from_bottle "Poured from bottle" else "Built from source" end s << "using the formulae.brew.sh API" if loaded_from_api s << Time.at(time).strftime("on %Y-%m-%d at %H:%M:%S") if time unless .empty? s << "with:" s << .to_a.join(" ") end s.join(" ") end |
#version_scheme ⇒ Object
332 333 334 |
# File 'tab.rb', line 332 def version_scheme versions["version_scheme"] || 0 end |
#versions ⇒ Object
320 321 322 |
# File 'tab.rb', line 320 def versions source["versions"] end |
#with?(val) ⇒ Boolean
244 245 246 247 248 249 250 |
# File 'tab.rb', line 244 def with?(val) option_names = val.respond_to?(:option_names) ? val.option_names : [val] option_names.any? do |name| include?("with-#{name}") || .include?("without-#{name}") end end |
#without?(val) ⇒ Boolean
252 253 254 |
# File 'tab.rb', line 252 def without?(val) !with?(val) end |
#write ⇒ Object
383 384 385 386 387 388 389 390 |
# File 'tab.rb', line 383 def write # If this is a new installation, the cache of installed formulae # will no longer be valid. Formula.clear_cache unless tabfile.exist? self.class.cache[tabfile] = self tabfile.atomic_write(to_json) end |