forked from Homebrew/legacy-homebrew
/
keg.rb
159 lines (140 loc) · 4.58 KB
/
keg.rb
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
154
155
156
157
158
159
# 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 '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
path=HOMEBREW_CELLAR+formula
kids=path.children
raise "Empty installation: #{path}" if kids.length < 1
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
# don't rmtree shit if we aren't positive about our location!
raise "Bad stuff!" unless path.parent.parent == HOMEBREW_CELLAR
if path.directory?
FileUtils.chmod_R 0777, path # ensure we have permission to delete
path.rmtree # HOMEBREW_CELLAR/foo/1.2.0
path.parent.rmdir if path.parent.children.length == 0 # HOMEBREW_CELLAR/foo
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?
root=Pathname.new HOMEBREW_PREFIX
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