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
|
module Homebrew
def tap
if ARGV.empty?
each_tap do |user, repo|
puts "#{user.basename}/#{repo.basename.sub("homebrew-", "")}" if (repo/".git").directory?
end
elsif ARGV.first == "--repair"
repair_taps
else
opoo "Already tapped!" unless install_tap(*tap_args)
end
end
def install_tap user, repo
# 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}/homebrew-#{repo.downcase}"
return false if tapd.directory?
ohai "Tapping #{repouser}/#{repo}"
abort unless system "git", "clone", "https://github.com/#{repouser}/homebrew-#{repo}", tapd.to_s
files = []
tapd.find_formula { |file| files << file }
link_tap_formula(files)
puts "Tapped #{files.length} formula#{plural(files.length, 'e')} (#{tapd.abv})"
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(paths, warn_about_conflicts=true)
ignores = (HOMEBREW_LIBRARY/"Formula/.gitignore").read.split rescue []
tapped = 0
paths.each do |path|
to = HOMEBREW_LIBRARY.join("Formula", path.basename)
# Unexpected, but possible, lets proceed as if nothing happened
to.delete if to.symlink? && to.resolved_path == path
begin
to.make_relative_symlink(path)
rescue SystemCallError
to = to.resolved_path if to.symlink?
opoo <<-EOS.undent if warn_about_conflicts
Could not create link for #{Tty.white}#{tap_ref(path)}#{Tty.reset}, as it
conflicts with #{Tty.white}#{tap_ref(to)}#{Tty.reset}. You will need to use the
fully-qualified name when referring this formula, e.g.
brew install #{tap_ref(path)}
EOS
else
ignores << path.basename.to_s
tapped += 1
end
end
HOMEBREW_LIBRARY.join("Formula/.gitignore").atomic_write(ignores.uniq.join("\n"))
tapped
end
def repair_taps(warn_about_conflicts=true)
count = 0
# prune dead symlinks in Formula
Dir.glob("#{HOMEBREW_LIBRARY}/Formula/*.rb") do |fn|
if not File.exist? fn
File.delete fn
count += 1
end
end
puts "Pruned #{count} dead formula#{plural(count, 'e')}"
return unless HOMEBREW_REPOSITORY.join("Library/Taps").exist?
count = 0
# check symlinks are all set in each tap
each_tap do |user, repo|
files = []
repo.find_formula { |file| files << file }
count += link_tap_formula(files, warn_about_conflicts)
end
puts "Tapped #{count} formula#{plural(count, 'e')}"
end
private
def each_tap
taps = HOMEBREW_LIBRARY.join("Taps")
if taps.directory?
taps.subdirs.each do |user|
user.subdirs.each do |repo|
yield user, repo
end
end
end
end
def tap_args(tap_name=ARGV.first)
tap_name =~ HOMEBREW_TAP_ARGS_REGEX
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
def tap_ref(path)
case path.to_s
when %r{^#{Regexp.escape(HOMEBREW_LIBRARY.to_s)}/Formula}o
"Homebrew/homebrew/#{path.basename(".rb")}"
when HOMEBREW_TAP_PATH_REGEX
"#{$1}/#{$2.sub("homebrew-", "")}/#{path.basename(".rb")}"
end
end
end
|