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
|
require "fileutils"
require "tmpdir"
require "etc"
# Homebrew extends Ruby's `FileUtils` to make our code more readable.
# @see http://ruby-doc.org/stdlib-1.8.7/libdoc/fileutils/rdoc/FileUtils.html Ruby's FileUtils API
module FileUtils
# Create a temporary directory then yield. When the block returns,
# recursively delete the temporary directory. Passing opts[:retain]
# or calling `do |staging| ... staging.retain!` in the block will skip
# the deletion and retain the temporary directory's contents.
def mktemp(prefix = name, opts = {})
Mktemp.new(prefix, opts).run do |staging|
yield staging
end
end
module_function :mktemp
# Performs mktemp's functionality, and tracks the results.
# Each instance is only intended to be used once.
class Mktemp
include FileUtils
# Path to the tmpdir used in this run, as a Pathname.
attr_reader :tmpdir
def initialize(prefix = name, opts = {})
@prefix = prefix
@retain = opts[:retain]
@quiet = false
end
# Instructs this Mktemp to retain the staged files
def retain!
@retain = true
end
# True if the staged temporary files should be retained
def retain?
@retain
end
# Instructs this Mktemp to not emit messages when retention is triggered
def quiet!
@quiet = true
end
def to_s
"[Mktemp: #{tmpdir} retain=#{@retain} quiet=#{@quiet}]"
end
def run
@tmpdir = Pathname.new(Dir.mktmpdir("#{@prefix}-", HOMEBREW_TEMP))
# Make sure files inside the temporary directory have the same group as the
# brew instance.
#
# Reference from `man 2 open`
# > When a new file is created, it is given the group of the directory which
# contains it.
group_id = if HOMEBREW_BREW_FILE.grpowned?
HOMEBREW_BREW_FILE.stat.gid
else
Process.gid
end
begin
chown(nil, group_id, tmpdir)
rescue Errno::EPERM
opoo "Failed setting group \"#{Etc.getgrgid(group_id).name}\" on #{tmpdir}"
end
begin
Dir.chdir(tmpdir) { yield self }
ensure
ignore_interrupts { rm_rf(tmpdir) } unless retain?
end
ensure
if retain? && !@tmpdir.nil? && !@quiet
ohai "Kept temporary files"
puts "Temporary files retained at #{@tmpdir}"
end
end
end
# @private
alias_method :old_mkdir, :mkdir
# A version of mkdir that also changes to that folder in a block.
def mkdir(name, &_block)
old_mkdir(name)
if block_given?
chdir name do
yield
end
end
end
module_function :mkdir
# Run `scons` using a Homebrew-installed version rather than whatever is in the `PATH`.
def scons(*args)
system Formulary.factory("scons").opt_bin/"scons", *args
end
# Run the `rake` from the `ruby` Homebrew is using rather than whatever is in the `PATH`.
def rake(*args)
system RUBY_BIN/"rake", *args
end
# Run `make` 3.81 or newer.
# Uses the system make on Leopard and newer, and the
# path to the actually-installed make on Tiger or older.
def make(*args)
if Utils.popen_read("/usr/bin/make", "--version").match(/Make (\d\.\d+)/)[1] > "3.80"
system "/usr/bin/make", *args
else
make = Formula["make"].opt_bin/"make"
make_path = make.exist? ? make.to_s : (Formula["make"].opt_bin/"gmake").to_s
system make_path, *args
end
end
if method_defined?(:ruby)
# @private
alias_method :old_ruby, :ruby
end
# Run the `ruby` Homebrew is using rather than whatever is in the `PATH`.
def ruby(*args)
system RUBY_PATH, *args
end
# Run `xcodebuild` without Homebrew's compiler environment variables set.
def xcodebuild(*args)
removed = ENV.remove_cc_etc
system "xcodebuild", *args
ensure
ENV.update(removed)
end
end
|