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
|
module Homebrew extend self
def tap
if ARGV.empty?
tapd = HOMEBREW_LIBRARY/"Taps"
tapd.children.each do |tap|
# only replace the *last* dash: yes, tap filenames suck
puts tap.basename.to_s.reverse.sub('-', '/').reverse if (tap/'.git').directory?
end if tapd.directory?
elsif ARGV.first == "--repair"
repair_taps
else
opoo "Already tapped!" unless install_tap(*tap_args)
end
end
def install_tap user, repo
raise "brew install git" unless which 'git'
# we special case homebrew so users don't have to shift in a terminal
repouser = if user == "homebrew" then "Homebrew" else user end
user = "homebrew" if user == "Homebrew"
# we downcase to avoid case-insensitive filesystem issues
tapd = HOMEBREW_LIBRARY/"Taps/#{user.downcase}-#{repo.downcase}"
return false if tapd.directory?
abort unless system "git clone https://github.com/#{repouser}/homebrew-#{repo} #{tapd}"
files = []
tapd.find_formula{ |file| files << tapd.basename.join(file) }
link_tap_formula(files)
puts "Tapped #{files.length} formula"
if private_tap?(repouser, repo) then puts <<-EOS.undent
It looks like you tapped a private repository. To avoid entering your
credentials each time you update, you can use git HTTP credential caching
or issue the following command:
cd #{tapd}
git remote set-url origin git@github.com:#{repouser}/homebrew-#{repo}.git
EOS
end
true
end
def link_tap_formula formulae
ignores = (HOMEBREW_LIBRARY/"Formula/.gitignore").read.split rescue []
tapped = 0
cd HOMEBREW_LIBRARY/"Formula" do
formulae.each do |formula|
from = HOMEBREW_LIBRARY.join("Taps/#{formula}")
to = HOMEBREW_LIBRARY.join("Formula/#{formula.basename}")
# Unexpected, but possible, lets proceed as if nothing happened
to.delete if to.symlink? and to.realpath == from
# using the system ln is the only way to get relative symlinks
system "ln -s ../Taps/#{formula} 2>/dev/null"
if $?.success?
ignores << formula.basename.to_s
tapped += 1
else
to = to.realpath if to.exist?
# Whitelist gcc42 temporarily until Mavericks/Xcode 5.0 issues are resolved.
unless to.tap_ref == 'Homebrew/homebrew/apple-gcc42'
opoo "Could not tap #{Tty.white}#{from.tap_ref}#{Tty.reset} over #{Tty.white}#{to.tap_ref}#{Tty.reset}"
end
end
end
end
HOMEBREW_LIBRARY.join("Formula/.gitignore").atomic_write(ignores.uniq.join("\n"))
tapped
end
def repair_taps
count = 0
# prune dead symlinks in Formula
Dir["#{HOMEBREW_LIBRARY}/Formula/*.rb"].each do |fn|
if not File.exist? fn
File.delete fn
count += 1
end
end
puts "Pruned #{count} dead formula"
return unless HOMEBREW_REPOSITORY.join("Library/Taps").exist?
count = 0
# check symlinks are all set in each tap
HOMEBREW_REPOSITORY.join("Library/Taps").children.each do |tap|
files = []
tap.find_formula{ |file| files << tap.basename.join(file) } if tap.directory?
count += link_tap_formula(files)
end
puts "Tapped #{count} formula"
end
private
def tap_args
ARGV.first =~ %r{^(\S+)/(homebrew-)?(\w+)$}
raise "Invalid tap name" unless $1 && $3
[$1, $3]
end
def private_tap?(user, repo)
GitHub.private_repo?(user, "homebrew-#{repo}")
rescue GitHub::HTTPNotFoundError
true
rescue GitHub::Error
false
end
end
class Pathname
def tap_ref
case self.to_s
when %r{^#{HOMEBREW_LIBRARY}/Taps/([a-z\-_]+)-(\w+)/(.+)}
"#$1/#$2/#{File.basename($3, '.rb')}"
when %r{^#{HOMEBREW_LIBRARY}/Formula/(.+)}
"Homebrew/homebrew/#{File.basename($1, '.rb')}"
else
nil
end
end
end
|