aboutsummaryrefslogtreecommitdiffstats
path: root/Library/Homebrew/requirements.rb
blob: 4ca9496eb1d179006ac29fc6ddbec2734d745758 (plain)
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
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
require 'requirement'

# A dependency on a language-specific module.
class LanguageModuleDependency < Requirement
  fatal true

  def initialize language, module_name, import_name=nil
    @language = language
    @module_name = module_name
    @import_name = import_name || module_name
  end

  satisfy { quiet_system(*the_test) }

  def message; <<-EOS.undent
    Unsatisfied dependency: #{@module_name}
    Homebrew does not provide #{@language.to_s.capitalize} dependencies; install with:
      #{command_line} #{@module_name}
    EOS
  end

  def the_test
    case @language
      when :chicken then %W{/usr/bin/env csi -e (use #{@import_name})}
      when :jruby then %W{/usr/bin/env jruby -rubygems -e require\ '#{@import_name}'}
      when :lua then %W{/usr/bin/env luarocks show #{@import_name}}
      when :node then %W{/usr/bin/env node -e require('#{@import_name}');}
      when :ocaml then %W{/usr/bin/env opam list #{@import_name} | grep #{@import_name}}
      when :perl then %W{/usr/bin/env perl -e use\ #{@import_name}}
      when :python then %W{/usr/bin/env python -c import\ #{@import_name}}
      when :ruby then %W{/usr/bin/env ruby -rubygems -e require\ '#{@import_name}'}
      when :rbx then %W{/usr/bin/env rbx -rubygems -e require\ '#{@import_name}'}
    end
  end

  def command_line
    case @language
      when :chicken then "chicken-install"
      when :jruby   then "jruby -S gem install"
      when :lua     then "luarocks install"
      when :node    then "npm install"
      when :ocaml   then "opam install"
      when :perl    then "cpan -i"
      when :python  then "pip install"
      when :rbx     then "rbx gem install"
      when :ruby    then "gem install"
    end
  end
end


# This requirement is used to require an X11 implementation,
# optionally with a minimum version number.
class X11Dependency < Requirement
  include Comparable
  attr_reader :min_version

  fatal true

  env { x11 }

  def initialize(*tags)
    tags.flatten!
    @min_version = tags.shift if /(\d\.)+\d/ === tags.first
    super
  end

  satisfy :build_env => false do
    MacOS::XQuartz.installed? && (@min_version.nil? || @min_version <= MacOS::XQuartz.version)
  end

  def message; <<-EOS.undent
    Unsatisfied dependency: XQuartz #{@min_version}
    Homebrew does not package XQuartz. Installers may be found at:
      https://xquartz.macosforge.org
    EOS
  end

  def <=> other
    unless other.is_a? X11Dependency
      raise TypeError, "expected X11Dependency"
    end

    if other.min_version.nil?
      1
    elsif @min_version.nil?
      -1
    else
      @min_version <=> other.min_version
    end
  end

end


# There are multiple implementations of MPI-2 available.
# http://www.mpi-forum.org/
# This requirement is used to find an appropriate one.
class MPIDependency < Requirement

  attr_reader :lang_list

  fatal true

  env :userpaths

  def initialize *lang_list
    @lang_list = lang_list
    @non_functional = []
    @unknown_langs = []
    super()
  end

  def mpi_wrapper_works? compiler
    compiler = which compiler
    return false if compiler.nil? or not compiler.executable?

    # Some wrappers are non-functional and will return a non-zero exit code
    # when invoked for version info.
    #
    # NOTE: A better test may be to do a small test compilation a la autotools.
    quiet_system compiler, '--version'
  end

  satisfy do
    @lang_list.each do |lang|
      case lang
      when :cc, :cxx, :f90, :f77
        compiler = 'mpi' + lang.to_s
        @non_functional << compiler unless mpi_wrapper_works? compiler
      else
        @unknown_langs << lang.to_s
      end
    end
    @unknown_langs.empty? and @non_functional.empty?
  end

  env do |req|
    # Set environment variables to help configure scripts find MPI compilers.
    # Variable names taken from:
    # http://www.gnu.org/software/autoconf-archive/ax_mpi.html
    req.lang_list.each do |lang|
      compiler = 'mpi' + lang.to_s
      mpi_path = which compiler

      # Fortran 90 environment var has a different name
      compiler = 'MPIFC' if lang == :f90
      ENV[compiler.upcase] = mpi_path
    end
  end

  def message
    if not @unknown_langs.empty?
      <<-EOS.undent
        There is no MPI compiler wrapper for:
            #{@unknown_langs.join ', '}

        The following values are valid arguments to `MPIDependency.new`:
            :cc, :cxx, :f90, :f77
        EOS
    else
      <<-EOS.undent
        Homebrew could not locate working copies of the following MPI compiler
        wrappers:
            #{@non_functional.join ', '}

        If you have a MPI installation, please ensure the bin folder is on your
        PATH and that all the wrappers are functional. Otherwise, a MPI
        installation can be obtained from homebrew by *picking one* of the
        following formulae:
            open-mpi, mpich2
        EOS
    end
  end
end

# This requirement added by the `conflicts_with` DSL method.
class ConflictRequirement < Requirement
  attr_reader :formula

  # The user can chose to force installation even in the face of conflicts.
  fatal !ARGV.force?

  def initialize formula, name, opts={}
    @formula = formula
    @name = name
    @opts = opts
    super()
  end

  def message
    message = "#{@name.downcase} cannot be installed alongside #{@formula}.\n"
    message << "This is because #{@opts[:because]}\n" if @opts[:because]
    message << <<-EOS.undent unless ARGV.force?
      Please `brew unlink #{@formula}` before continuing. Unlinking removes
      the formula's symlinks from #{HOMEBREW_PREFIX}. You can link the
      formula again after the install finishes. You can --force this install
      but the build may fail or cause obscure side-effects in the end-binary.
    EOS
    message
  end

  satisfy :build_env => false do
    keg = Formula.factory(@formula).prefix
    not keg.exist? && Keg.new(keg).linked?
  end
end

class XcodeDependency < Requirement
  fatal true
  build true

  satisfy(:build_env => false) { MacOS::Xcode.installed? }

  def message; <<-EOS.undent
    A full installation of Xcode.app is required to compile this software.
    Installing just the Command Line Tools is not sufficent.
    EOS
  end
end

class MysqlInstalled < Requirement
  fatal true

  satisfy { which 'mysql_config' }

  def message; <<-EOS.undent
    MySQL is required to install.

    You can install this with Homebrew using:
      brew install mysql-connector-c
        For MySQL client libraries only.

      brew install mysql
        For MySQL server.

    Or you can use an official installer from:
      http://dev.mysql.com/downloads/mysql/
    EOS
  end
end

class PostgresqlInstalled < Requirement
  fatal true

  satisfy { which 'pg_config' }

  def message
    <<-EOS.undent
      Postgres is required to install.

      You can install this with Homebrew using:
        brew install postgres

      Or you can use an official installer from:
        http://www.postgresql.org/download/macosx/
    EOS
  end
end

class TeXInstalled < Requirement
  fatal true

  satisfy { which('tex') || which('latex') }

  def message; <<-EOS.undent
    A LaTeX distribution is required to install.

    You can install MacTeX distribution from:
      http://www.tug.org/mactex/

    Make sure that its bin directory is in your PATH before proceeding.

    You may also need to restore the ownership of Homebrew install:
      sudo chown -R $USER `brew --prefix`
    EOS
  end
end

class CLTDependency < Requirement
  fatal true
  build true

  def satisfied?
    MacOS::CLT.installed?
  end

  def message; <<-EOS.undent
    The Command Line Tools for Xcode are required to compile this software.
    The standalone package can be obtained from http://connect.apple.com,
    or it can be installed via Xcode's preferences.
    EOS
  end
end