archruby 0.2.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +3 -0
- data/README.md +1 -1
- data/Rakefile +46 -0
- data/TODO.rtf +20 -0
- data/architecture.yml +51 -0
- data/archruby.gemspec +3 -0
- data/bin/archruby +1 -0
- data/lib/archruby.rb +14 -2
- data/lib/archruby/architecture/architecture.rb +6 -6
- data/lib/archruby/architecture/config_definition.rb +13 -13
- data/lib/archruby/architecture/constraint_break.rb +1 -1
- data/lib/archruby/architecture/dependency.rb +3 -1
- data/lib/archruby/architecture/file_content.rb +2 -2
- data/lib/archruby/architecture/module_definition.rb +33 -20
- data/lib/archruby/architecture/parser.rb +25 -11
- data/lib/archruby/architecture/type_inference_checker.rb +29 -13
- data/lib/archruby/presenters/dsm.rb +163 -0
- data/lib/archruby/presenters/dsm/cell_dsm.rb +17 -0
- data/lib/archruby/presenters/dsm/dsm_css.css +77 -0
- data/lib/archruby/presenters/graph.rb +12 -9
- data/lib/archruby/ruby/parser.rb +131 -125
- data/lib/archruby/ruby/type_inference/dependency_organizer.rb +53 -0
- data/lib/archruby/ruby/type_inference/ruby/class_dependency.rb +22 -0
- data/lib/archruby/ruby/type_inference/ruby/internal_method_invocation.rb +20 -0
- data/lib/archruby/ruby/type_inference/ruby/method_definition.rb +20 -0
- data/lib/archruby/ruby/type_inference/ruby/parser_for_typeinference.rb +537 -0
- data/lib/archruby/ruby/type_inference/ruby/process_method_arguments.rb +155 -0
- data/lib/archruby/ruby/type_inference/ruby/process_method_body.rb +427 -0
- data/lib/archruby/ruby/type_inference/ruby/process_method_params.rb +276 -0
- data/lib/archruby/ruby/type_inference/type_inference_checker.rb +126 -0
- data/lib/archruby/version.rb +1 -1
- data/spec/architecture/file_content_spec.rb +2 -1
- data/spec/architecture/module_definition_spec.rb +9 -9
- data/spec/dummy_app/lib/teste_class.rb +6 -0
- data/spec/ruby/type_inference/dependency_organizer_spec.rb +20 -0
- data/spec/ruby/type_inference/fixtures/homebrew_bottles_class.rb +139 -0
- data/spec/ruby/type_inference/fixtures/homebrew_brew_teste.rb +1323 -0
- data/spec/ruby/type_inference/fixtures/rails_action_view_class_teste.rb +89 -0
- data/spec/ruby/type_inference/fixtures/rails_active_record_class.rb +99 -0
- data/spec/ruby/type_inference/fixtures/rails_teste_active_record.rb +55 -0
- data/spec/ruby/type_inference/fixtures/teste2.rb +16 -0
- data/spec/ruby/type_inference/fixtures/teste_class_and_args.rb +49 -0
- data/spec/ruby/type_inference/fixtures/teste_class_and_args2.rb +11 -0
- data/spec/ruby/type_inference/parser_for_typeinference_spec.rb +69 -0
- data/spec/ruby/type_inference/type_inference_checker_spec.rb +47 -0
- metadata +84 -3
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Archruby::Ruby::TypeInference::DependencyOrganizer do
|
4
|
+
before do
|
5
|
+
@fixtures_path = File.expand_path('../fixtures', __FILE__)
|
6
|
+
end
|
7
|
+
|
8
|
+
it "mantains the dependencies and methods invocations correctly" do
|
9
|
+
parser = Archruby::Ruby::TypeInference::Ruby::ParserForTypeinference.new
|
10
|
+
file_content = File.read("#{@fixtures_path}/rails_action_view_class_teste.rb")
|
11
|
+
dependencies, methods_calls = parser.parse(file_content)
|
12
|
+
dependency_organizer = Archruby::Ruby::TypeInference::DependencyOrganizer.new
|
13
|
+
dependency_organizer.add_dependencies(dependencies)
|
14
|
+
dependency_organizer.add_method_calls(methods_calls)
|
15
|
+
# acho que vou manter um hash com o nome da classe e o valor vai
|
16
|
+
# ser um set com todas as dependencias dessa classe
|
17
|
+
|
18
|
+
# Tenho que decidir o que vou fazer com as chamadas de metodo ainda
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,139 @@
|
|
1
|
+
require "tab"
|
2
|
+
require "os/mac"
|
3
|
+
require "extend/ARGV"
|
4
|
+
|
5
|
+
def built_as_bottle?(f)
|
6
|
+
return false unless f.installed?
|
7
|
+
tab = Tab.for_keg(f.installed_prefix)
|
8
|
+
tab.built_as_bottle
|
9
|
+
end
|
10
|
+
|
11
|
+
def bottle_file_outdated?(f, file)
|
12
|
+
filename = file.basename.to_s
|
13
|
+
return unless f.bottle && filename.match(Pathname::BOTTLE_EXTNAME_RX)
|
14
|
+
|
15
|
+
bottle_ext = filename[bottle_native_regex, 1]
|
16
|
+
bottle_url_ext = f.bottle.url[bottle_native_regex, 1]
|
17
|
+
|
18
|
+
bottle_ext && bottle_url_ext && bottle_ext != bottle_url_ext
|
19
|
+
end
|
20
|
+
|
21
|
+
def bottle_native_regex
|
22
|
+
/(\.#{bottle_tag}\.bottle\.(\d+\.)?tar\.gz)$/o
|
23
|
+
end
|
24
|
+
|
25
|
+
def bottle_tag
|
26
|
+
if MacOS.version >= :lion
|
27
|
+
MacOS.cat
|
28
|
+
elsif MacOS.version == :snow_leopard
|
29
|
+
Hardware::CPU.is_64_bit? ? :snow_leopard : :snow_leopard_32
|
30
|
+
else
|
31
|
+
# Return, e.g., :tiger_g3, :leopard_g5_64, :leopard_64 (which is Intel)
|
32
|
+
if Hardware::CPU.type == :ppc
|
33
|
+
tag = "#{MacOS.cat}_#{Hardware::CPU.family}".to_sym
|
34
|
+
else
|
35
|
+
tag = MacOS.cat
|
36
|
+
end
|
37
|
+
MacOS.prefer_64_bit? ? "#{tag}_64".to_sym : tag
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def bottle_receipt_path(bottle_file)
|
42
|
+
Utils.popen_read("tar", "-tzf", bottle_file, "*/*/INSTALL_RECEIPT.json").chomp
|
43
|
+
end
|
44
|
+
|
45
|
+
def bottle_resolve_formula_names(bottle_file)
|
46
|
+
receipt_file_path = bottle_receipt_path bottle_file
|
47
|
+
receipt_file = Utils.popen_read("tar", "-xOzf", bottle_file, receipt_file_path)
|
48
|
+
name = receipt_file_path.split("/").first
|
49
|
+
tap = Tab.from_file_content(receipt_file, "#{bottle_file}/#{receipt_file_path}").tap
|
50
|
+
|
51
|
+
if tap.nil? || tap == "Homebrew/homebrew"
|
52
|
+
full_name = name
|
53
|
+
else
|
54
|
+
full_name = "#{tap.sub("homebrew-", "")}/#{name}"
|
55
|
+
end
|
56
|
+
|
57
|
+
[name, full_name]
|
58
|
+
end
|
59
|
+
|
60
|
+
def bottle_resolve_version(bottle_file)
|
61
|
+
PkgVersion.parse bottle_receipt_path(bottle_file).split("/")[1]
|
62
|
+
end
|
63
|
+
|
64
|
+
class Bintray
|
65
|
+
def self.package(formula_name)
|
66
|
+
formula_name.to_s.tr("+", "x")
|
67
|
+
end
|
68
|
+
|
69
|
+
def self.repository(tap = nil)
|
70
|
+
return "bottles" if tap.nil? || tap == "Homebrew/homebrew"
|
71
|
+
"bottles-#{tap.sub(%r{^homebrew/(homebrew-)?}i, "")}"
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
class BottleCollector
|
76
|
+
def initialize
|
77
|
+
@checksums = {}
|
78
|
+
end
|
79
|
+
|
80
|
+
def fetch_checksum_for(tag)
|
81
|
+
tag = find_matching_tag(tag)
|
82
|
+
return self[tag], tag if tag
|
83
|
+
end
|
84
|
+
|
85
|
+
def keys
|
86
|
+
@checksums.keys
|
87
|
+
end
|
88
|
+
|
89
|
+
def [](key)
|
90
|
+
@checksums[key]
|
91
|
+
end
|
92
|
+
|
93
|
+
def []=(key, value)
|
94
|
+
@checksums[key] = value
|
95
|
+
end
|
96
|
+
|
97
|
+
def key?(key)
|
98
|
+
@checksums.key?(key)
|
99
|
+
end
|
100
|
+
|
101
|
+
private
|
102
|
+
|
103
|
+
def find_matching_tag(tag)
|
104
|
+
if key?(tag)
|
105
|
+
tag
|
106
|
+
else
|
107
|
+
find_altivec_tag(tag) || find_or_later_tag(tag)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
# This allows generic Altivec PPC bottles to be supported in some
|
112
|
+
# formulae, while also allowing specific bottles in others; e.g.,
|
113
|
+
# sometimes a formula has just :tiger_altivec, other times it has
|
114
|
+
# :tiger_g4, :tiger_g5, etc.
|
115
|
+
def find_altivec_tag(tag)
|
116
|
+
if tag.to_s =~ /(\w+)_(g4|g4e|g5)$/
|
117
|
+
altivec_tag = "#{$1}_altivec".to_sym
|
118
|
+
altivec_tag if key?(altivec_tag)
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
# Allows a bottle tag to specify a specific OS or later,
|
123
|
+
# so the same bottle can target multiple OSs.
|
124
|
+
# Not used in core, used in taps.
|
125
|
+
def find_or_later_tag(tag)
|
126
|
+
begin
|
127
|
+
tag_version = MacOS::Version.from_symbol(tag)
|
128
|
+
rescue ArgumentError
|
129
|
+
return
|
130
|
+
end
|
131
|
+
|
132
|
+
keys.find do |key|
|
133
|
+
if key.to_s.end_with?("_or_later")
|
134
|
+
later_tag = key.to_s[/(\w+)_or_later$/, 1].to_sym
|
135
|
+
MacOS::Version.from_symbol(later_tag) <= tag_version
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
@@ -0,0 +1,1323 @@
|
|
1
|
+
require "cmd/missing"
|
2
|
+
require "formula"
|
3
|
+
require "keg"
|
4
|
+
require "language/python"
|
5
|
+
require "version"
|
6
|
+
|
7
|
+
class Volumes
|
8
|
+
def initialize
|
9
|
+
@volumes = get_mounts
|
10
|
+
end
|
11
|
+
|
12
|
+
def which(path)
|
13
|
+
vols = get_mounts path
|
14
|
+
|
15
|
+
# no volume found
|
16
|
+
if vols.empty?
|
17
|
+
return -1
|
18
|
+
end
|
19
|
+
|
20
|
+
vol_index = @volumes.index(vols[0])
|
21
|
+
# volume not found in volume list
|
22
|
+
if vol_index.nil?
|
23
|
+
return -1
|
24
|
+
end
|
25
|
+
vol_index
|
26
|
+
end
|
27
|
+
|
28
|
+
def get_mounts(path = nil)
|
29
|
+
vols = []
|
30
|
+
# get the volume of path, if path is nil returns all volumes
|
31
|
+
|
32
|
+
args = %w[/bin/df -P]
|
33
|
+
args << path if path
|
34
|
+
|
35
|
+
Utils.popen_read(*args) do |io|
|
36
|
+
io.each_line do |line|
|
37
|
+
case line.chomp
|
38
|
+
# regex matches: /dev/disk0s2 489562928 440803616 48247312 91% /
|
39
|
+
when /^.+\s+[0-9]+\s+[0-9]+\s+[0-9]+\s+[0-9]{1,3}%\s+(.+)/
|
40
|
+
vols << $1
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
vols
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
class Checks
|
49
|
+
############# HELPERS
|
50
|
+
# Finds files in HOMEBREW_PREFIX *and* /usr/local.
|
51
|
+
# Specify paths relative to a prefix eg. "include/foo.h".
|
52
|
+
# Sets @found for your convenience.
|
53
|
+
def find_relative_paths(*relative_paths)
|
54
|
+
@found = %W[#{HOMEBREW_PREFIX} /usr/local].uniq.inject([]) do |found, prefix|
|
55
|
+
found + relative_paths.map { |f| File.join(prefix, f) }.select { |f| File.exist? f }
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def inject_file_list(list, str)
|
60
|
+
list.inject(str) { |s, f| s << " #{f}\n" }
|
61
|
+
end
|
62
|
+
|
63
|
+
# Git will always be on PATH because of the wrapper script in
|
64
|
+
# Library/ENV/scm, so we check if there is a *real*
|
65
|
+
# git here to avoid multiple warnings.
|
66
|
+
def git?
|
67
|
+
return @git if instance_variable_defined?(:@git)
|
68
|
+
@git = system "git --version >/dev/null 2>&1"
|
69
|
+
end
|
70
|
+
############# END HELPERS
|
71
|
+
|
72
|
+
# Sorry for the lack of an indent here, the diff would have been unreadable.
|
73
|
+
# See https://github.com/Homebrew/homebrew/pull/9986
|
74
|
+
def check_path_for_trailing_slashes
|
75
|
+
bad_paths = ENV["PATH"].split(File::PATH_SEPARATOR).select { |p| p[-1..-1] == "/" }
|
76
|
+
return if bad_paths.empty?
|
77
|
+
s = <<-EOS.undent
|
78
|
+
Some directories in your path end in a slash.
|
79
|
+
Directories in your path should not end in a slash. This can break other
|
80
|
+
doctor checks. The following directories should be edited:
|
81
|
+
EOS
|
82
|
+
bad_paths.each { |p| s << " #{p}" }
|
83
|
+
s
|
84
|
+
end
|
85
|
+
|
86
|
+
# Installing MacGPG2 interferes with Homebrew in a big way
|
87
|
+
# https://github.com/GPGTools/MacGPG2
|
88
|
+
def check_for_macgpg2
|
89
|
+
return if File.exist? "/usr/local/MacGPG2/share/gnupg/VERSION"
|
90
|
+
|
91
|
+
suspects = %w[
|
92
|
+
/Applications/start-gpg-agent.app
|
93
|
+
/Library/Receipts/libiconv1.pkg
|
94
|
+
/usr/local/MacGPG2
|
95
|
+
]
|
96
|
+
|
97
|
+
if suspects.any? { |f| File.exist? f } then <<-EOS.undent
|
98
|
+
You may have installed MacGPG2 via the package installer.
|
99
|
+
Several other checks in this script will turn up problems, such as stray
|
100
|
+
dylibs in /usr/local and permissions issues with share and man in /usr/local/.
|
101
|
+
EOS
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
def __check_stray_files(dir, pattern, white_list, message)
|
106
|
+
return unless File.directory?(dir)
|
107
|
+
|
108
|
+
files = Dir.chdir(dir) do
|
109
|
+
Dir[pattern].select { |f| File.file?(f) && !File.symlink?(f) } - Dir.glob(white_list)
|
110
|
+
end.map { |file| File.join(dir, file) }
|
111
|
+
|
112
|
+
inject_file_list(files, message) unless files.empty?
|
113
|
+
end
|
114
|
+
|
115
|
+
def check_for_stray_dylibs
|
116
|
+
# Dylibs which are generally OK should be added to this list,
|
117
|
+
# with a short description of the software they come with.
|
118
|
+
white_list = [
|
119
|
+
"libfuse.2.dylib", # MacFuse
|
120
|
+
"libfuse_ino64.2.dylib", # MacFuse
|
121
|
+
"libmacfuse_i32.2.dylib", # OSXFuse MacFuse compatibility layer
|
122
|
+
"libmacfuse_i64.2.dylib", # OSXFuse MacFuse compatibility layer
|
123
|
+
"libosxfuse_i32.2.dylib", # OSXFuse
|
124
|
+
"libosxfuse_i64.2.dylib", # OSXFuse
|
125
|
+
"libTrAPI.dylib", # TrAPI / Endpoint Security VPN
|
126
|
+
"libntfs-3g.*.dylib", # NTFS-3G
|
127
|
+
"libntfs.*.dylib", # NTFS-3G
|
128
|
+
"libublio.*.dylib", # NTFS-3G
|
129
|
+
]
|
130
|
+
|
131
|
+
__check_stray_files "/usr/local/lib", "*.dylib", white_list, <<-EOS.undent
|
132
|
+
Unbrewed dylibs were found in /usr/local/lib.
|
133
|
+
If you didn't put them there on purpose they could cause problems when
|
134
|
+
building Homebrew formulae, and may need to be deleted.
|
135
|
+
|
136
|
+
Unexpected dylibs:
|
137
|
+
EOS
|
138
|
+
end
|
139
|
+
|
140
|
+
def check_for_stray_static_libs
|
141
|
+
# Static libs which are generally OK should be added to this list,
|
142
|
+
# with a short description of the software they come with.
|
143
|
+
white_list = [
|
144
|
+
"libsecurity_agent_client.a", # OS X 10.8.2 Supplemental Update
|
145
|
+
"libsecurity_agent_server.a", # OS X 10.8.2 Supplemental Update
|
146
|
+
"libntfs-3g.a", # NTFS-3G
|
147
|
+
"libntfs.a", # NTFS-3G
|
148
|
+
"libublio.a", # NTFS-3G
|
149
|
+
]
|
150
|
+
|
151
|
+
__check_stray_files "/usr/local/lib", "*.a", white_list, <<-EOS.undent
|
152
|
+
Unbrewed static libraries were found in /usr/local/lib.
|
153
|
+
If you didn't put them there on purpose they could cause problems when
|
154
|
+
building Homebrew formulae, and may need to be deleted.
|
155
|
+
|
156
|
+
Unexpected static libraries:
|
157
|
+
EOS
|
158
|
+
end
|
159
|
+
|
160
|
+
def check_for_stray_pcs
|
161
|
+
# Package-config files which are generally OK should be added to this list,
|
162
|
+
# with a short description of the software they come with.
|
163
|
+
white_list = [
|
164
|
+
"fuse.pc", # OSXFuse/MacFuse
|
165
|
+
"macfuse.pc", # OSXFuse MacFuse compatibility layer
|
166
|
+
"osxfuse.pc", # OSXFuse
|
167
|
+
"libntfs-3g.pc", # NTFS-3G
|
168
|
+
"libublio.pc", # NTFS-3G
|
169
|
+
]
|
170
|
+
|
171
|
+
__check_stray_files "/usr/local/lib/pkgconfig", "*.pc", white_list, <<-EOS.undent
|
172
|
+
Unbrewed .pc files were found in /usr/local/lib/pkgconfig.
|
173
|
+
If you didn't put them there on purpose they could cause problems when
|
174
|
+
building Homebrew formulae, and may need to be deleted.
|
175
|
+
|
176
|
+
Unexpected .pc files:
|
177
|
+
EOS
|
178
|
+
end
|
179
|
+
|
180
|
+
def check_for_stray_las
|
181
|
+
white_list = [
|
182
|
+
"libfuse.la", # MacFuse
|
183
|
+
"libfuse_ino64.la", # MacFuse
|
184
|
+
"libosxfuse_i32.la", # OSXFuse
|
185
|
+
"libosxfuse_i64.la", # OSXFuse
|
186
|
+
"libntfs-3g.la", # NTFS-3G
|
187
|
+
"libntfs.la", # NTFS-3G
|
188
|
+
"libublio.la", # NTFS-3G
|
189
|
+
]
|
190
|
+
|
191
|
+
__check_stray_files "/usr/local/lib", "*.la", white_list, <<-EOS.undent
|
192
|
+
Unbrewed .la files were found in /usr/local/lib.
|
193
|
+
If you didn't put them there on purpose they could cause problems when
|
194
|
+
building Homebrew formulae, and may need to be deleted.
|
195
|
+
|
196
|
+
Unexpected .la files:
|
197
|
+
EOS
|
198
|
+
end
|
199
|
+
|
200
|
+
def check_for_stray_headers
|
201
|
+
white_list = [
|
202
|
+
"fuse.h", # MacFuse
|
203
|
+
"fuse/**/*.h", # MacFuse
|
204
|
+
"macfuse/**/*.h", # OSXFuse MacFuse compatibility layer
|
205
|
+
"osxfuse/**/*.h", # OSXFuse
|
206
|
+
"ntfs/**/*.h", # NTFS-3G
|
207
|
+
"ntfs-3g/**/*.h", # NTFS-3G
|
208
|
+
]
|
209
|
+
|
210
|
+
__check_stray_files "/usr/local/include", "**/*.h", white_list, <<-EOS.undent
|
211
|
+
Unbrewed header files were found in /usr/local/include.
|
212
|
+
If you didn't put them there on purpose they could cause problems when
|
213
|
+
building Homebrew formulae, and may need to be deleted.
|
214
|
+
|
215
|
+
Unexpected header files:
|
216
|
+
EOS
|
217
|
+
end
|
218
|
+
|
219
|
+
def check_for_other_package_managers
|
220
|
+
ponk = MacOS.macports_or_fink
|
221
|
+
unless ponk.empty?
|
222
|
+
<<-EOS.undent
|
223
|
+
You have MacPorts or Fink installed:
|
224
|
+
#{ponk.join(", ")}
|
225
|
+
|
226
|
+
This can cause trouble. You don't have to uninstall them, but you may want to
|
227
|
+
temporarily move them out of the way, e.g.
|
228
|
+
|
229
|
+
sudo mv /opt/local ~/macports
|
230
|
+
EOS
|
231
|
+
end
|
232
|
+
end
|
233
|
+
|
234
|
+
def check_for_broken_symlinks
|
235
|
+
broken_symlinks = []
|
236
|
+
|
237
|
+
Keg::PRUNEABLE_DIRECTORIES.each do |d|
|
238
|
+
next unless d.directory?
|
239
|
+
d.find do |path|
|
240
|
+
if path.symlink? && !path.resolved_path_exists?
|
241
|
+
broken_symlinks << path
|
242
|
+
end
|
243
|
+
end
|
244
|
+
end
|
245
|
+
unless broken_symlinks.empty? then <<-EOS.undent
|
246
|
+
Broken symlinks were found. Remove them with `brew prune`:
|
247
|
+
#{broken_symlinks * "\n "}
|
248
|
+
EOS
|
249
|
+
end
|
250
|
+
end
|
251
|
+
|
252
|
+
def check_for_unsupported_osx
|
253
|
+
if MacOS.version >= "10.11" then <<-EOS.undent
|
254
|
+
You are using OS X #{MacOS.version}.
|
255
|
+
We do not provide support for this pre-release version.
|
256
|
+
You may encounter build failures or other breakage.
|
257
|
+
EOS
|
258
|
+
end
|
259
|
+
end
|
260
|
+
|
261
|
+
# TODO: distill down into single method definition a la BuildToolsError
|
262
|
+
if MacOS.version >= "10.9"
|
263
|
+
def check_for_installed_developer_tools
|
264
|
+
unless MacOS::Xcode.installed? || MacOS::CLT.installed? then <<-EOS.undent
|
265
|
+
No developer tools installed.
|
266
|
+
Install the Command Line Tools:
|
267
|
+
xcode-select --install
|
268
|
+
EOS
|
269
|
+
end
|
270
|
+
end
|
271
|
+
|
272
|
+
# TODO: remove when 10.11 is released
|
273
|
+
if MacOS.version >= "10.11"
|
274
|
+
def check_xcode_up_to_date
|
275
|
+
if MacOS::Xcode.installed? && MacOS::Xcode.outdated?
|
276
|
+
<<-EOS.undent
|
277
|
+
Your Xcode (#{MacOS::Xcode.version}) is outdated
|
278
|
+
Please update to Xcode #{MacOS::Xcode.latest_version}.
|
279
|
+
Xcode can be updated from
|
280
|
+
https://developer.apple.com/xcode/downloads/
|
281
|
+
EOS
|
282
|
+
end
|
283
|
+
end
|
284
|
+
else
|
285
|
+
def check_xcode_up_to_date
|
286
|
+
if MacOS::Xcode.installed? && MacOS::Xcode.outdated?
|
287
|
+
<<-EOS.undent
|
288
|
+
Your Xcode (#{MacOS::Xcode.version}) is outdated
|
289
|
+
Please update to Xcode #{MacOS::Xcode.latest_version}.
|
290
|
+
Xcode can be updated from the App Store.
|
291
|
+
EOS
|
292
|
+
end
|
293
|
+
end
|
294
|
+
end
|
295
|
+
|
296
|
+
def check_clt_up_to_date
|
297
|
+
if MacOS::CLT.installed? && MacOS::CLT.outdated? then <<-EOS.undent
|
298
|
+
A newer Command Line Tools release is available.
|
299
|
+
Update them from Software Update in the App Store.
|
300
|
+
EOS
|
301
|
+
end
|
302
|
+
end
|
303
|
+
elsif MacOS.version == "10.8" || MacOS.version == "10.7"
|
304
|
+
def check_for_installed_developer_tools
|
305
|
+
unless MacOS::Xcode.installed? || MacOS::CLT.installed? then <<-EOS.undent
|
306
|
+
No developer tools installed.
|
307
|
+
You should install the Command Line Tools.
|
308
|
+
The standalone package can be obtained from
|
309
|
+
https://developer.apple.com/downloads
|
310
|
+
or it can be installed via Xcode's preferences.
|
311
|
+
EOS
|
312
|
+
end
|
313
|
+
end
|
314
|
+
|
315
|
+
def check_xcode_up_to_date
|
316
|
+
if MacOS::Xcode.installed? && MacOS::Xcode.outdated? then <<-EOS.undent
|
317
|
+
Your Xcode (#{MacOS::Xcode.version}) is outdated
|
318
|
+
Please update to Xcode #{MacOS::Xcode.latest_version}.
|
319
|
+
Xcode can be updated from
|
320
|
+
https://developer.apple.com/xcode/downloads/
|
321
|
+
EOS
|
322
|
+
end
|
323
|
+
end
|
324
|
+
|
325
|
+
def check_clt_up_to_date
|
326
|
+
if MacOS::CLT.installed? && MacOS::CLT.outdated? then <<-EOS.undent
|
327
|
+
A newer Command Line Tools release is available.
|
328
|
+
The standalone package can be obtained from
|
329
|
+
https://developer.apple.com/downloads
|
330
|
+
or it can be installed via Xcode's preferences.
|
331
|
+
EOS
|
332
|
+
end
|
333
|
+
end
|
334
|
+
else
|
335
|
+
def check_for_installed_developer_tools
|
336
|
+
unless MacOS::Xcode.installed? then <<-EOS.undent
|
337
|
+
Xcode is not installed. Most formulae need Xcode to build.
|
338
|
+
It can be installed from
|
339
|
+
https://developer.apple.com/xcode/downloads/
|
340
|
+
EOS
|
341
|
+
end
|
342
|
+
end
|
343
|
+
|
344
|
+
def check_xcode_up_to_date
|
345
|
+
if MacOS::Xcode.installed? && MacOS::Xcode.outdated? then <<-EOS.undent
|
346
|
+
Your Xcode (#{MacOS::Xcode.version}) is outdated
|
347
|
+
Please update to Xcode #{MacOS::Xcode.latest_version}.
|
348
|
+
Xcode can be updated from
|
349
|
+
https://developer.apple.com/xcode/downloads/
|
350
|
+
EOS
|
351
|
+
end
|
352
|
+
end
|
353
|
+
end
|
354
|
+
|
355
|
+
def check_for_osx_gcc_installer
|
356
|
+
if (MacOS.version < "10.7" || MacOS::Xcode.version > "4.1") && \
|
357
|
+
MacOS.clang_version == "2.1"
|
358
|
+
message = <<-EOS.undent
|
359
|
+
You seem to have osx-gcc-installer installed.
|
360
|
+
Homebrew doesn't support osx-gcc-installer. It causes many builds to fail and
|
361
|
+
is an unlicensed distribution of really old Xcode files.
|
362
|
+
EOS
|
363
|
+
if MacOS.version >= :mavericks
|
364
|
+
message += <<-EOS.undent
|
365
|
+
Please run `xcode-select --install` to install the CLT.
|
366
|
+
EOS
|
367
|
+
elsif MacOS.version >= :lion
|
368
|
+
message += <<-EOS.undent
|
369
|
+
Please install the CLT or Xcode #{MacOS::Xcode.latest_version}.
|
370
|
+
EOS
|
371
|
+
else
|
372
|
+
message += <<-EOS.undent
|
373
|
+
Please install Xcode #{MacOS::Xcode.latest_version}.
|
374
|
+
EOS
|
375
|
+
end
|
376
|
+
end
|
377
|
+
end
|
378
|
+
|
379
|
+
def check_for_stray_developer_directory
|
380
|
+
# if the uninstaller script isn't there, it's a good guess neither are
|
381
|
+
# any troublesome leftover Xcode files
|
382
|
+
uninstaller = Pathname.new("/Developer/Library/uninstall-developer-folder")
|
383
|
+
if MacOS::Xcode.version >= "4.3" && uninstaller.exist? then <<-EOS.undent
|
384
|
+
You have leftover files from an older version of Xcode.
|
385
|
+
You should delete them using:
|
386
|
+
#{uninstaller}
|
387
|
+
EOS
|
388
|
+
end
|
389
|
+
end
|
390
|
+
|
391
|
+
def check_for_bad_install_name_tool
|
392
|
+
return if MacOS.version < "10.9"
|
393
|
+
|
394
|
+
libs = Pathname.new("/usr/bin/install_name_tool").dynamically_linked_libraries
|
395
|
+
|
396
|
+
# otool may not work, for example if the Xcode license hasn't been accepted yet
|
397
|
+
return if libs.empty?
|
398
|
+
|
399
|
+
unless libs.include? "/usr/lib/libxcselect.dylib" then <<-EOS.undent
|
400
|
+
You have an outdated version of /usr/bin/install_name_tool installed.
|
401
|
+
This will cause binary package installations to fail.
|
402
|
+
This can happen if you install osx-gcc-installer or RailsInstaller.
|
403
|
+
To restore it, you must reinstall OS X or restore the binary from
|
404
|
+
the OS packages.
|
405
|
+
EOS
|
406
|
+
end
|
407
|
+
end
|
408
|
+
|
409
|
+
def __check_subdir_access(base)
|
410
|
+
target = HOMEBREW_PREFIX+base
|
411
|
+
return unless target.exist?
|
412
|
+
|
413
|
+
cant_read = []
|
414
|
+
|
415
|
+
target.find do |d|
|
416
|
+
next unless d.directory?
|
417
|
+
cant_read << d unless d.writable_real?
|
418
|
+
end
|
419
|
+
|
420
|
+
cant_read.sort!
|
421
|
+
if cant_read.length > 0
|
422
|
+
s = <<-EOS.undent
|
423
|
+
Some directories in #{target} aren't writable.
|
424
|
+
This can happen if you "sudo make install" software that isn't managed
|
425
|
+
by Homebrew. If a brew tries to add locale information to one of these
|
426
|
+
directories, then the install will fail during the link step.
|
427
|
+
You should probably `chown` them:
|
428
|
+
|
429
|
+
EOS
|
430
|
+
cant_read.each { |f| s << " #{f}\n" }
|
431
|
+
s
|
432
|
+
end
|
433
|
+
end
|
434
|
+
|
435
|
+
def check_access_share_locale
|
436
|
+
__check_subdir_access "share/locale"
|
437
|
+
end
|
438
|
+
|
439
|
+
def check_access_share_man
|
440
|
+
__check_subdir_access "share/man"
|
441
|
+
end
|
442
|
+
|
443
|
+
def check_access_usr_local
|
444
|
+
return unless HOMEBREW_PREFIX.to_s == "/usr/local"
|
445
|
+
|
446
|
+
unless File.writable_real?("/usr/local") then <<-EOS.undent
|
447
|
+
The /usr/local directory is not writable.
|
448
|
+
Even if this directory was writable when you installed Homebrew, other
|
449
|
+
software may change permissions on this directory. Some versions of the
|
450
|
+
"InstantOn" component of Airfoil are known to do this.
|
451
|
+
|
452
|
+
You should probably change the ownership and permissions of /usr/local
|
453
|
+
back to your user account.
|
454
|
+
EOS
|
455
|
+
end
|
456
|
+
end
|
457
|
+
|
458
|
+
def check_tmpdir_sticky_bit
|
459
|
+
world_writable = HOMEBREW_TEMP.stat.mode & 0777 == 0777
|
460
|
+
if world_writable && !HOMEBREW_TEMP.sticky? then <<-EOS.undent
|
461
|
+
#{HOMEBREW_TEMP} is world-writable but does not have the sticky bit set.
|
462
|
+
Please run "Repair Disk Permissions" in Disk Utility.
|
463
|
+
EOS
|
464
|
+
end
|
465
|
+
end
|
466
|
+
|
467
|
+
(Keg::TOP_LEVEL_DIRECTORIES + ["lib/pkgconfig"]).each do |d|
|
468
|
+
define_method("check_access_#{d.sub("/", "_")}") do
|
469
|
+
dir = HOMEBREW_PREFIX.join(d)
|
470
|
+
if dir.exist? && !dir.writable_real? then <<-EOS.undent
|
471
|
+
#{dir} isn't writable.
|
472
|
+
|
473
|
+
This can happen if you "sudo make install" software that isn't managed by
|
474
|
+
by Homebrew. If a formula tries to write a file to this directory, the
|
475
|
+
install will fail during the link step.
|
476
|
+
|
477
|
+
You should probably `chown` #{dir}
|
478
|
+
EOS
|
479
|
+
end
|
480
|
+
end
|
481
|
+
end
|
482
|
+
|
483
|
+
def check_access_site_packages
|
484
|
+
if Language::Python.homebrew_site_packages.exist? && !Language::Python.homebrew_site_packages.writable_real?
|
485
|
+
<<-EOS.undent
|
486
|
+
#{Language::Python.homebrew_site_packages} isn't writable.
|
487
|
+
This can happen if you "sudo pip install" software that isn't managed
|
488
|
+
by Homebrew. If you install a formula with Python modules, the install
|
489
|
+
will fail during the link step.
|
490
|
+
|
491
|
+
You should probably `chown` #{Language::Python.homebrew_site_packages}
|
492
|
+
EOS
|
493
|
+
end
|
494
|
+
end
|
495
|
+
|
496
|
+
def check_access_logs
|
497
|
+
if HOMEBREW_LOGS.exist? && !HOMEBREW_LOGS.writable_real?
|
498
|
+
<<-EOS.undent
|
499
|
+
#{HOMEBREW_LOGS} isn't writable.
|
500
|
+
Homebrew writes debugging logs to this location.
|
501
|
+
You should probably `chown` #{HOMEBREW_LOGS}
|
502
|
+
EOS
|
503
|
+
end
|
504
|
+
end
|
505
|
+
|
506
|
+
def check_access_cache
|
507
|
+
if HOMEBREW_CACHE.exist? && !HOMEBREW_CACHE.writable_real?
|
508
|
+
<<-EOS.undent
|
509
|
+
#{HOMEBREW_CACHE} isn't writable.
|
510
|
+
This can happen if you run `brew install` or `brew fetch` as another user.
|
511
|
+
Homebrew caches downloaded files to this location.
|
512
|
+
You should probably `chown` #{HOMEBREW_CACHE}
|
513
|
+
EOS
|
514
|
+
end
|
515
|
+
end
|
516
|
+
|
517
|
+
def check_access_cellar
|
518
|
+
if HOMEBREW_CELLAR.exist? && !HOMEBREW_CELLAR.writable_real?
|
519
|
+
<<-EOS.undent
|
520
|
+
#{HOMEBREW_CELLAR} isn't writable.
|
521
|
+
You should `chown` #{HOMEBREW_CELLAR}
|
522
|
+
EOS
|
523
|
+
end
|
524
|
+
end
|
525
|
+
|
526
|
+
def check_access_prefix_opt
|
527
|
+
opt = HOMEBREW_PREFIX.join("opt")
|
528
|
+
if opt.exist? && !opt.writable_real?
|
529
|
+
<<-EOS.undent
|
530
|
+
#{opt} isn't writable.
|
531
|
+
You should `chown` #{opt}
|
532
|
+
EOS
|
533
|
+
end
|
534
|
+
end
|
535
|
+
|
536
|
+
def check_ruby_version
|
537
|
+
ruby_version = MacOS.version >= "10.9" ? "2.0" : "1.8"
|
538
|
+
if RUBY_VERSION[/\d\.\d/] != ruby_version then <<-EOS.undent
|
539
|
+
Ruby version #{RUBY_VERSION} is unsupported on #{MacOS.version}. Homebrew
|
540
|
+
is developed and tested on Ruby #{ruby_version}, and may not work correctly
|
541
|
+
on other Rubies. Patches are accepted as long as they don't cause breakage
|
542
|
+
on supported Rubies.
|
543
|
+
EOS
|
544
|
+
end
|
545
|
+
end
|
546
|
+
|
547
|
+
def check_homebrew_prefix
|
548
|
+
unless HOMEBREW_PREFIX.to_s == "/usr/local"
|
549
|
+
<<-EOS.undent
|
550
|
+
Your Homebrew is not installed to /usr/local
|
551
|
+
You can install Homebrew anywhere you want, but some brews may only build
|
552
|
+
correctly if you install in /usr/local. Sorry!
|
553
|
+
EOS
|
554
|
+
end
|
555
|
+
end
|
556
|
+
|
557
|
+
def check_xcode_prefix
|
558
|
+
prefix = MacOS::Xcode.prefix
|
559
|
+
return if prefix.nil?
|
560
|
+
if prefix.to_s.match(" ")
|
561
|
+
<<-EOS.undent
|
562
|
+
Xcode is installed to a directory with a space in the name.
|
563
|
+
This will cause some formulae to fail to build.
|
564
|
+
EOS
|
565
|
+
end
|
566
|
+
end
|
567
|
+
|
568
|
+
def check_xcode_prefix_exists
|
569
|
+
prefix = MacOS::Xcode.prefix
|
570
|
+
return if prefix.nil?
|
571
|
+
unless prefix.exist?
|
572
|
+
<<-EOS.undent
|
573
|
+
The directory Xcode is reportedly installed to doesn't exist:
|
574
|
+
#{prefix}
|
575
|
+
You may need to `xcode-select` the proper path if you have moved Xcode.
|
576
|
+
EOS
|
577
|
+
end
|
578
|
+
end
|
579
|
+
|
580
|
+
def check_xcode_select_path
|
581
|
+
if !MacOS::CLT.installed? && !File.file?("#{MacOS.active_developer_dir}/usr/bin/xcodebuild")
|
582
|
+
path = MacOS::Xcode.bundle_path
|
583
|
+
path = "/Developer" if path.nil? || !path.directory?
|
584
|
+
<<-EOS.undent
|
585
|
+
Your Xcode is configured with an invalid path.
|
586
|
+
You should change it to the correct path:
|
587
|
+
sudo xcode-select -switch #{path}
|
588
|
+
EOS
|
589
|
+
end
|
590
|
+
end
|
591
|
+
|
592
|
+
def check_user_path_1
|
593
|
+
$seen_prefix_bin = false
|
594
|
+
$seen_prefix_sbin = false
|
595
|
+
|
596
|
+
out = nil
|
597
|
+
|
598
|
+
paths.each do |p|
|
599
|
+
case p
|
600
|
+
when "/usr/bin"
|
601
|
+
unless $seen_prefix_bin
|
602
|
+
# only show the doctor message if there are any conflicts
|
603
|
+
# rationale: a default install should not trigger any brew doctor messages
|
604
|
+
conflicts = Dir["#{HOMEBREW_PREFIX}/bin/*"].
|
605
|
+
map { |fn| File.basename fn }.
|
606
|
+
select { |bn| File.exist? "/usr/bin/#{bn}" }
|
607
|
+
|
608
|
+
if conflicts.size > 0
|
609
|
+
out = <<-EOS.undent
|
610
|
+
/usr/bin occurs before #{HOMEBREW_PREFIX}/bin
|
611
|
+
This means that system-provided programs will be used instead of those
|
612
|
+
provided by Homebrew. The following tools exist at both paths:
|
613
|
+
|
614
|
+
#{conflicts * "\n "}
|
615
|
+
|
616
|
+
Consider setting your PATH so that #{HOMEBREW_PREFIX}/bin
|
617
|
+
occurs before /usr/bin. Here is a one-liner:
|
618
|
+
echo 'export PATH="#{HOMEBREW_PREFIX}/bin:$PATH"' >> #{shell_profile}
|
619
|
+
EOS
|
620
|
+
end
|
621
|
+
end
|
622
|
+
when "#{HOMEBREW_PREFIX}/bin"
|
623
|
+
$seen_prefix_bin = true
|
624
|
+
when "#{HOMEBREW_PREFIX}/sbin"
|
625
|
+
$seen_prefix_sbin = true
|
626
|
+
end
|
627
|
+
end
|
628
|
+
out
|
629
|
+
end
|
630
|
+
|
631
|
+
def check_user_path_2
|
632
|
+
unless $seen_prefix_bin
|
633
|
+
<<-EOS.undent
|
634
|
+
Homebrew's bin was not found in your PATH.
|
635
|
+
Consider setting the PATH for example like so
|
636
|
+
echo 'export PATH="#{HOMEBREW_PREFIX}/bin:$PATH"' >> #{shell_profile}
|
637
|
+
EOS
|
638
|
+
end
|
639
|
+
end
|
640
|
+
|
641
|
+
def check_user_path_3
|
642
|
+
# Don't complain about sbin not being in the path if it doesn't exist
|
643
|
+
sbin = (HOMEBREW_PREFIX+"sbin")
|
644
|
+
if sbin.directory? && sbin.children.length > 0
|
645
|
+
unless $seen_prefix_sbin
|
646
|
+
<<-EOS.undent
|
647
|
+
Homebrew's sbin was not found in your PATH but you have installed
|
648
|
+
formulae that put executables in #{HOMEBREW_PREFIX}/sbin.
|
649
|
+
Consider setting the PATH for example like so
|
650
|
+
echo 'export PATH="#{HOMEBREW_PREFIX}/sbin:$PATH"' >> #{shell_profile}
|
651
|
+
EOS
|
652
|
+
end
|
653
|
+
end
|
654
|
+
end
|
655
|
+
|
656
|
+
def check_user_curlrc
|
657
|
+
if %w[CURL_HOME HOME].any? { |key| ENV[key] && File.exist?("#{ENV[key]}/.curlrc") } then <<-EOS.undent
|
658
|
+
You have a curlrc file
|
659
|
+
If you have trouble downloading packages with Homebrew, then maybe this
|
660
|
+
is the problem? If the following command doesn't work, then try removing
|
661
|
+
your curlrc:
|
662
|
+
curl http://github.com
|
663
|
+
EOS
|
664
|
+
end
|
665
|
+
end
|
666
|
+
|
667
|
+
def check_for_unsupported_curl_vars
|
668
|
+
# Support for SSL_CERT_DIR seemed to be removed in the 10.10.5 update.
|
669
|
+
if MacOS.version >= :yosemite && !ENV["SSL_CERT_DIR"].nil? then <<-EOS.undent
|
670
|
+
SSL_CERT_DIR support was removed from Apple's curl.
|
671
|
+
If fetching formulae fails you should:
|
672
|
+
unset SSL_CERT_DIR
|
673
|
+
and remove it from #{shell_profile} if present.
|
674
|
+
EOS
|
675
|
+
end
|
676
|
+
end
|
677
|
+
|
678
|
+
def check_which_pkg_config
|
679
|
+
binary = which "pkg-config"
|
680
|
+
return if binary.nil?
|
681
|
+
|
682
|
+
mono_config = Pathname.new("/usr/bin/pkg-config")
|
683
|
+
if mono_config.exist? && mono_config.realpath.to_s.include?("Mono.framework") then <<-EOS.undent
|
684
|
+
You have a non-Homebrew 'pkg-config' in your PATH:
|
685
|
+
/usr/bin/pkg-config => #{mono_config.realpath}
|
686
|
+
|
687
|
+
This was most likely created by the Mono installer. `./configure` may
|
688
|
+
have problems finding brew-installed packages using this other pkg-config.
|
689
|
+
|
690
|
+
Mono no longer installs this file as of 3.0.4. You should
|
691
|
+
`sudo rm /usr/bin/pkg-config` and upgrade to the latest version of Mono.
|
692
|
+
EOS
|
693
|
+
elsif binary.to_s != "#{HOMEBREW_PREFIX}/bin/pkg-config" then <<-EOS.undent
|
694
|
+
You have a non-Homebrew 'pkg-config' in your PATH:
|
695
|
+
#{binary}
|
696
|
+
|
697
|
+
`./configure` may have problems finding brew-installed packages using
|
698
|
+
this other pkg-config.
|
699
|
+
EOS
|
700
|
+
end
|
701
|
+
end
|
702
|
+
|
703
|
+
def check_for_gettext
|
704
|
+
find_relative_paths("lib/libgettextlib.dylib",
|
705
|
+
"lib/libintl.dylib",
|
706
|
+
"include/libintl.h")
|
707
|
+
|
708
|
+
return if @found.empty?
|
709
|
+
|
710
|
+
# Our gettext formula will be caught by check_linked_keg_only_brews
|
711
|
+
f = Formulary.factory("gettext") rescue nil
|
712
|
+
return if f && f.linked_keg.directory? && @found.all? do |path|
|
713
|
+
Pathname.new(path).realpath.to_s.start_with? "#{HOMEBREW_CELLAR}/gettext"
|
714
|
+
end
|
715
|
+
|
716
|
+
s = <<-EOS.undent_________________________________________________________72
|
717
|
+
gettext files detected at a system prefix
|
718
|
+
These files can cause compilation and link failures, especially if they
|
719
|
+
are compiled with improper architectures. Consider removing these files:
|
720
|
+
EOS
|
721
|
+
inject_file_list(@found, s)
|
722
|
+
end
|
723
|
+
|
724
|
+
def check_for_iconv
|
725
|
+
unless find_relative_paths("lib/libiconv.dylib", "include/iconv.h").empty?
|
726
|
+
if (f = Formulary.factory("libiconv") rescue nil) && f.linked_keg.directory?
|
727
|
+
unless f.keg_only? then <<-EOS.undent
|
728
|
+
A libiconv formula is installed and linked
|
729
|
+
This will break stuff. For serious. Unlink it.
|
730
|
+
EOS
|
731
|
+
end
|
732
|
+
else
|
733
|
+
s = <<-EOS.undent_________________________________________________________72
|
734
|
+
libiconv files detected at a system prefix other than /usr
|
735
|
+
Homebrew doesn't provide a libiconv formula, and expects to link against
|
736
|
+
the system version in /usr. libiconv in other prefixes can cause
|
737
|
+
compile or link failure, especially if compiled with improper
|
738
|
+
architectures. OS X itself never installs anything to /usr/local so
|
739
|
+
it was either installed by a user or some other third party software.
|
740
|
+
|
741
|
+
tl;dr: delete these files:
|
742
|
+
EOS
|
743
|
+
inject_file_list(@found, s)
|
744
|
+
end
|
745
|
+
end
|
746
|
+
end
|
747
|
+
|
748
|
+
def check_for_config_scripts
|
749
|
+
return unless HOMEBREW_CELLAR.exist?
|
750
|
+
real_cellar = HOMEBREW_CELLAR.realpath
|
751
|
+
|
752
|
+
scripts = []
|
753
|
+
|
754
|
+
whitelist = %W[
|
755
|
+
/usr/bin /usr/sbin
|
756
|
+
/usr/X11/bin /usr/X11R6/bin /opt/X11/bin
|
757
|
+
#{HOMEBREW_PREFIX}/bin #{HOMEBREW_PREFIX}/sbin
|
758
|
+
/Applications/Server.app/Contents/ServerRoot/usr/bin
|
759
|
+
/Applications/Server.app/Contents/ServerRoot/usr/sbin
|
760
|
+
].map(&:downcase)
|
761
|
+
|
762
|
+
paths.each do |p|
|
763
|
+
next if whitelist.include?(p.downcase) || !File.directory?(p)
|
764
|
+
|
765
|
+
realpath = Pathname.new(p).realpath.to_s
|
766
|
+
next if realpath.start_with?(real_cellar.to_s, HOMEBREW_CELLAR.to_s)
|
767
|
+
|
768
|
+
scripts += Dir.chdir(p) { Dir["*-config"] }.map { |c| File.join(p, c) }
|
769
|
+
end
|
770
|
+
|
771
|
+
unless scripts.empty?
|
772
|
+
s = <<-EOS.undent
|
773
|
+
"config" scripts exist outside your system or Homebrew directories.
|
774
|
+
`./configure` scripts often look for *-config scripts to determine if
|
775
|
+
software packages are installed, and what additional flags to use when
|
776
|
+
compiling and linking.
|
777
|
+
|
778
|
+
Having additional scripts in your path can confuse software installed via
|
779
|
+
Homebrew if the config script overrides a system or Homebrew provided
|
780
|
+
script of the same name. We found the following "config" scripts:
|
781
|
+
|
782
|
+
EOS
|
783
|
+
|
784
|
+
s << scripts.map { |f| " #{f}" }.join("\n")
|
785
|
+
end
|
786
|
+
end
|
787
|
+
|
788
|
+
def check_DYLD_vars
|
789
|
+
found = ENV.keys.grep(/^DYLD_/)
|
790
|
+
unless found.empty?
|
791
|
+
s = <<-EOS.undent
|
792
|
+
Setting DYLD_* vars can break dynamic linking.
|
793
|
+
Set variables:
|
794
|
+
EOS
|
795
|
+
s << found.map { |e| " #{e}: #{ENV.fetch(e)}\n" }.join
|
796
|
+
if found.include? "DYLD_INSERT_LIBRARIES"
|
797
|
+
s += <<-EOS.undent
|
798
|
+
|
799
|
+
Setting DYLD_INSERT_LIBRARIES can cause Go builds to fail.
|
800
|
+
Having this set is common if you use this software:
|
801
|
+
http://asepsis.binaryage.com/
|
802
|
+
EOS
|
803
|
+
end
|
804
|
+
s
|
805
|
+
end
|
806
|
+
end
|
807
|
+
|
808
|
+
def check_for_symlinked_cellar
|
809
|
+
return unless HOMEBREW_CELLAR.exist?
|
810
|
+
if HOMEBREW_CELLAR.symlink?
|
811
|
+
<<-EOS.undent
|
812
|
+
Symlinked Cellars can cause problems.
|
813
|
+
Your Homebrew Cellar is a symlink: #{HOMEBREW_CELLAR}
|
814
|
+
which resolves to: #{HOMEBREW_CELLAR.realpath}
|
815
|
+
|
816
|
+
The recommended Homebrew installations are either:
|
817
|
+
(A) Have Cellar be a real directory inside of your HOMEBREW_PREFIX
|
818
|
+
(B) Symlink "bin/brew" into your prefix, but don't symlink "Cellar".
|
819
|
+
|
820
|
+
Older installations of Homebrew may have created a symlinked Cellar, but this can
|
821
|
+
cause problems when two formula install to locations that are mapped on top of each
|
822
|
+
other during the linking step.
|
823
|
+
EOS
|
824
|
+
end
|
825
|
+
end
|
826
|
+
|
827
|
+
def check_for_multiple_volumes
|
828
|
+
return unless HOMEBREW_CELLAR.exist?
|
829
|
+
volumes = Volumes.new
|
830
|
+
|
831
|
+
# Find the volumes for the TMP folder & HOMEBREW_CELLAR
|
832
|
+
real_cellar = HOMEBREW_CELLAR.realpath
|
833
|
+
|
834
|
+
tmp = Pathname.new(Dir.mktmpdir("doctor", HOMEBREW_TEMP))
|
835
|
+
real_temp = tmp.realpath.parent
|
836
|
+
|
837
|
+
where_cellar = volumes.which real_cellar
|
838
|
+
where_temp = volumes.which real_temp
|
839
|
+
|
840
|
+
Dir.delete tmp
|
841
|
+
|
842
|
+
unless where_cellar == where_temp then <<-EOS.undent
|
843
|
+
Your Cellar and TEMP directories are on different volumes.
|
844
|
+
OS X won't move relative symlinks across volumes unless the target file already
|
845
|
+
exists. Brews known to be affected by this are Git and Narwhal.
|
846
|
+
|
847
|
+
You should set the "HOMEBREW_TEMP" environmental variable to a suitable
|
848
|
+
directory on the same volume as your Cellar.
|
849
|
+
EOS
|
850
|
+
end
|
851
|
+
end
|
852
|
+
|
853
|
+
def check_filesystem_case_sensitive
|
854
|
+
volumes = Volumes.new
|
855
|
+
case_sensitive_vols = [HOMEBREW_PREFIX, HOMEBREW_REPOSITORY, HOMEBREW_CELLAR, HOMEBREW_TEMP].select do |dir|
|
856
|
+
# We select the dir as being case-sensitive if either the UPCASED or the
|
857
|
+
# downcased variant is missing.
|
858
|
+
# Of course, on a case-insensitive fs, both exist because the os reports so.
|
859
|
+
# In the rare situation when the user has indeed a downcased and an upcased
|
860
|
+
# dir (e.g. /TMP and /tmp) this check falsely thinks it is case-insensitive
|
861
|
+
# but we don't care beacuse: 1. there is more than one dir checked, 2. the
|
862
|
+
# check is not vital and 3. we would have to touch files otherwise.
|
863
|
+
upcased = Pathname.new(dir.to_s.upcase)
|
864
|
+
downcased = Pathname.new(dir.to_s.downcase)
|
865
|
+
dir.exist? && !(upcased.exist? && downcased.exist?)
|
866
|
+
end.map { |case_sensitive_dir| volumes.get_mounts(case_sensitive_dir) }.uniq
|
867
|
+
return if case_sensitive_vols.empty?
|
868
|
+
<<-EOS.undent
|
869
|
+
The filesystem on #{case_sensitive_vols.join(",")} appears to be case-sensitive.
|
870
|
+
The default OS X filesystem is case-insensitive. Please report any apparent problems.
|
871
|
+
EOS
|
872
|
+
end
|
873
|
+
|
874
|
+
def __check_git_version
|
875
|
+
# https://help.github.com/articles/https-cloning-errors
|
876
|
+
`git --version`.chomp =~ /git version ((?:\d+\.?)+)/
|
877
|
+
|
878
|
+
if $1 && Version.new($1) < Version.new("1.7.10")
|
879
|
+
git_upgrade_cmd = Formula["git"].any_version_installed? ? "upgrade" : "install"
|
880
|
+
|
881
|
+
<<-EOS.undent
|
882
|
+
An outdated version of Git was detected in your PATH.
|
883
|
+
Git 1.7.10 or newer is required to perform checkouts over HTTPS from GitHub.
|
884
|
+
Please upgrade: brew #{git_upgrade_cmd} git
|
885
|
+
EOS
|
886
|
+
end
|
887
|
+
end
|
888
|
+
|
889
|
+
def check_for_git
|
890
|
+
if git?
|
891
|
+
__check_git_version
|
892
|
+
else <<-EOS.undent
|
893
|
+
Git could not be found in your PATH.
|
894
|
+
Homebrew uses Git for several internal functions, and some formulae use Git
|
895
|
+
checkouts instead of stable tarballs. You may want to install Git:
|
896
|
+
brew install git
|
897
|
+
EOS
|
898
|
+
end
|
899
|
+
end
|
900
|
+
|
901
|
+
def check_git_newline_settings
|
902
|
+
return unless git?
|
903
|
+
|
904
|
+
autocrlf = `git config --get core.autocrlf`.chomp
|
905
|
+
|
906
|
+
if autocrlf == "true" then <<-EOS.undent
|
907
|
+
Suspicious Git newline settings found.
|
908
|
+
|
909
|
+
The detected Git newline settings will cause checkout problems:
|
910
|
+
core.autocrlf = #{autocrlf}
|
911
|
+
|
912
|
+
If you are not routinely dealing with Windows-based projects,
|
913
|
+
consider removing these by running:
|
914
|
+
`git config --global core.autocrlf input`
|
915
|
+
EOS
|
916
|
+
end
|
917
|
+
end
|
918
|
+
|
919
|
+
def check_git_origin
|
920
|
+
return unless git? && (HOMEBREW_REPOSITORY/".git").exist?
|
921
|
+
|
922
|
+
HOMEBREW_REPOSITORY.cd do
|
923
|
+
origin = `git config --get remote.origin.url`.strip
|
924
|
+
|
925
|
+
if origin.empty? then <<-EOS.undent
|
926
|
+
Missing git origin remote.
|
927
|
+
|
928
|
+
Without a correctly configured origin, Homebrew won't update
|
929
|
+
properly. You can solve this by adding the Homebrew remote:
|
930
|
+
cd #{HOMEBREW_REPOSITORY}
|
931
|
+
git remote add origin https://github.com/Homebrew/homebrew.git
|
932
|
+
EOS
|
933
|
+
elsif origin !~ /(mxcl|Homebrew)\/homebrew(\.git)?$/ then <<-EOS.undent
|
934
|
+
Suspicious git origin remote found.
|
935
|
+
|
936
|
+
With a non-standard origin, Homebrew won't pull updates from
|
937
|
+
the main repository. The current git origin is:
|
938
|
+
#{origin}
|
939
|
+
|
940
|
+
Unless you have compelling reasons, consider setting the
|
941
|
+
origin remote to point at the main repository, located at:
|
942
|
+
https://github.com/Homebrew/homebrew.git
|
943
|
+
EOS
|
944
|
+
end
|
945
|
+
end
|
946
|
+
end
|
947
|
+
|
948
|
+
def check_for_autoconf
|
949
|
+
return unless MacOS::Xcode.provides_autotools?
|
950
|
+
|
951
|
+
autoconf = which("autoconf")
|
952
|
+
safe_autoconfs = %w[/usr/bin/autoconf /Developer/usr/bin/autoconf]
|
953
|
+
unless autoconf.nil? || safe_autoconfs.include?(autoconf.to_s) then <<-EOS.undent
|
954
|
+
An "autoconf" in your path blocks the Xcode-provided version at:
|
955
|
+
#{autoconf}
|
956
|
+
|
957
|
+
This custom autoconf may cause some Homebrew formulae to fail to compile.
|
958
|
+
EOS
|
959
|
+
end
|
960
|
+
end
|
961
|
+
|
962
|
+
def __check_linked_brew(f)
|
963
|
+
f.rack.subdirs.each do |prefix|
|
964
|
+
prefix.find do |src|
|
965
|
+
next if src == prefix
|
966
|
+
dst = HOMEBREW_PREFIX + src.relative_path_from(prefix)
|
967
|
+
return true if dst.symlink? && src == dst.resolved_path
|
968
|
+
end
|
969
|
+
end
|
970
|
+
|
971
|
+
false
|
972
|
+
end
|
973
|
+
|
974
|
+
def check_for_linked_keg_only_brews
|
975
|
+
return unless HOMEBREW_CELLAR.exist?
|
976
|
+
|
977
|
+
linked = Formula.installed.select do |f|
|
978
|
+
f.keg_only? && __check_linked_brew(f)
|
979
|
+
end
|
980
|
+
|
981
|
+
unless linked.empty?
|
982
|
+
s = <<-EOS.undent
|
983
|
+
Some keg-only formula are linked into the Cellar.
|
984
|
+
Linking a keg-only formula, such as gettext, into the cellar with
|
985
|
+
`brew link <formula>` will cause other formulae to detect them during
|
986
|
+
the `./configure` step. This may cause problems when compiling those
|
987
|
+
other formulae.
|
988
|
+
|
989
|
+
Binaries provided by keg-only formulae may override system binaries
|
990
|
+
with other strange results.
|
991
|
+
|
992
|
+
You may wish to `brew unlink` these brews:
|
993
|
+
|
994
|
+
EOS
|
995
|
+
linked.each { |f| s << " #{f.full_name}\n" }
|
996
|
+
s
|
997
|
+
end
|
998
|
+
end
|
999
|
+
|
1000
|
+
def check_for_other_frameworks
|
1001
|
+
# Other frameworks that are known to cause problems when present
|
1002
|
+
%w[expat.framework libexpat.framework libcurl.framework].
|
1003
|
+
map { |frmwrk| "/Library/Frameworks/#{frmwrk}" }.
|
1004
|
+
select { |frmwrk| File.exist? frmwrk }.
|
1005
|
+
map do |frmwrk|
|
1006
|
+
<<-EOS.undent
|
1007
|
+
#{frmwrk} detected
|
1008
|
+
This can be picked up by CMake's build system and likely cause the build to
|
1009
|
+
fail. You may need to move this file out of the way to compile CMake.
|
1010
|
+
EOS
|
1011
|
+
end.join
|
1012
|
+
end
|
1013
|
+
|
1014
|
+
def check_tmpdir
|
1015
|
+
tmpdir = ENV["TMPDIR"]
|
1016
|
+
"TMPDIR #{tmpdir.inspect} doesn't exist." unless tmpdir.nil? || File.directory?(tmpdir)
|
1017
|
+
end
|
1018
|
+
|
1019
|
+
def check_missing_deps
|
1020
|
+
return unless HOMEBREW_CELLAR.exist?
|
1021
|
+
missing = Set.new
|
1022
|
+
Homebrew.missing_deps(Formula.installed).each_value do |deps|
|
1023
|
+
missing.merge(deps)
|
1024
|
+
end
|
1025
|
+
|
1026
|
+
if missing.any? then <<-EOS.undent
|
1027
|
+
Some installed formula are missing dependencies.
|
1028
|
+
You should `brew install` the missing dependencies:
|
1029
|
+
|
1030
|
+
brew install #{missing.sort_by(&:full_name) * " "}
|
1031
|
+
|
1032
|
+
Run `brew missing` for more details.
|
1033
|
+
EOS
|
1034
|
+
end
|
1035
|
+
end
|
1036
|
+
|
1037
|
+
def check_git_status
|
1038
|
+
return unless git?
|
1039
|
+
HOMEBREW_REPOSITORY.cd do
|
1040
|
+
unless `git status --untracked-files=all --porcelain -- Library/Homebrew/ 2>/dev/null`.chomp.empty?
|
1041
|
+
<<-EOS.undent_________________________________________________________72
|
1042
|
+
You have uncommitted modifications to Homebrew
|
1043
|
+
If this a surprise to you, then you should stash these modifications.
|
1044
|
+
Stashing returns Homebrew to a pristine state but can be undone
|
1045
|
+
should you later need to do so for some reason.
|
1046
|
+
cd #{HOMEBREW_LIBRARY} && git stash && git clean -d -f
|
1047
|
+
EOS
|
1048
|
+
end
|
1049
|
+
end
|
1050
|
+
end
|
1051
|
+
|
1052
|
+
def check_for_enthought_python
|
1053
|
+
if which "enpkg" then <<-EOS.undent
|
1054
|
+
Enthought Python was found in your PATH.
|
1055
|
+
This can cause build problems, as this software installs its own
|
1056
|
+
copies of iconv and libxml2 into directories that are picked up by
|
1057
|
+
other build systems.
|
1058
|
+
EOS
|
1059
|
+
end
|
1060
|
+
end
|
1061
|
+
|
1062
|
+
def check_for_library_python
|
1063
|
+
if File.exist?("/Library/Frameworks/Python.framework") then <<-EOS.undent
|
1064
|
+
Python is installed at /Library/Frameworks/Python.framework
|
1065
|
+
|
1066
|
+
Homebrew only supports building against the System-provided Python or a
|
1067
|
+
brewed Python. In particular, Pythons installed to /Library can interfere
|
1068
|
+
with other software installs.
|
1069
|
+
EOS
|
1070
|
+
end
|
1071
|
+
end
|
1072
|
+
|
1073
|
+
def check_for_old_homebrew_share_python_in_path
|
1074
|
+
s = ""
|
1075
|
+
["", "3"].map do |suffix|
|
1076
|
+
if paths.include?((HOMEBREW_PREFIX/"share/python#{suffix}").to_s)
|
1077
|
+
s += "#{HOMEBREW_PREFIX}/share/python#{suffix} is not needed in PATH.\n"
|
1078
|
+
end
|
1079
|
+
end
|
1080
|
+
unless s.empty?
|
1081
|
+
s += <<-EOS.undent
|
1082
|
+
Formerly homebrew put Python scripts you installed via `pip` or `pip3`
|
1083
|
+
(or `easy_install`) into that directory above but now it can be removed
|
1084
|
+
from your PATH variable.
|
1085
|
+
Python scripts will now install into #{HOMEBREW_PREFIX}/bin.
|
1086
|
+
You can delete anything, except 'Extras', from the #{HOMEBREW_PREFIX}/share/python
|
1087
|
+
(and #{HOMEBREW_PREFIX}/share/python3) dir and install affected Python packages
|
1088
|
+
anew with `pip install --upgrade`.
|
1089
|
+
EOS
|
1090
|
+
end
|
1091
|
+
end
|
1092
|
+
|
1093
|
+
def check_for_bad_python_symlink
|
1094
|
+
return unless which "python"
|
1095
|
+
`python -V 2>&1` =~ /Python (\d+)\./
|
1096
|
+
# This won't be the right warning if we matched nothing at all
|
1097
|
+
return if $1.nil?
|
1098
|
+
unless $1 == "2" then <<-EOS.undent
|
1099
|
+
python is symlinked to python#{$1}
|
1100
|
+
This will confuse build scripts and in general lead to subtle breakage.
|
1101
|
+
EOS
|
1102
|
+
end
|
1103
|
+
end
|
1104
|
+
|
1105
|
+
def check_for_non_prefixed_coreutils
|
1106
|
+
gnubin = "#{Formulary.factory("coreutils").prefix}/libexec/gnubin"
|
1107
|
+
if paths.include? gnubin then <<-EOS.undent
|
1108
|
+
Putting non-prefixed coreutils in your path can cause gmp builds to fail.
|
1109
|
+
EOS
|
1110
|
+
end
|
1111
|
+
end
|
1112
|
+
|
1113
|
+
def check_for_non_prefixed_findutils
|
1114
|
+
default_names = Tab.for_name("findutils").with? "default-names"
|
1115
|
+
if default_names then <<-EOS.undent
|
1116
|
+
Putting non-prefixed findutils in your path can cause python builds to fail.
|
1117
|
+
EOS
|
1118
|
+
end
|
1119
|
+
end
|
1120
|
+
|
1121
|
+
def check_for_pydistutils_cfg_in_home
|
1122
|
+
if File.exist? "#{ENV["HOME"]}/.pydistutils.cfg" then <<-EOS.undent
|
1123
|
+
A .pydistutils.cfg file was found in $HOME, which may cause Python
|
1124
|
+
builds to fail. See:
|
1125
|
+
https://bugs.python.org/issue6138
|
1126
|
+
https://bugs.python.org/issue4655
|
1127
|
+
EOS
|
1128
|
+
end
|
1129
|
+
end
|
1130
|
+
|
1131
|
+
def check_for_outdated_homebrew
|
1132
|
+
return unless git?
|
1133
|
+
HOMEBREW_REPOSITORY.cd do
|
1134
|
+
if File.directory? ".git"
|
1135
|
+
local = `git rev-parse -q --verify refs/remotes/origin/master`.chomp
|
1136
|
+
remote = /^([a-f0-9]{40})/.match(`git ls-remote origin refs/heads/master 2>/dev/null`)
|
1137
|
+
if remote.nil? || local == remote[0]
|
1138
|
+
return
|
1139
|
+
end
|
1140
|
+
end
|
1141
|
+
|
1142
|
+
timestamp = if File.directory? ".git"
|
1143
|
+
`git log -1 --format="%ct" HEAD`.to_i
|
1144
|
+
else
|
1145
|
+
HOMEBREW_LIBRARY.mtime.to_i
|
1146
|
+
end
|
1147
|
+
|
1148
|
+
if Time.now.to_i - timestamp > 60 * 60 * 24 then <<-EOS.undent
|
1149
|
+
Your Homebrew is outdated.
|
1150
|
+
You haven't updated for at least 24 hours. This is a long time in brewland!
|
1151
|
+
To update Homebrew, run `brew update`.
|
1152
|
+
EOS
|
1153
|
+
end
|
1154
|
+
end
|
1155
|
+
end
|
1156
|
+
|
1157
|
+
def check_for_unlinked_but_not_keg_only
|
1158
|
+
return unless HOMEBREW_CELLAR.exist?
|
1159
|
+
unlinked = HOMEBREW_CELLAR.children.reject do |rack|
|
1160
|
+
if !rack.directory?
|
1161
|
+
true
|
1162
|
+
elsif !(HOMEBREW_REPOSITORY/"Library/LinkedKegs"/rack.basename).directory?
|
1163
|
+
begin
|
1164
|
+
Formulary.from_rack(rack).keg_only?
|
1165
|
+
rescue FormulaUnavailableError, TapFormulaAmbiguityError
|
1166
|
+
false
|
1167
|
+
end
|
1168
|
+
else
|
1169
|
+
true
|
1170
|
+
end
|
1171
|
+
end.map(&:basename)
|
1172
|
+
|
1173
|
+
unless unlinked.empty? then <<-EOS.undent
|
1174
|
+
You have unlinked kegs in your Cellar
|
1175
|
+
Leaving kegs unlinked can lead to build-trouble and cause brews that depend on
|
1176
|
+
those kegs to fail to run properly once built. Run `brew link` on these:
|
1177
|
+
|
1178
|
+
#{unlinked * "\n "}
|
1179
|
+
EOS
|
1180
|
+
end
|
1181
|
+
end
|
1182
|
+
|
1183
|
+
def check_xcode_license_approved
|
1184
|
+
# If the user installs Xcode-only, they have to approve the
|
1185
|
+
# license or no "xc*" tool will work.
|
1186
|
+
if `/usr/bin/xcrun clang 2>&1` =~ /license/ && !$?.success? then <<-EOS.undent
|
1187
|
+
You have not agreed to the Xcode license.
|
1188
|
+
Builds will fail! Agree to the license by opening Xcode.app or running:
|
1189
|
+
sudo xcodebuild -license
|
1190
|
+
EOS
|
1191
|
+
end
|
1192
|
+
end
|
1193
|
+
|
1194
|
+
def check_for_latest_xquartz
|
1195
|
+
return unless MacOS::XQuartz.version
|
1196
|
+
return if MacOS::XQuartz.provided_by_apple?
|
1197
|
+
|
1198
|
+
installed_version = Version.new(MacOS::XQuartz.version)
|
1199
|
+
latest_version = Version.new(MacOS::XQuartz.latest_version)
|
1200
|
+
|
1201
|
+
return if installed_version >= latest_version
|
1202
|
+
|
1203
|
+
<<-EOS.undent
|
1204
|
+
Your XQuartz (#{installed_version}) is outdated
|
1205
|
+
Please install XQuartz #{latest_version}:
|
1206
|
+
https://xquartz.macosforge.org
|
1207
|
+
EOS
|
1208
|
+
end
|
1209
|
+
|
1210
|
+
def check_for_old_env_vars
|
1211
|
+
if ENV["HOMEBREW_KEEP_INFO"]
|
1212
|
+
<<-EOS.undent
|
1213
|
+
`HOMEBREW_KEEP_INFO` is no longer used
|
1214
|
+
info files are no longer deleted by default; you may
|
1215
|
+
remove this environment variable.
|
1216
|
+
EOS
|
1217
|
+
end
|
1218
|
+
end
|
1219
|
+
|
1220
|
+
def check_for_pth_support
|
1221
|
+
homebrew_site_packages = Language::Python.homebrew_site_packages
|
1222
|
+
return unless homebrew_site_packages.directory?
|
1223
|
+
return if Language::Python.reads_brewed_pth_files?("python") != false
|
1224
|
+
return unless Language::Python.in_sys_path?("python", homebrew_site_packages)
|
1225
|
+
user_site_packages = Language::Python.user_site_packages "python"
|
1226
|
+
<<-EOS.undent
|
1227
|
+
Your default Python does not recognize the Homebrew site-packages
|
1228
|
+
directory as a special site-packages directory, which means that .pth
|
1229
|
+
files will not be followed. This means you will not be able to import
|
1230
|
+
some modules after installing them with Homebrew, like wxpython. To fix
|
1231
|
+
this for the current user, you can run:
|
1232
|
+
|
1233
|
+
mkdir -p #{user_site_packages}
|
1234
|
+
echo 'import site; site.addsitedir("#{homebrew_site_packages}")' >> #{user_site_packages}/homebrew.pth
|
1235
|
+
EOS
|
1236
|
+
end
|
1237
|
+
|
1238
|
+
def check_for_external_cmd_name_conflict
|
1239
|
+
cmds = paths.flat_map { |p| Dir["#{p}/brew-*"] }.uniq
|
1240
|
+
cmds = cmds.select { |cmd| File.file?(cmd) && File.executable?(cmd) }
|
1241
|
+
cmd_map = {}
|
1242
|
+
cmds.each do |cmd|
|
1243
|
+
cmd_name = File.basename(cmd, ".rb")
|
1244
|
+
cmd_map[cmd_name] ||= []
|
1245
|
+
cmd_map[cmd_name] << cmd
|
1246
|
+
end
|
1247
|
+
cmd_map.reject! { |_cmd_name, cmd_paths| cmd_paths.size == 1 }
|
1248
|
+
return if cmd_map.empty?
|
1249
|
+
s = "You have external commands with conflicting names."
|
1250
|
+
cmd_map.each do |cmd_name, cmd_paths|
|
1251
|
+
s += "\n\nFound command `#{cmd_name}` in following places:\n"
|
1252
|
+
s += cmd_paths.map { |f| " #{f}" }.join("\n")
|
1253
|
+
end
|
1254
|
+
s
|
1255
|
+
end
|
1256
|
+
|
1257
|
+
def all
|
1258
|
+
methods.map(&:to_s).grep(/^check_/)
|
1259
|
+
end
|
1260
|
+
end # end class Checks
|
1261
|
+
|
1262
|
+
module Homebrew
|
1263
|
+
def doctor
|
1264
|
+
checks = Checks.new
|
1265
|
+
|
1266
|
+
if ARGV.include? "--list-checks"
|
1267
|
+
puts checks.all.sort
|
1268
|
+
exit
|
1269
|
+
end
|
1270
|
+
|
1271
|
+
inject_dump_stats(checks) if ARGV.switch? "D"
|
1272
|
+
|
1273
|
+
if ARGV.named.empty?
|
1274
|
+
methods = checks.all.sort
|
1275
|
+
methods << "check_for_linked_keg_only_brews" << "check_for_outdated_homebrew"
|
1276
|
+
methods = methods.reverse.uniq.reverse
|
1277
|
+
else
|
1278
|
+
methods = ARGV.named
|
1279
|
+
end
|
1280
|
+
|
1281
|
+
first_warning = true
|
1282
|
+
methods.each do |method|
|
1283
|
+
begin
|
1284
|
+
out = checks.send(method)
|
1285
|
+
rescue NoMethodError
|
1286
|
+
Homebrew.failed = true
|
1287
|
+
puts "No check available by the name: #{method}"
|
1288
|
+
next
|
1289
|
+
end
|
1290
|
+
unless out.nil? || out.empty?
|
1291
|
+
if first_warning
|
1292
|
+
puts <<-EOS.undent
|
1293
|
+
#{Tty.white}Please note that these warnings are just used to help the Homebrew maintainers
|
1294
|
+
with debugging if you file an issue. If everything you use Homebrew for is
|
1295
|
+
working fine: please don't worry and just ignore them. Thanks!#{Tty.reset}
|
1296
|
+
EOS
|
1297
|
+
end
|
1298
|
+
|
1299
|
+
puts
|
1300
|
+
opoo out
|
1301
|
+
Homebrew.failed = true
|
1302
|
+
first_warning = false
|
1303
|
+
end
|
1304
|
+
end
|
1305
|
+
|
1306
|
+
puts "Your system is ready to brew." unless Homebrew.failed?
|
1307
|
+
end
|
1308
|
+
|
1309
|
+
def inject_dump_stats(checks)
|
1310
|
+
checks.extend Module.new {
|
1311
|
+
def send(method, *)
|
1312
|
+
time = Time.now
|
1313
|
+
super
|
1314
|
+
ensure
|
1315
|
+
$times[method] = Time.now - time
|
1316
|
+
end
|
1317
|
+
}
|
1318
|
+
$times = {}
|
1319
|
+
at_exit do
|
1320
|
+
puts $times.sort_by { |_k, v| v }.map { |k, v| "#{k}: #{v}" }
|
1321
|
+
end
|
1322
|
+
end
|
1323
|
+
end
|