2010-06-23 11:20:47 -07:00
|
|
|
require 'formula'
|
|
|
|
require 'utils'
|
superenv: build-environments that just work
1. A minimal build environment, we don't set CFLAGS, CPPFLAGS, LDFLAGS, etc. the rationale being, the less that is set, the less variables we are introducing that can break builds.
2. A set of scripts that replace cc, ld, etc. and inject the -I, -L, etc. flags we need into the args passed to the build-tools.
Because we now have complete control over compiler instantiations we do a variety of clean-up tasks, like removing bad flags, enforcing universal builds and ensuring makefiles don't try to change the order of library and include paths from ones that work to ones that don't.
The previous ENV-system is still available when --env=std is specified.
superenv applies to Xcode >= 4.3 only currently.
2012-08-11 12:30:51 -04:00
|
|
|
require 'superenv'
|
2012-03-17 19:49:49 -07:00
|
|
|
|
2012-08-07 01:37:46 -05:00
|
|
|
module Homebrew extend self
|
|
|
|
def audit
|
|
|
|
formula_count = 0
|
|
|
|
problem_count = 0
|
|
|
|
|
|
|
|
ff = if ARGV.named.empty?
|
2012-08-21 11:39:45 -04:00
|
|
|
Formula
|
2012-08-07 01:37:46 -05:00
|
|
|
else
|
|
|
|
ARGV.formulae
|
|
|
|
end
|
|
|
|
|
|
|
|
ff.each do |f|
|
|
|
|
fa = FormulaAuditor.new f
|
|
|
|
fa.audit
|
|
|
|
|
|
|
|
unless fa.problems.empty?
|
|
|
|
puts "#{f.name}:"
|
|
|
|
fa.problems.each { |p| puts " * #{p}" }
|
|
|
|
puts
|
|
|
|
formula_count += 1
|
|
|
|
problem_count += fa.problems.size
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
unless problem_count.zero?
|
|
|
|
ofail "#{problem_count} problems in #{formula_count} formulae"
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2012-03-17 19:49:49 -07:00
|
|
|
|
|
|
|
class Module
|
|
|
|
def redefine_const(name, value)
|
|
|
|
__send__(:remove_const, name) if const_defined?(name)
|
|
|
|
const_set(name, value)
|
|
|
|
end
|
|
|
|
end
|
2010-06-23 11:20:47 -07:00
|
|
|
|
2012-08-07 01:37:46 -05:00
|
|
|
# Formula extensions for auditing
|
|
|
|
class Formula
|
|
|
|
def head_only?
|
|
|
|
@head and @stable.nil?
|
2011-06-06 07:25:00 -07:00
|
|
|
end
|
2011-03-21 12:57:35 -07:00
|
|
|
|
2012-08-07 01:37:46 -05:00
|
|
|
def text
|
|
|
|
@text ||= FormulaText.new(@path)
|
2010-07-12 10:34:12 -07:00
|
|
|
end
|
2012-08-07 01:37:46 -05:00
|
|
|
end
|
2010-07-12 10:34:12 -07:00
|
|
|
|
2012-08-07 01:37:46 -05:00
|
|
|
class FormulaText
|
|
|
|
def initialize path
|
|
|
|
@text = path.open('r') { |f| f.read }
|
2010-07-23 21:31:32 -07:00
|
|
|
end
|
|
|
|
|
2012-08-07 01:37:46 -05:00
|
|
|
def without_patch
|
|
|
|
@text.split("__END__")[0].strip()
|
2011-11-29 19:37:39 -06:00
|
|
|
end
|
|
|
|
|
2012-08-07 01:37:46 -05:00
|
|
|
def has_DATA?
|
|
|
|
/\bDATA\b/ =~ @text
|
2010-08-15 15:19:19 -07:00
|
|
|
end
|
|
|
|
|
2012-08-07 01:37:46 -05:00
|
|
|
def has_END?
|
|
|
|
/^__END__$/ =~ @text
|
2010-09-08 09:07:59 -07:00
|
|
|
end
|
|
|
|
|
2012-08-07 01:37:46 -05:00
|
|
|
def has_trailing_newline?
|
|
|
|
/.+\z/ =~ @text
|
2010-09-07 14:34:39 -07:00
|
|
|
end
|
2012-08-07 01:37:46 -05:00
|
|
|
end
|
2010-09-07 14:34:39 -07:00
|
|
|
|
2012-08-07 01:37:46 -05:00
|
|
|
class FormulaAuditor
|
|
|
|
attr :f
|
|
|
|
attr :text
|
|
|
|
attr :problems, true
|
|
|
|
|
|
|
|
BUILD_TIME_DEPS = %W[
|
|
|
|
autoconf
|
|
|
|
automake
|
|
|
|
boost-build
|
|
|
|
bsdmake
|
|
|
|
cmake
|
|
|
|
imake
|
2013-02-03 14:41:00 -06:00
|
|
|
intltool
|
2012-08-07 01:37:46 -05:00
|
|
|
libtool
|
|
|
|
pkg-config
|
|
|
|
scons
|
|
|
|
smake
|
2012-09-05 21:12:08 -07:00
|
|
|
swig
|
2012-08-07 01:37:46 -05:00
|
|
|
]
|
|
|
|
|
|
|
|
def initialize f
|
|
|
|
@f = f
|
|
|
|
@problems = []
|
|
|
|
@text = f.text.without_patch
|
|
|
|
|
|
|
|
# We need to do this in case the formula defines a patch that uses DATA.
|
|
|
|
f.class.redefine_const :DATA, ""
|
|
|
|
end
|
|
|
|
|
|
|
|
def audit_file
|
|
|
|
unless f.path.stat.mode.to_s(8) == "100644"
|
|
|
|
problem "Incorrect file permissions: chmod 644 #{f.path}"
|
|
|
|
end
|
2010-06-23 11:20:47 -07:00
|
|
|
|
2012-08-07 01:37:46 -05:00
|
|
|
if f.text.has_DATA? and not f.text.has_END?
|
|
|
|
problem "'DATA' was found, but no '__END__'"
|
|
|
|
end
|
2010-08-08 10:17:53 -07:00
|
|
|
|
2012-08-07 01:37:46 -05:00
|
|
|
if f.text.has_END? and not f.text.has_DATA?
|
|
|
|
problem "'__END__' was found, but 'DATA' is not used"
|
|
|
|
end
|
2010-08-15 11:32:45 -07:00
|
|
|
|
2012-08-07 01:37:46 -05:00
|
|
|
if f.text.has_trailing_newline?
|
|
|
|
problem "File should end with a newline"
|
|
|
|
end
|
2010-08-08 10:17:53 -07:00
|
|
|
end
|
|
|
|
|
2012-08-07 01:37:46 -05:00
|
|
|
def audit_deps
|
|
|
|
problems = []
|
2010-08-08 10:17:53 -07:00
|
|
|
|
2012-08-07 01:37:46 -05:00
|
|
|
# Don't depend_on aliases; use full name
|
|
|
|
aliases = Formula.aliases
|
2012-08-27 21:17:39 -05:00
|
|
|
f.deps.select { |d| aliases.include? d.name }.each do |d|
|
2012-08-07 01:37:46 -05:00
|
|
|
problem "Dependency #{d} is an alias; use the canonical name."
|
|
|
|
end
|
2010-09-08 09:22:48 -07:00
|
|
|
|
2012-08-07 01:37:46 -05:00
|
|
|
# Check for things we don't like to depend on.
|
|
|
|
# We allow non-Homebrew installs whenever possible.
|
2013-01-23 00:26:31 -06:00
|
|
|
f.deps.each do |dep|
|
2012-08-07 01:37:46 -05:00
|
|
|
begin
|
2013-01-23 00:26:31 -06:00
|
|
|
dep_f = dep.to_formula
|
2012-08-07 01:37:46 -05:00
|
|
|
rescue
|
2013-02-02 00:54:32 -06:00
|
|
|
problem "Can't find dependency #{dep.name.inspect}."
|
2012-08-07 01:37:46 -05:00
|
|
|
end
|
2010-08-08 10:17:53 -07:00
|
|
|
|
2013-01-23 00:26:31 -06:00
|
|
|
dep.options.reject do |opt|
|
|
|
|
dep_f.build.has_option?(opt.name)
|
|
|
|
end.each do |opt|
|
|
|
|
problem "Dependency #{dep} does not define option #{opt.name.inspect}"
|
|
|
|
end
|
|
|
|
|
|
|
|
case dep.name
|
2012-08-07 01:37:46 -05:00
|
|
|
when "git", "python", "ruby", "emacs", "mysql", "postgresql", "mercurial"
|
|
|
|
problem <<-EOS.undent
|
2013-01-23 00:26:31 -06:00
|
|
|
Don't use #{dep} as a dependency. We allow non-Homebrew
|
|
|
|
#{dep} installations.
|
2012-08-07 01:37:46 -05:00
|
|
|
EOS
|
|
|
|
when 'gfortran'
|
|
|
|
problem "Use ENV.fortran during install instead of depends_on 'gfortran'"
|
|
|
|
when 'open-mpi', 'mpich2'
|
|
|
|
problem <<-EOS.undent
|
|
|
|
There are multiple conflicting ways to install MPI. Use an MPIDependency:
|
|
|
|
depends_on MPIDependency.new(<lang list>)
|
|
|
|
Where <lang list> is a comma delimited list that can include:
|
|
|
|
:cc, :cxx, :f90, :f77
|
|
|
|
EOS
|
|
|
|
end
|
|
|
|
end
|
2010-09-13 15:16:09 -07:00
|
|
|
end
|
|
|
|
|
2013-01-03 11:22:31 -08:00
|
|
|
def audit_conflicts
|
|
|
|
f.conflicts.each do |req|
|
|
|
|
begin
|
|
|
|
conflict_f = Formula.factory req.formula
|
|
|
|
rescue
|
|
|
|
problem "Can't find conflicting formula \"#{req.formula}\"."
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2010-08-07 15:23:13 -07:00
|
|
|
|
2012-08-07 01:37:46 -05:00
|
|
|
def audit_urls
|
|
|
|
unless f.homepage =~ %r[^https?://]
|
|
|
|
problem "The homepage should start with http or https."
|
|
|
|
end
|
2010-10-08 20:11:40 -07:00
|
|
|
|
2012-08-07 01:37:46 -05:00
|
|
|
# Google Code homepages should end in a slash
|
|
|
|
if f.homepage =~ %r[^https?://code\.google\.com/p/[^/]+[^/]$]
|
|
|
|
problem "Google Code homepage should end with a slash."
|
|
|
|
end
|
2010-10-30 08:26:36 -07:00
|
|
|
|
2012-08-07 01:37:46 -05:00
|
|
|
urls = [(f.stable.url rescue nil), (f.devel.url rescue nil), (f.head.url rescue nil)].compact
|
2010-10-21 07:51:47 -07:00
|
|
|
|
2012-08-07 01:37:46 -05:00
|
|
|
# Check GNU urls; doesn't apply to mirrors
|
2013-02-07 15:34:13 -06:00
|
|
|
if urls.any? { |p| p =~ %r[^(https?|ftp)://(?!alpha).+/gnu/] }
|
2012-08-07 01:37:46 -05:00
|
|
|
problem "\"ftpmirror.gnu.org\" is preferred for GNU software."
|
|
|
|
end
|
2011-03-21 12:54:00 -07:00
|
|
|
|
2012-08-07 01:37:46 -05:00
|
|
|
# the rest of the checks apply to mirrors as well
|
|
|
|
urls.concat([(f.stable.mirrors rescue nil), (f.devel.mirrors rescue nil)].flatten.compact)
|
2011-11-18 15:22:04 -06:00
|
|
|
|
2012-08-07 01:37:46 -05:00
|
|
|
# Check SourceForge urls
|
|
|
|
urls.each do |p|
|
|
|
|
# Is it a filedownload (instead of svnroot)
|
|
|
|
next if p =~ %r[/svnroot/]
|
|
|
|
next if p =~ %r[svn\.sourceforge]
|
2011-12-08 22:16:19 -06:00
|
|
|
|
2012-08-07 01:37:46 -05:00
|
|
|
# Is it a sourceforge http(s) URL?
|
|
|
|
next unless p =~ %r[^https?://.*\bsourceforge\.]
|
2011-12-08 22:16:19 -06:00
|
|
|
|
2012-08-07 01:37:46 -05:00
|
|
|
if p =~ /(\?|&)use_mirror=/
|
|
|
|
problem "Update this url (don't use #{$1}use_mirror)."
|
|
|
|
end
|
2012-06-17 17:59:30 -05:00
|
|
|
|
2012-08-07 01:37:46 -05:00
|
|
|
if p =~ /\/download$/
|
|
|
|
problem "Update this url (don't use /download)."
|
|
|
|
end
|
2012-06-17 18:01:22 -05:00
|
|
|
|
2012-08-07 01:37:46 -05:00
|
|
|
if p =~ %r[^http://prdownloads\.]
|
2012-09-18 16:26:02 -04:00
|
|
|
problem "Update this url (don't use prdownloads). See:\nhttp://librelist.com/browser/homebrew/2011/1/12/prdownloads-is-bad/"
|
2012-08-07 01:37:46 -05:00
|
|
|
end
|
2010-08-09 11:59:16 -07:00
|
|
|
|
2012-08-07 01:37:46 -05:00
|
|
|
if p =~ %r[^http://\w+\.dl\.]
|
|
|
|
problem "Update this url (don't use specific dl mirrors)."
|
|
|
|
end
|
2012-03-17 19:49:49 -07:00
|
|
|
end
|
2010-09-09 14:16:05 -07:00
|
|
|
|
2012-08-07 01:37:46 -05:00
|
|
|
# Check for git:// urls; https:// is preferred.
|
|
|
|
if urls.any? { |p| p =~ %r[^git://github\.com/] }
|
|
|
|
problem "Use https:// URLs for accessing GitHub repositories."
|
|
|
|
end
|
2013-02-03 14:54:18 -06:00
|
|
|
|
|
|
|
if urls.any? { |u| u =~ /\.xz/ } && !f.deps.any? { |d| d.name == "xz" }
|
|
|
|
problem "Missing a build-time dependency on 'xz'"
|
|
|
|
end
|
2011-03-15 21:40:09 -07:00
|
|
|
end
|
|
|
|
|
2012-08-07 01:37:46 -05:00
|
|
|
def audit_specs
|
|
|
|
problem "Head-only (no stable download)" if f.head_only?
|
2012-01-25 22:41:53 -06:00
|
|
|
|
2012-08-07 01:37:46 -05:00
|
|
|
[:stable, :devel].each do |spec|
|
|
|
|
s = f.send(spec)
|
|
|
|
next if s.nil?
|
|
|
|
|
|
|
|
if s.version.to_s.empty?
|
|
|
|
problem "Invalid or missing #{spec} version"
|
|
|
|
else
|
2012-07-10 16:10:16 -05:00
|
|
|
version_text = s.version unless s.version.detected_from_url?
|
|
|
|
version_url = Version.parse(s.url)
|
2012-08-27 09:44:54 -05:00
|
|
|
if version_url.to_s == version_text.to_s
|
2012-08-07 01:37:46 -05:00
|
|
|
problem "#{spec} version #{version_text} is redundant with version scanned from URL"
|
|
|
|
end
|
|
|
|
end
|
2010-09-29 10:21:44 -07:00
|
|
|
|
2012-08-07 01:37:46 -05:00
|
|
|
cksum = s.checksum
|
|
|
|
next if cksum.nil?
|
|
|
|
|
|
|
|
len = case cksum.hash_type
|
|
|
|
when :sha1 then 40
|
|
|
|
when :sha256 then 64
|
|
|
|
end
|
|
|
|
|
|
|
|
if cksum.empty?
|
|
|
|
problem "#{cksum.hash_type} is empty"
|
|
|
|
else
|
|
|
|
problem "#{cksum.hash_type} should be #{len} characters" unless cksum.hexdigest.length == len
|
|
|
|
problem "#{cksum.hash_type} contains invalid characters" unless cksum.hexdigest =~ /^[a-fA-F0-9]+$/
|
|
|
|
problem "#{cksum.hash_type} should be lowercase" unless cksum.hexdigest == cksum.hexdigest.downcase
|
|
|
|
end
|
2011-11-30 13:14:24 -06:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2012-08-07 01:37:46 -05:00
|
|
|
def audit_patches
|
|
|
|
# Some formulae use ENV in patches, so set up an environment
|
2013-02-01 14:27:34 -06:00
|
|
|
ENV.with_build_environment do
|
|
|
|
Patches.new(f.patches).select { |p| p.external? }.each do |p|
|
|
|
|
case p.url
|
|
|
|
when %r[raw\.github\.com], %r[gist\.github\.com/raw]
|
|
|
|
unless p.url =~ /[a-fA-F0-9]{40}/
|
|
|
|
problem "GitHub/Gist patches should specify a revision:\n#{p.url}"
|
|
|
|
end
|
|
|
|
when %r[macports/trunk]
|
|
|
|
problem "MacPorts patches should specify a revision instead of trunk:\n#{p.url}"
|
2012-09-06 20:47:05 -05:00
|
|
|
end
|
2012-08-07 01:37:46 -05:00
|
|
|
end
|
2010-09-09 14:16:05 -07:00
|
|
|
end
|
2012-08-07 01:37:46 -05:00
|
|
|
end
|
2010-09-09 14:16:05 -07:00
|
|
|
|
2012-08-07 01:37:46 -05:00
|
|
|
def audit_text
|
|
|
|
if text =~ /<(Formula|AmazonWebServicesFormula|ScriptFileFormula|GithubGistFormula)/
|
|
|
|
problem "Use a space in class inheritance: class Foo < #{$1}"
|
2010-09-09 14:16:05 -07:00
|
|
|
end
|
|
|
|
|
2012-08-07 01:37:46 -05:00
|
|
|
# Commented-out cmake support from default template
|
2013-01-04 09:30:57 -08:00
|
|
|
if (text =~ /# system "cmake/)
|
|
|
|
problem "Commented cmake call found"
|
2010-09-09 14:16:05 -07:00
|
|
|
end
|
|
|
|
|
2012-08-07 01:37:46 -05:00
|
|
|
# build tools should be flagged properly
|
2012-09-04 10:43:44 -07:00
|
|
|
# but don't complain about automake; it needs autoconf at runtime
|
2012-08-07 01:37:46 -05:00
|
|
|
if text =~ /depends_on ['"](#{BUILD_TIME_DEPS*'|'})['"]$/
|
|
|
|
problem "#{$1} dependency should be \"depends_on '#{$1}' => :build\""
|
2012-09-04 10:43:44 -07:00
|
|
|
end unless f.name == "automake"
|
2011-06-13 14:20:55 -07:00
|
|
|
|
2012-08-07 01:37:46 -05:00
|
|
|
# FileUtils is included in Formula
|
|
|
|
if text =~ /FileUtils\.(\w+)/
|
|
|
|
problem "Don't need 'FileUtils.' before #{$1}."
|
|
|
|
end
|
2010-09-09 14:16:05 -07:00
|
|
|
|
2012-08-07 01:37:46 -05:00
|
|
|
# Check for long inreplace block vars
|
|
|
|
if text =~ /inreplace .* do \|(.{2,})\|/
|
|
|
|
problem "\"inreplace <filenames> do |s|\" is preferred over \"|#{$1}|\"."
|
|
|
|
end
|
2012-01-25 22:41:53 -06:00
|
|
|
|
2012-08-07 01:37:46 -05:00
|
|
|
# Check for string interpolation of single values.
|
|
|
|
if text =~ /(system|inreplace|gsub!|change_make_var!) .* ['"]#\{(\w+(\.\w+)?)\}['"]/
|
|
|
|
problem "Don't need to interpolate \"#{$2}\" with #{$1}"
|
|
|
|
end
|
2012-01-25 22:41:53 -06:00
|
|
|
|
2012-08-07 01:37:46 -05:00
|
|
|
# Check for string concatenation; prefer interpolation
|
|
|
|
if text =~ /(#\{\w+\s*\+\s*['"][^}]+\})/
|
|
|
|
problem "Try not to concatenate paths in string interpolation:\n #{$1}"
|
2012-04-05 21:12:02 -05:00
|
|
|
end
|
2012-01-25 22:41:53 -06:00
|
|
|
|
2012-08-07 01:37:46 -05:00
|
|
|
# Prefer formula path shortcuts in Pathname+
|
|
|
|
if text =~ %r{\(\s*(prefix\s*\+\s*(['"])(bin|include|libexec|lib|sbin|share)[/'"])}
|
|
|
|
problem "\"(#{$1}...#{$2})\" should be \"(#{$3}+...)\""
|
|
|
|
end
|
2012-06-18 19:58:35 -05:00
|
|
|
|
2012-08-07 01:37:46 -05:00
|
|
|
if text =~ %r[((man)\s*\+\s*(['"])(man[1-8])(['"]))]
|
|
|
|
problem "\"#{$1}\" should be \"#{$4}\""
|
|
|
|
end
|
2012-04-05 21:12:02 -05:00
|
|
|
|
2012-08-07 01:37:46 -05:00
|
|
|
# Prefer formula path shortcuts in strings
|
|
|
|
if text =~ %r[(\#\{prefix\}/(bin|include|libexec|lib|sbin|share))]
|
|
|
|
problem "\"#{$1}\" should be \"\#{#{$2}}\""
|
2012-04-05 21:12:02 -05:00
|
|
|
end
|
2012-01-25 22:41:53 -06:00
|
|
|
|
2012-08-07 01:37:46 -05:00
|
|
|
if text =~ %r[((\#\{prefix\}/share/man/|\#\{man\}/)(man[1-8]))]
|
|
|
|
problem "\"#{$1}\" should be \"\#{#{$3}}\""
|
|
|
|
end
|
2012-01-25 22:41:53 -06:00
|
|
|
|
2012-08-07 01:37:46 -05:00
|
|
|
if text =~ %r[((\#\{share\}/(man)))[/'"]]
|
|
|
|
problem "\"#{$1}\" should be \"\#{#{$3}}\""
|
|
|
|
end
|
2010-08-21 11:55:57 -07:00
|
|
|
|
2012-08-07 01:37:46 -05:00
|
|
|
if text =~ %r[(\#\{prefix\}/share/(info|man))]
|
|
|
|
problem "\"#{$1}\" should be \"\#{#{$2}}\""
|
|
|
|
end
|
2010-08-21 11:55:57 -07:00
|
|
|
|
2012-08-07 01:37:46 -05:00
|
|
|
# Commented-out depends_on
|
|
|
|
if text =~ /#\s*depends_on\s+(.+)\s*$/
|
2012-09-13 07:14:45 -07:00
|
|
|
problem "Commented-out dep #{$1}"
|
2010-09-07 09:23:29 -07:00
|
|
|
end
|
|
|
|
|
2012-08-07 01:37:46 -05:00
|
|
|
# No trailing whitespace, please
|
|
|
|
if text =~ /(\t|[ ])+$/
|
2012-09-13 07:14:45 -07:00
|
|
|
problem "Trailing whitespace was found"
|
2012-08-07 01:37:46 -05:00
|
|
|
end
|
2010-08-21 11:55:57 -07:00
|
|
|
|
2012-08-07 01:37:46 -05:00
|
|
|
if text =~ /if\s+ARGV\.include\?\s+'--(HEAD|devel)'/
|
|
|
|
problem "Use \"if ARGV.build_#{$1.downcase}?\" instead"
|
|
|
|
end
|
2012-03-17 19:49:49 -07:00
|
|
|
|
2012-08-07 01:37:46 -05:00
|
|
|
if text =~ /make && make/
|
2012-09-13 07:14:45 -07:00
|
|
|
problem "Use separate make calls"
|
2012-08-07 01:37:46 -05:00
|
|
|
end
|
2012-03-17 19:49:49 -07:00
|
|
|
|
2012-08-07 01:37:46 -05:00
|
|
|
if text =~ /^[ ]*\t/
|
|
|
|
problem "Use spaces instead of tabs for indentation"
|
|
|
|
end
|
2011-05-31 13:23:42 -07:00
|
|
|
|
2012-08-07 01:37:46 -05:00
|
|
|
# xcodebuild should specify SYMROOT
|
|
|
|
if text =~ /system\s+['"]xcodebuild/ and not text =~ /SYMROOT=/
|
|
|
|
problem "xcodebuild should be passed an explicit \"SYMROOT\""
|
|
|
|
end
|
2012-02-16 20:27:08 -08:00
|
|
|
|
2012-09-03 19:18:58 -07:00
|
|
|
if text =~ /ENV\.x11/
|
|
|
|
problem "Use \"depends_on :x11\" instead of \"ENV.x11\""
|
|
|
|
end
|
|
|
|
|
2012-08-07 01:37:46 -05:00
|
|
|
# Avoid hard-coding compilers
|
|
|
|
if text =~ %r[(system|ENV\[.+\]\s?=)\s?['"](/usr/bin/)?(gcc|llvm-gcc|clang)['" ]]
|
|
|
|
problem "Use \"\#{ENV.cc}\" instead of hard-coding \"#{$3}\""
|
|
|
|
end
|
2010-08-10 11:52:03 -07:00
|
|
|
|
2012-08-07 01:37:46 -05:00
|
|
|
if text =~ %r[(system|ENV\[.+\]\s?=)\s?['"](/usr/bin/)?((g|llvm-g|clang)\+\+)['" ]]
|
|
|
|
problem "Use \"\#{ENV.cxx}\" instead of hard-coding \"#{$3}\""
|
|
|
|
end
|
2011-02-20 15:03:15 -08:00
|
|
|
|
2012-08-07 01:37:46 -05:00
|
|
|
if text =~ /system\s+['"](env|export)/
|
|
|
|
problem "Use ENV instead of invoking '#{$1}' to modify the environment"
|
|
|
|
end
|
2012-01-22 22:32:15 -06:00
|
|
|
|
2012-08-07 01:37:46 -05:00
|
|
|
if text =~ /version == ['"]HEAD['"]/
|
2012-08-22 20:59:43 -07:00
|
|
|
problem "Use 'build.head?' instead of inspecting 'version'"
|
|
|
|
end
|
|
|
|
|
2012-08-25 09:36:01 -07:00
|
|
|
if text =~ /build\.include\?\s+['"]\-\-(.*)['"]/
|
2012-09-13 07:14:45 -07:00
|
|
|
problem "Reference '#{$1}' without dashes"
|
2012-08-25 09:36:01 -07:00
|
|
|
end
|
|
|
|
|
2012-10-21 13:23:43 -07:00
|
|
|
if text =~ /ARGV\.(?!(debug|verbose|find)\?)/
|
2012-09-13 07:14:45 -07:00
|
|
|
problem "Use build instead of ARGV to check options"
|
2012-08-22 20:59:43 -07:00
|
|
|
end
|
|
|
|
|
|
|
|
if text =~ /def options/
|
2012-09-13 07:14:45 -07:00
|
|
|
problem "Use new-style option definitions"
|
2012-08-07 01:37:46 -05:00
|
|
|
end
|
2012-09-04 18:18:14 -05:00
|
|
|
|
|
|
|
if text =~ /MACOS_VERSION/
|
|
|
|
problem "Use MacOS.version instead of MACOS_VERSION"
|
|
|
|
end
|
2012-09-10 16:40:13 -05:00
|
|
|
|
|
|
|
if text =~ /(MacOS.((snow_)?leopard|leopard|(mountain_)?lion)\?)/
|
|
|
|
problem "#{$1} is deprecated, use a comparison to MacOS.version instead"
|
|
|
|
end
|
2012-09-13 07:14:45 -07:00
|
|
|
|
|
|
|
if text =~ /skip_clean\s+:all/
|
|
|
|
problem "`skip_clean :all` is deprecated; brew no longer strips symbols"
|
|
|
|
end
|
2013-01-27 14:27:32 -08:00
|
|
|
|
|
|
|
if text =~ /depends_on (.*)\.new\s*[^(]/
|
|
|
|
problem "`depends_on` can take requirement classes directly"
|
|
|
|
end
|
2012-08-07 01:37:46 -05:00
|
|
|
end
|
2010-08-09 11:59:16 -07:00
|
|
|
|
2012-08-07 01:37:46 -05:00
|
|
|
def audit
|
|
|
|
audit_file
|
|
|
|
audit_specs
|
|
|
|
audit_urls
|
|
|
|
audit_deps
|
2013-01-03 11:22:31 -08:00
|
|
|
audit_conflicts
|
2012-08-07 01:37:46 -05:00
|
|
|
audit_patches
|
|
|
|
audit_text
|
|
|
|
end
|
2010-11-09 13:00:33 +00:00
|
|
|
|
2012-08-07 01:37:46 -05:00
|
|
|
private
|
2011-05-31 13:23:42 -07:00
|
|
|
|
2012-08-07 01:37:46 -05:00
|
|
|
def problem p
|
|
|
|
@problems << p
|
2010-06-23 11:20:47 -07:00
|
|
|
end
|
|
|
|
end
|