aboutsummaryrefslogtreecommitdiffstats
path: root/Library/Homebrew/tab.rb
blob: 15f2911d9d2eed59d395e0a48937ce3d614fb958 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
require 'ostruct'

require 'formula'
require 'vendor/multi_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.for_install`.
class Tab < OpenStruct
  def self.for_install f, args
    sha = `cd '#{HOMEBREW_REPOSITORY}' && git rev-parse --verify -q HEAD 2>/dev/null`.chuzzle
    Tab.new :used_options => args.used_options(f),
            :unused_options => args.unused_options(f),
            :tabfile => f.prefix + "INSTALL_RECEIPT.json",
            :built_as_bottle => !!args.build_bottle?,
            :tapped_from => f.tap,
            :time => Time.now.to_i, # to_s would be better but Ruby has no from_s function :P
            :HEAD => sha
  end

  def self.from_file path
    tab = Tab.new MultiJson.decode(open(path).read)
    tab.tabfile = path
    return tab
  end

  def self.for_keg keg
    path = keg+'INSTALL_RECEIPT.json'

    if path.exist?
      self.from_file path
    else
      begin
        self.dummy_tab Formula.factory(keg.parent.basename)
      rescue FormulaUnavailableError
        Tab.new :used_options => [],
                :unused_options => [],
                :built_as_bottle => false,
                :tapped_from => "",
                :time => nil,
                :HEAD => nil
      end
    end
  end

  def self.for_formula f
    f = Formula.factory f unless f.kind_of? Formula
    path = f.linked_keg/'INSTALL_RECEIPT.json'

    if path.exist?
      self.from_file path
    else
      # Really should bail out with an error if a formula was not installed
      # with a Tab. However, there will be lots of legacy installs that have no
      # receipt---so we fabricate one that claims the formula was installed with
      # no options.
      #
      # TODO:
      # This isn't the best behavior---perhaps a future version of Homebrew can
      # treat missing Tabs as errors.
      self.dummy_tab f
    end
  end

  def self.dummy_tab f
    Tab.new :used_options => [],
            :unused_options => f.build.as_flags,
            :built_as_bottle => false,
            :tapped_from => "",
            :time => nil,
            :HEAD => nil
  end

  def installed_with? opt
    used_options.include? opt
  end

  def options
    used_options + unused_options
  end

  def to_json
    MultiJson.encode({
      :used_options => used_options,
      :unused_options => unused_options,
      :built_as_bottle => built_as_bottle,
      :tapped_from => tapped_from,
      :time => time,
      :HEAD => send("HEAD")})
  end

  def write
    tabfile.write to_json
  end
end