aboutsummaryrefslogtreecommitdiffstats
path: root/Library/Homebrew/keg.rb
blob: 8330c650f2c387cf3b1666beb06b45dccca00031 (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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
#  Copyright 2009 Max Howell <max@methylblue.com>
#
#  This file is part of Homebrew.
#
#  Homebrew is free software: you can redistribute it and/or modify
#  it under the terms of the GNU General Public License as published by
#  the Free Software Foundation, either version 3 of the License, or
#  (at your option) any later version.
#
#  Homebrew is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#
#  You should have received a copy of the GNU General Public License
#  along with Homebrew.  If not, see <http://www.gnu.org/licenses/>.

require 'env'
require 'formula'

class Keg
  attr_reader :path, :version, :name
  
  def initialize formula
    if formula.is_a? AbstractFormula
      @path=formula.prefix
      @name=formula.name
      @version=formula.version
    elsif formula.is_a? Pathname
      # TODO
    elsif formula.is_a? String
      kids=($cellar+formula).children
      raise "Multiple versions installed" if kids.length > 1
      @path=kids[0]
      @name=formula
      @version=@path.basename
    end
  end

  def clean
    # TODO unset write permission more
    %w[bin lib].each {|d| (Pathname.new(path)+d).find do |path|
      if not path.file?
        next
      elsif path.extname == '.la'
        # .la files are stupid
        path.unlink
      else
        fo=`file -h #{path}`
        args=nil
        perms=0444
        if fo =~ /Mach-O dynamically linked shared library/
          args='-SxX'
        elsif fo =~ /Mach-O executable/ # defaults strip everything
          args='' # still do the strip
          perms=0544
        elsif fo =~ /script text executable/
          perms=0544
        end
        if args
          puts "Stripping: #{path}" if ARGV.include? '--verbose'
          path.chmod 0644 # so we can strip
          unless path.stat.nlink > 1
            `strip #{args} #{path}`
          else
            # strip unlinks the file and recreates it, thus breaking hard links!
            # is this expected behaviour? patch does it too… still,mktm this fixes it
            tmp=`mktemp -t #{path.basename}`.strip
            `strip -o #{tmp} #{path}`
            `cat #{tmp} > #{path}`
            File.unlink tmp
          end
        end
        path.chmod perms
      end
    end}

    # remove empty directories TODO Rubyize!
    `perl -MFile::Find -e"finddepth(sub{rmdir},'#{path}')"`
  end

  def rm
    if path.directory?
      FileUtils.chmod_R 0777, path # ensure we have permission to delete
      path.rmtree
    end
  end

private
  def __symlink_relative_to from, to
    tod=to.dirname
    tod.mkpath
    Dir.chdir(tod) do
      #TODO use Ruby function so we get exceptions
      #NOTE Ruby functions are fucked up!
      `ln -sf "#{from.relative_path_from tod}"`
      @n+=1
    end
  end

  # symlinks a directory recursively into our FHS tree
  def __ln start
    start=path+start
    return unless start.directory?

    start.find do |from|
      next if from == start

      prune=false

      relative_path=from.relative_path_from path
      to=$root+relative_path

      if from.file?
        __symlink_relative_to from, to
      elsif from.directory?
        # no need to put .app bundles in the path, the user can just use
        # spotlight, or the open command and actual mac apps use an equivalent
        Find.prune if from.extname.to_s == '.app'

        branch=from.relative_path_from start

        case yield branch when :skip
          Find.prune
        when :mkpath
          to.mkpath
          @n+=1
        else
          __symlink_relative_to from, to
          Find.prune
        end
      end
    end
  end

public
  def ln
    # yeah indeed, you have to force anything you need in the main tree into
    # these dirs REMEMBER that *NOT* everything needs to be in the main tree
    # TODO consider using hardlinks
    @n=0

    __ln('etc') {:mkpath}
    __ln('bin') {:link}
    __ln('lib') {|path| :mkpath if ['pkgconfig','php'].include? path.to_s}
    __ln('include') {:link}

    mkpaths=(1..9).collect {|x| "man/man#{x}"} <<'man'<<'doc'<<'locale'<<'info'<<'aclocal'
    __ln('share') {|path| :mkpath if mkpaths.include? path.to_s}

    return @n
  end
end