Merge branch 'master' into undeclared_runtime_dependencies
This commit is contained in:
commit
6cd195723f
@ -26,6 +26,9 @@ Layout/CaseIndentation:
|
||||
Layout/EmptyLineBetweenDefs:
|
||||
AllowAdjacentOneLineDefs: true
|
||||
|
||||
Layout/EndAlignment:
|
||||
EnforcedStyleAlignWith: variable
|
||||
|
||||
Layout/IndentArray:
|
||||
EnforcedStyle: special_inside_parentheses
|
||||
|
||||
@ -52,9 +55,6 @@ Lint/AmbiguousBlockAssociation:
|
||||
Lint/AssignmentInCondition:
|
||||
Enabled: false
|
||||
|
||||
Lint/EndAlignment:
|
||||
EnforcedStyleAlignWith: variable
|
||||
|
||||
# so many of these in formulae and can't be autocorrected
|
||||
Lint/ParenthesesAsGroupedExpression:
|
||||
Enabled: false
|
||||
@ -205,7 +205,10 @@ Style/TernaryParentheses:
|
||||
EnforcedStyle: require_parentheses_when_complex
|
||||
|
||||
# makes diffs nicer
|
||||
Style/TrailingCommaInLiteral:
|
||||
Style/TrailingCommaInArrayLiteral:
|
||||
EnforcedStyleForMultiline: comma
|
||||
|
||||
Style/TrailingCommaInHashLiteral:
|
||||
EnforcedStyleForMultiline: comma
|
||||
|
||||
Style/TrailingCommaInArguments:
|
||||
@ -215,6 +218,10 @@ Style/TrailingCommaInArguments:
|
||||
Naming/VariableNumber:
|
||||
Enabled: false
|
||||
|
||||
# doesn't make sense for Homebrew/brew but does for taps
|
||||
Naming/UncommunicativeMethodParamName:
|
||||
Enabled: true
|
||||
|
||||
Style/WordArray:
|
||||
MinSize: 4
|
||||
|
||||
|
||||
@ -68,6 +68,10 @@ Naming/PredicateName:
|
||||
- 'compat/**/*'
|
||||
NameWhitelist: is_32_bit?, is_64_bit?
|
||||
|
||||
# f meaning formulae is pretty standard
|
||||
Naming/UncommunicativeMethodParamName:
|
||||
Enabled: false
|
||||
|
||||
Style/BlockDelimiters:
|
||||
Exclude:
|
||||
- '**/*_spec.rb'
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
require "uri"
|
||||
|
||||
module Hbc
|
||||
module CaskLoader
|
||||
class FromContentLoader
|
||||
|
||||
@ -85,7 +85,7 @@ module Hbc
|
||||
executable, *args = expanded_command
|
||||
|
||||
raw_stdin, raw_stdout, raw_stderr, raw_wait_thr =
|
||||
Open3.popen3({ "PATH" => path }, executable, *args, **options)
|
||||
Open3.popen3({ "PATH" => path }, [executable, executable], *args, **options)
|
||||
|
||||
write_input_to(raw_stdin)
|
||||
raw_stdin.close_write
|
||||
|
||||
@ -25,7 +25,6 @@ class Caveats
|
||||
caveats << function_completion_caveats(:zsh)
|
||||
caveats << function_completion_caveats(:fish)
|
||||
caveats << plist_caveats
|
||||
caveats << python_caveats
|
||||
caveats << elisp_caveats
|
||||
caveats.compact.join("\n")
|
||||
end
|
||||
@ -108,53 +107,6 @@ class Caveats
|
||||
end
|
||||
end
|
||||
|
||||
def python_caveats
|
||||
return unless keg
|
||||
return unless keg.python_site_packages_installed?
|
||||
|
||||
s = nil
|
||||
homebrew_site_packages = Language::Python.homebrew_site_packages
|
||||
user_site_packages = Language::Python.user_site_packages "python"
|
||||
pth_file = user_site_packages/"homebrew.pth"
|
||||
instructions = <<~EOS.gsub(/^/, " ")
|
||||
mkdir -p #{user_site_packages}
|
||||
echo 'import site; site.addsitedir("#{homebrew_site_packages}")' >> #{pth_file}
|
||||
EOS
|
||||
|
||||
if f.keg_only?
|
||||
keg_site_packages = f.opt_prefix/"lib/python2.7/site-packages"
|
||||
unless Language::Python.in_sys_path?("python", keg_site_packages)
|
||||
s = <<~EOS
|
||||
If you need Python to find bindings for this keg-only formula, run:
|
||||
echo #{keg_site_packages} >> #{homebrew_site_packages/f.name}.pth
|
||||
EOS
|
||||
s += instructions unless Language::Python.reads_brewed_pth_files?("python")
|
||||
end
|
||||
return s
|
||||
end
|
||||
|
||||
return if Language::Python.reads_brewed_pth_files?("python")
|
||||
|
||||
if !Language::Python.in_sys_path?("python", homebrew_site_packages)
|
||||
s = <<~EOS
|
||||
Python modules have been installed and Homebrew's site-packages is not
|
||||
in your Python sys.path, so you will not be able to import the modules
|
||||
this formula installed. If you plan to develop with these modules,
|
||||
please run:
|
||||
EOS
|
||||
s += instructions
|
||||
elsif keg.python_pth_files_installed?
|
||||
s = <<~EOS
|
||||
This formula installed .pth files to Homebrew's site-packages and your
|
||||
Python isn't configured to process them, so you will not be able to
|
||||
import the modules this formula installed. If you plan to develop
|
||||
with these modules, please run:
|
||||
EOS
|
||||
s += instructions
|
||||
end
|
||||
s
|
||||
end
|
||||
|
||||
def elisp_caveats
|
||||
return if f.keg_only?
|
||||
return unless keg
|
||||
|
||||
@ -17,7 +17,8 @@
|
||||
#:
|
||||
#: By default, `deps` shows required and recommended dependencies for
|
||||
#: <formulae>. To include the `:build` type dependencies, pass `--include-build`.
|
||||
#: Similarly, pass `--include-optional` to include `:optional` dependencies.
|
||||
#: Similarly, pass `--include-optional` to include `:optional` dependencies or
|
||||
#: `--include-test` to include `:test` dependencies.
|
||||
#: To skip `:recommended` type dependencies, pass `--skip-recommended`.
|
||||
#: To include requirements in addition to dependencies, pass `--include-requirements`.
|
||||
#:
|
||||
@ -30,8 +31,8 @@
|
||||
#: If `--installed` is passed, output a tree for every installed formula.
|
||||
#:
|
||||
#: The <filters> placeholder is any combination of options `--include-build`,
|
||||
#: `--include-optional`, `--skip-recommended`, and `--include-requirements` as
|
||||
#: documented above.
|
||||
#: `--include-optional`, `--include-test`, `--skip-recommended`, and
|
||||
#: `--include-requirements` as documented above.
|
||||
#:
|
||||
#: If `--annotate` is passed, the build, optional, and recommended dependencies
|
||||
#: are marked as such in the output.
|
||||
@ -42,7 +43,8 @@
|
||||
#: dependencies of that formula.
|
||||
#:
|
||||
#: The <filters> placeholder is any combination of options `--include-build`,
|
||||
#: `--include-optional`, and `--skip-recommended` as documented above.
|
||||
#: `--include-optional`, `--include-test`, and `--skip-recommended` as
|
||||
#: documented above.
|
||||
|
||||
# The undocumented `--for-each` option will switch into the mode used by `deps --all`,
|
||||
# but only list dependencies for specified formula, one specified formula per line.
|
||||
@ -111,6 +113,7 @@ module Homebrew
|
||||
end
|
||||
if ARGV.include?("--annotate")
|
||||
str = "#{str} [build]" if dep.build?
|
||||
str = "#{str} [test]" if dep.test?
|
||||
str = "#{str} [optional" if dep.optional?
|
||||
str = "#{str} [recommended]" if dep.recommended?
|
||||
end
|
||||
@ -125,6 +128,11 @@ module Homebrew
|
||||
else
|
||||
ignores << "build?"
|
||||
end
|
||||
if ARGV.include?("--include-test")
|
||||
includes << "test?"
|
||||
else
|
||||
ignores << "test?"
|
||||
end
|
||||
if ARGV.include?("--include-optional")
|
||||
includes << "optional?"
|
||||
else
|
||||
@ -136,6 +144,9 @@ module Homebrew
|
||||
deps = f.recursive_dependencies do |dependent, dep|
|
||||
if dep.recommended?
|
||||
Dependency.prune if ignores.include?("recommended?") || dependent.build.without?(dep)
|
||||
elsif dep.test?
|
||||
next if includes.include?("test?")
|
||||
Dependency.prune
|
||||
elsif dep.optional?
|
||||
Dependency.prune if !includes.include?("optional?") && !dependent.build.with?(dep)
|
||||
elsif dep.build?
|
||||
@ -145,6 +156,9 @@ module Homebrew
|
||||
reqs = f.recursive_requirements do |dependent, req|
|
||||
if req.recommended?
|
||||
Requirement.prune if ignores.include?("recommended?") || dependent.build.without?(req)
|
||||
elsif req.test?
|
||||
next if includes.include?("test?")
|
||||
Requirement.prune
|
||||
elsif req.optional?
|
||||
Requirement.prune if !includes.include?("optional?") && !dependent.build.with?(req)
|
||||
elsif req.build?
|
||||
@ -191,6 +205,7 @@ module Homebrew
|
||||
dependables = reqs + deps
|
||||
dependables = dependables.reject(&:optional?) unless ARGV.include?("--include-optional")
|
||||
dependables = dependables.reject(&:build?) unless ARGV.include?("--include-build")
|
||||
dependables = dependables.reject(&:test?) unless ARGV.include?("--include-test")
|
||||
dependables = dependables.reject(&:recommended?) if ARGV.include?("--skip-recommended")
|
||||
max = dependables.length - 1
|
||||
@dep_stack.push f.name
|
||||
|
||||
@ -113,14 +113,14 @@ module Homebrew
|
||||
url = "https://api.github.com/gists"
|
||||
data = { "public" => true, "files" => files, "description" => description }
|
||||
scopes = GitHub::CREATE_GIST_SCOPES
|
||||
GitHub.open(url, data: data, scopes: scopes)["html_url"]
|
||||
GitHub.open_api(url, data: data, scopes: scopes)["html_url"]
|
||||
end
|
||||
|
||||
def create_issue(repo, title, body)
|
||||
url = "https://api.github.com/repos/#{repo}/issues"
|
||||
data = { "title" => title, "body" => body }
|
||||
scopes = GitHub::CREATE_ISSUE_SCOPES
|
||||
GitHub.open(url, data: data, scopes: scopes)["html_url"]
|
||||
GitHub.open_api(url, data: data, scopes: scopes)["html_url"]
|
||||
end
|
||||
|
||||
def gist_logs
|
||||
|
||||
@ -137,7 +137,12 @@ module Homebrew
|
||||
EOS
|
||||
end
|
||||
|
||||
kegs = f.installed_kegs.sort_by(&:version)
|
||||
kegs = f.installed_kegs
|
||||
heads, versioned = kegs.partition { |k| k.version.head? }
|
||||
kegs = [
|
||||
*heads.sort_by { |k| -Tab.for_keg(k).time.to_i },
|
||||
*versioned.sort_by(&:version),
|
||||
]
|
||||
if kegs.empty?
|
||||
puts "Not installed"
|
||||
else
|
||||
|
||||
@ -344,7 +344,7 @@ module Homebrew
|
||||
rescue FormulaInstallationAlreadyAttemptedError
|
||||
# We already attempted to install f as part of the dependency tree of
|
||||
# another formula. In that case, don't generate an error, just move on.
|
||||
return
|
||||
nil
|
||||
rescue CannotInstallFormulaError => e
|
||||
ofail e.message
|
||||
end
|
||||
|
||||
@ -47,7 +47,7 @@ module Homebrew
|
||||
fi.install
|
||||
fi.finish
|
||||
rescue FormulaInstallationAlreadyAttemptedError
|
||||
return
|
||||
nil
|
||||
rescue Exception # rubocop:disable Lint/RescueException
|
||||
ignore_interrupts { restore_backup(keg, keg_was_linked) }
|
||||
raise
|
||||
|
||||
@ -13,7 +13,7 @@ module Homebrew
|
||||
module_function
|
||||
|
||||
def update_preinstall_header
|
||||
@header_already_printed ||= begin
|
||||
@update_preinstall_header ||= begin
|
||||
ohai "Auto-updated Homebrew!" if ARGV.include?("--preinstall")
|
||||
true
|
||||
end
|
||||
|
||||
@ -10,8 +10,8 @@
|
||||
#: repository's HEAD will be checked for updates when a new stable or devel
|
||||
#: version has been released.
|
||||
#:
|
||||
#: If <formulae> are given, upgrade only the specified brews (but do so even
|
||||
#: if they are pinned; see `pin`, `unpin`).
|
||||
#: If <formulae> are given, upgrade only the specified brews (unless they
|
||||
#: are pinned; see `pin`, `unpin`).
|
||||
|
||||
require "cmd/install"
|
||||
require "cleanup"
|
||||
@ -118,7 +118,7 @@ module Homebrew
|
||||
|
||||
fi = FormulaInstaller.new(f)
|
||||
fi.options = options
|
||||
fi.build_bottle = ARGV.build_bottle? || (!f.bottled? && f.build.build_bottle?)
|
||||
fi.build_bottle = ARGV.build_bottle? || (!f.bottled? && f.build.bottle?)
|
||||
fi.installed_on_request = !ARGV.named.empty?
|
||||
fi.link_keg ||= keg_was_linked if keg_had_linked_opt
|
||||
if tab
|
||||
@ -139,7 +139,7 @@ module Homebrew
|
||||
rescue FormulaInstallationAlreadyAttemptedError
|
||||
# We already attempted to upgrade f as part of the dependency tree of
|
||||
# another formula. In that case, don't generate an error, just move on.
|
||||
return
|
||||
nil
|
||||
rescue CannotInstallFormulaError => e
|
||||
ofail e
|
||||
rescue BuildError => e
|
||||
|
||||
@ -52,11 +52,11 @@ class DependencyCollector
|
||||
output_deprecation(spec, "open-mpi")
|
||||
Dependency.new("open-mpi", tags)
|
||||
when :python, :python2
|
||||
output_deprecation(spec, "python@2")
|
||||
Dependency.new("python@2", tags)
|
||||
when :python3
|
||||
output_deprecation(spec, "python")
|
||||
Dependency.new("python", tags)
|
||||
when :python3
|
||||
output_deprecation(spec, "python3")
|
||||
Dependency.new("python3", tags)
|
||||
when :emacs, :mysql, :perl, :postgresql, :rbenv, :ruby
|
||||
output_deprecation(spec)
|
||||
Dependency.new(spec.to_s, tags)
|
||||
|
||||
@ -84,16 +84,16 @@ end
|
||||
class PythonRequirement < Requirement
|
||||
fatal true
|
||||
satisfy do
|
||||
odeprecated("PythonRequirement", "'depends_on \"python\"'")
|
||||
which "python"
|
||||
odeprecated("PythonRequirement", "'depends_on \"python@2\"'")
|
||||
which "python2"
|
||||
end
|
||||
end
|
||||
|
||||
class Python3Requirement < Requirement
|
||||
fatal true
|
||||
satisfy do
|
||||
odeprecated("Python3Requirement", "'depends_on \"python3\"'")
|
||||
which "python3"
|
||||
odeprecated("Python3Requirement", "'depends_on \"python\"'")
|
||||
which "python"
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@ -38,9 +38,9 @@ class LanguageModuleRequirement < Requirement
|
||||
when :perl
|
||||
["/usr/bin/env", "perl", "-e", "use #{@import_name}"]
|
||||
when :python
|
||||
["/usr/bin/env", "python", "-c", "import #{@import_name}"]
|
||||
["/usr/bin/env", "python2", "-c", "import #{@import_name}"]
|
||||
when :python3
|
||||
["/usr/bin/env", "python3", "-c", "import #{@import_name}"]
|
||||
["/usr/bin/env", "python", "-c", "import #{@import_name}"]
|
||||
when :ruby
|
||||
["/usr/bin/env", "ruby", "-rubygems", "-e", "require '#{@import_name}'"]
|
||||
end
|
||||
@ -51,8 +51,8 @@ class LanguageModuleRequirement < Requirement
|
||||
when :lua then "luarocks-5.2 install"
|
||||
when :lua51 then "luarocks-5.1 install"
|
||||
when :perl then "cpan -i"
|
||||
when :python then "pip install"
|
||||
when :python3 then "pip3 install"
|
||||
when :python then "pip3 install"
|
||||
when :python3 then "pip install"
|
||||
when :ruby then "gem install"
|
||||
end
|
||||
end
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# RuboCop version used for `brew style` and `brew cask style`
|
||||
HOMEBREW_RUBOCOP_VERSION = "0.52.1"
|
||||
HOMEBREW_RUBOCOP_CASK_VERSION = "~> 0.16.0" # has to be updated when RuboCop version changes
|
||||
HOMEBREW_RUBOCOP_VERSION = "0.53.0"
|
||||
HOMEBREW_RUBOCOP_CASK_VERSION = "~> 0.17.0" # has to be updated when RuboCop version changes
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
require "options"
|
||||
|
||||
module Dependable
|
||||
RESERVED_TAGS = [:build, :optional, :recommended, :run, :linked].freeze
|
||||
RESERVED_TAGS = [:build, :optional, :recommended, :run, :test, :linked].freeze
|
||||
|
||||
def build?
|
||||
tags.include? :build
|
||||
@ -19,8 +19,12 @@ module Dependable
|
||||
tags.include? :run
|
||||
end
|
||||
|
||||
def test?
|
||||
tags.include? :test
|
||||
end
|
||||
|
||||
def required?
|
||||
!build? && !optional? && !recommended?
|
||||
!build? && !test? && !optional? && !recommended?
|
||||
end
|
||||
|
||||
def option_tags
|
||||
|
||||
@ -143,8 +143,9 @@ class Dependency
|
||||
private
|
||||
|
||||
def merge_tags(deps)
|
||||
options = deps.flat_map(&:option_tags).uniq
|
||||
merge_necessity(deps) + merge_temporality(deps) + options
|
||||
other_tags = deps.flat_map(&:option_tags).uniq
|
||||
other_tags << :test if deps.flat_map(&:tags).include?(:test)
|
||||
merge_necessity(deps) + merge_temporality(deps) + other_tags
|
||||
end
|
||||
|
||||
def merge_necessity(deps)
|
||||
|
||||
@ -70,8 +70,8 @@ class DependencyCollector
|
||||
Dependency.new("xz", tags) unless which("xz")
|
||||
end
|
||||
|
||||
def zip_dep_if_needed(tags)
|
||||
Dependency.new("zip", tags) unless which("zip")
|
||||
def unzip_dep_if_needed(tags)
|
||||
Dependency.new("unzip", tags) unless which("unzip")
|
||||
end
|
||||
|
||||
def bzip2_dep_if_needed(tags)
|
||||
@ -166,7 +166,7 @@ class DependencyCollector
|
||||
def parse_url_spec(url, tags)
|
||||
case File.extname(url)
|
||||
when ".xz" then xz_dep_if_needed(tags)
|
||||
when ".zip" then zip_dep_if_needed(tags)
|
||||
when ".zip" then unzip_dep_if_needed(tags)
|
||||
when ".bz2" then bzip2_dep_if_needed(tags)
|
||||
when ".lha", ".lzh" then Dependency.new("lha", tags)
|
||||
when ".lz" then Dependency.new("lzip", tags)
|
||||
|
||||
@ -45,6 +45,18 @@ module Homebrew
|
||||
next
|
||||
end
|
||||
|
||||
# Don't test formulae missing test dependencies
|
||||
missing_test_deps = f.recursive_dependencies do |_, dependency|
|
||||
Dependency.prune if dependency.installed?
|
||||
next if dependency.test?
|
||||
Dependency.prune if dependency.optional?
|
||||
Dependency.prune if dependency.build?
|
||||
end.map(&:to_s)
|
||||
unless missing_test_deps.empty?
|
||||
ofail "#{f.full_name} is missing test dependencies: #{missing_test_deps.join(" ")}"
|
||||
next
|
||||
end
|
||||
|
||||
puts "Testing #{f.full_name}"
|
||||
|
||||
env = ENV.to_hash
|
||||
|
||||
@ -934,7 +934,7 @@ module Homebrew
|
||||
from your PATH variable.
|
||||
Python scripts will now install into #{HOMEBREW_PREFIX}/bin.
|
||||
You can delete anything, except 'Extras', from the #{HOMEBREW_PREFIX}/share/python
|
||||
(and #{HOMEBREW_PREFIX}/share/python3) dir and install affected Python packages
|
||||
(and #{HOMEBREW_PREFIX}/share/python@2) dir and install affected Python packages
|
||||
anew with `pip install --upgrade`.
|
||||
EOS
|
||||
end
|
||||
@ -966,7 +966,7 @@ module Homebrew
|
||||
Putting non-prefixed coreutils in your path can cause gmp builds to fail.
|
||||
EOS
|
||||
rescue FormulaUnavailableError
|
||||
return
|
||||
nil
|
||||
end
|
||||
|
||||
def check_for_non_prefixed_findutils
|
||||
@ -981,7 +981,7 @@ module Homebrew
|
||||
Putting non-prefixed findutils in your path can cause python builds to fail.
|
||||
EOS
|
||||
rescue FormulaUnavailableError
|
||||
return
|
||||
nil
|
||||
end
|
||||
|
||||
def check_for_pydistutils_cfg_in_home
|
||||
@ -1016,24 +1016,6 @@ module Homebrew
|
||||
EOS
|
||||
end
|
||||
|
||||
def check_for_pth_support
|
||||
homebrew_site_packages = Language::Python.homebrew_site_packages
|
||||
return unless homebrew_site_packages.directory?
|
||||
return if Language::Python.reads_brewed_pth_files?("python") != false
|
||||
return unless Language::Python.in_sys_path?("python", homebrew_site_packages)
|
||||
|
||||
user_site_packages = Language::Python.user_site_packages "python"
|
||||
<<~EOS
|
||||
Your default Python does not recognize the Homebrew site-packages
|
||||
directory as a special site-packages directory, which means that .pth
|
||||
files will not be followed. This means you will not be able to import
|
||||
some modules after installing them with Homebrew, like wxpython. To fix
|
||||
this for the current user, you can run:
|
||||
mkdir -p #{user_site_packages}
|
||||
echo 'import site; site.addsitedir("#{homebrew_site_packages}")' >> #{user_site_packages}/homebrew.pth
|
||||
EOS
|
||||
end
|
||||
|
||||
def check_for_external_cmd_name_conflict
|
||||
cmds = Tap.cmd_directories.flat_map { |p| Dir["#{p}/brew-*"] }.uniq
|
||||
cmds = cmds.select { |cmd| File.file?(cmd) && File.executable?(cmd) }
|
||||
|
||||
@ -604,7 +604,7 @@ class GitHubPrivateRepositoryReleaseDownloadStrategy < GitHubPrivateRepositoryDo
|
||||
|
||||
def fetch_release_metadata
|
||||
release_url = "https://api.github.com/repos/#{@owner}/#{@repo}/releases/tags/#{@tag}"
|
||||
GitHub.open(release_url)
|
||||
GitHub.open_api(release_url)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@ -343,8 +343,8 @@ class FormulaAmbiguousPythonError < RuntimeError
|
||||
def initialize(formula)
|
||||
super <<~EOS
|
||||
The version of python to use with the virtualenv in the `#{formula.full_name}` formula
|
||||
cannot be guessed automatically. If the simultaneous use of python and python3
|
||||
is intentional, please add `:using => "python"` or `:using => "python3"` to
|
||||
cannot be guessed automatically. If the simultaneous use of python and python@2
|
||||
is intentional, please add `:using => "python"` or `:using => "python@2"` to
|
||||
`virtualenv_install_with_resources` to resolve the ambiguity manually.
|
||||
EOS
|
||||
end
|
||||
|
||||
@ -28,9 +28,9 @@ module EnvActivation
|
||||
end
|
||||
|
||||
def clear_sensitive_environment!
|
||||
ENV.each_key do |key|
|
||||
each_key do |key|
|
||||
next unless /(cookie|key|token|password)/i =~ key
|
||||
ENV.delete key
|
||||
delete key
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -173,11 +173,22 @@ module Superenv
|
||||
end
|
||||
|
||||
def determine_library_paths
|
||||
PATH.new(
|
||||
paths = [
|
||||
keg_only_deps.map(&:opt_lib),
|
||||
HOMEBREW_PREFIX/"lib",
|
||||
homebrew_extra_library_paths,
|
||||
).existing
|
||||
]
|
||||
|
||||
if compiler == :llvm_clang
|
||||
if MacOS::CLT.installed?
|
||||
paths << "/usr/lib"
|
||||
else
|
||||
paths << "#{MacOS.sdk_path}/usr/lib"
|
||||
end
|
||||
paths << Formula["llvm"].opt_lib.to_s
|
||||
end
|
||||
|
||||
paths += homebrew_extra_library_paths
|
||||
PATH.new(paths).existing
|
||||
end
|
||||
|
||||
def determine_dependencies
|
||||
|
||||
@ -31,7 +31,7 @@ class SystemConfig
|
||||
return "N/A" unless CoreTap.instance.installed?
|
||||
Formulary.factory(formula).linked_version || "N/A"
|
||||
rescue FormulaUnavailableError
|
||||
return "N/A"
|
||||
"N/A"
|
||||
end
|
||||
|
||||
def dump_verbose_config(out = $stdout)
|
||||
|
||||
@ -2219,12 +2219,12 @@ class Formula
|
||||
# # `build.with?` or `build.without? "another_formula"`:
|
||||
# depends_on "postgresql" if build.without? "sqlite"
|
||||
#
|
||||
# <pre># Python 2.7:
|
||||
# depends_on "python"</pre>
|
||||
# <pre># Python 2.7 but use system Python where possible
|
||||
# depends_on "python" if MacOS.version <= :snow_leopard</pre>
|
||||
# <pre># Python 3.x if the `--with-python3` is given to `brew install example`
|
||||
# <pre># Python 3.x if the `--with-python` is given to `brew install example`
|
||||
# depends_on "python3" => :optional</pre>
|
||||
# <pre># Python 2.7:
|
||||
# depends_on "python@2"</pre>
|
||||
# <pre># Python 2.7 but use system Python where possible
|
||||
# depends_on "python@2" if MacOS.version <= :snow_leopard</pre>
|
||||
def depends_on(dep)
|
||||
specs.each { |spec| spec.depends_on(dep) }
|
||||
end
|
||||
|
||||
@ -44,7 +44,7 @@ class FormulaVersions
|
||||
# continue walking the history
|
||||
ohai "#{e} in #{name} at revision #{rev}", e.backtrace if ARGV.debug?
|
||||
rescue FormulaUnavailableError
|
||||
return
|
||||
nil
|
||||
ensure
|
||||
Homebrew.raise_deprecation_exceptions = false
|
||||
end
|
||||
|
||||
@ -256,7 +256,11 @@ class Keg
|
||||
|
||||
aliases.each do |a|
|
||||
alias_symlink = opt/a
|
||||
alias_symlink.delete if alias_symlink.symlink? || alias_symlink.exist?
|
||||
if alias_symlink.symlink? && alias_symlink.exist?
|
||||
alias_symlink.delete if alias_symlink.realpath == opt_record.realpath
|
||||
elsif alias_symlink.symlink? || alias_symlink.exist?
|
||||
alias_symlink.delete
|
||||
end
|
||||
end
|
||||
|
||||
Pathname.glob("#{opt_record}@*").each do |a|
|
||||
@ -519,6 +523,7 @@ class Keg
|
||||
|
||||
def delete_pyc_files!
|
||||
find { |pn| pn.delete if %w[.pyc .pyo].include?(pn.extname) }
|
||||
find { |pn| pn.delete if pn.basename.to_s == "__pycache__" }
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
@ -9,7 +9,7 @@ module Language
|
||||
Version.create(version.to_s)
|
||||
end
|
||||
|
||||
def self.homebrew_site_packages(version = "2.7")
|
||||
def self.homebrew_site_packages(version = "3.6")
|
||||
HOMEBREW_PREFIX/"lib/python#{version}/site-packages"
|
||||
end
|
||||
|
||||
@ -89,7 +89,7 @@ module Language
|
||||
# @param venv_root [Pathname, String] the path to the root of the virtualenv
|
||||
# (often `libexec/"venv"`)
|
||||
# @param python [String] which interpreter to use (e.g. "python"
|
||||
# or "python3")
|
||||
# or "python2")
|
||||
# @param formula [Formula] the active Formula
|
||||
# @return [Virtualenv] a {Virtualenv} instance
|
||||
def virtualenv_create(venv_root, python = "python", formula = self)
|
||||
@ -115,8 +115,8 @@ module Language
|
||||
|
||||
# Returns true if a formula option for the specified python is currently
|
||||
# active or if the specified python is required by the formula. Valid
|
||||
# inputs are "python", "python3", :python, and :python3. Note that
|
||||
# "with-python", "without-python", "with-python3", and "without-python3"
|
||||
# inputs are "python", "python2", :python, and :python2. Note that
|
||||
# "with-python", "without-python", "with-python@2", and "without-python@2"
|
||||
# formula options are handled correctly even if not associated with any
|
||||
# corresponding depends_on statement.
|
||||
# @api private
|
||||
@ -128,16 +128,17 @@ module Language
|
||||
# Helper method for the common case of installing a Python application.
|
||||
# Creates a virtualenv in `libexec`, installs all `resource`s defined
|
||||
# on the formula, and then installs the formula. An options hash may be
|
||||
# passed (e.g., :using => "python3") to override the default, guessed
|
||||
# formula preference for python or python3, or to resolve an ambiguous
|
||||
# case where it's not clear whether python or python3 should be the
|
||||
# passed (e.g., :using => "python") to override the default, guessed
|
||||
# formula preference for python or python2, or to resolve an ambiguous
|
||||
# case where it's not clear whether python or python2 should be the
|
||||
# default guess.
|
||||
def virtualenv_install_with_resources(options = {})
|
||||
python = options[:using]
|
||||
if python.nil?
|
||||
wanted = %w[python python@2 python@3 python3].select { |py| needs_python?(py) }
|
||||
wanted = %w[python python@2 python2 python3 python@3].select { |py| needs_python?(py) }
|
||||
raise FormulaAmbiguousPythonError, self if wanted.size > 1
|
||||
python = wanted.first || "python2.7"
|
||||
python = "python3" if python == "python"
|
||||
end
|
||||
venv = virtualenv_create(libexec, python.delete("@"))
|
||||
venv.pip_install resources
|
||||
@ -154,7 +155,7 @@ module Language
|
||||
# @param venv_root [Pathname, String] the path to the root of the
|
||||
# virtualenv
|
||||
# @param python [String] which interpreter to use; i.e. "python" or
|
||||
# "python3"
|
||||
# "python2"
|
||||
def initialize(formula, venv_root, python)
|
||||
@formula = formula
|
||||
@venv_root = Pathname.new(venv_root)
|
||||
@ -180,11 +181,11 @@ module Language
|
||||
end
|
||||
end
|
||||
|
||||
# Robustify symlinks to survive python3 patch upgrades
|
||||
# Robustify symlinks to survive python patch upgrades
|
||||
@venv_root.find do |f|
|
||||
next unless f.symlink?
|
||||
next unless (rp = f.realpath.to_s).start_with? HOMEBREW_CELLAR
|
||||
python = rp.include?("python3") ? "python3" : "python"
|
||||
python = rp.include?("python@2") ? "python@2" : "python"
|
||||
new_target = rp.sub %r{#{HOMEBREW_CELLAR}/#{python}/[^/]+}, Formula[python].opt_prefix
|
||||
f.unlink
|
||||
f.make_symlink new_target
|
||||
@ -192,7 +193,7 @@ module Language
|
||||
|
||||
Pathname.glob(@venv_root/"lib/python*/orig-prefix.txt").each do |prefix_file|
|
||||
prefix_path = prefix_file.read
|
||||
python = prefix_path.include?("python3") ? "python3" : "python"
|
||||
python = prefix_path.include?("python@2") ? "python@2" : "python"
|
||||
prefix_path.sub! %r{^#{HOMEBREW_CELLAR}/#{python}/[^/]+}, Formula[python].opt_prefix
|
||||
prefix_file.atomic_write prefix_path
|
||||
end
|
||||
|
||||
@ -63,8 +63,7 @@ class LinkageChecker
|
||||
formula.build.without?(dep)
|
||||
end
|
||||
declared_deps = formula.deps.reject { |dep| filter_out.call(dep) }.map(&:name)
|
||||
recursive_deps = keg.to_formula.declared_runtime_dependencies
|
||||
.map { |dep| dep.to_formula.full_name }
|
||||
recursive_deps = keg.to_formula.declared_runtime_dependencies.map { |dep| dep.to_formula.name }
|
||||
declared_dep_names = declared_deps.map { |dep| dep.split("/").last }
|
||||
indirect_deps = []
|
||||
undeclared_deps = []
|
||||
|
||||
@ -183,7 +183,7 @@ class Migrator
|
||||
end
|
||||
|
||||
def migrate
|
||||
oh1 "Migrating #{Formatter.identifier(oldname)} to #{Formatter.identifier(newname)}"
|
||||
oh1 "Processing #{Formatter.identifier(oldname)} formula rename to #{Formatter.identifier(newname)}"
|
||||
lock
|
||||
unlink_oldname
|
||||
unlink_newname if new_cellar.exist?
|
||||
@ -193,6 +193,14 @@ class Migrator
|
||||
link_oldname_opt
|
||||
link_newname unless old_linked_keg.nil?
|
||||
update_tabs
|
||||
return unless formula.outdated?
|
||||
opoo <<~EOS
|
||||
#{Formatter.identifier(newname)} is outdated!
|
||||
To avoid broken installations, as soon as possible please run:
|
||||
brew upgrade
|
||||
Or, if you're OK with a less reliable fix:
|
||||
brew upgrade #{newname}
|
||||
EOS
|
||||
rescue Interrupt
|
||||
ignore_interrupts { backup_oldname }
|
||||
rescue Exception => e # rubocop:disable Lint/RescueException
|
||||
@ -226,7 +234,7 @@ class Migrator
|
||||
end
|
||||
end
|
||||
|
||||
oh1 "Moving #{Formatter.identifier(oldname)} children"
|
||||
oh1 "Moving #{Formatter.identifier(oldname)} versions to #{new_cellar}"
|
||||
if new_cellar.exist?
|
||||
FileUtils.mv(old_cellar.children, new_cellar)
|
||||
else
|
||||
@ -261,7 +269,7 @@ class Migrator
|
||||
end
|
||||
|
||||
def unlink_newname
|
||||
oh1 "Unlinking #{Formatter.identifier(newname)}"
|
||||
oh1 "Temporarily unlinking #{Formatter.identifier(newname)}"
|
||||
new_cellar.subdirs.each do |d|
|
||||
keg = Keg.new(d)
|
||||
keg.unlink
|
||||
@ -269,7 +277,7 @@ class Migrator
|
||||
end
|
||||
|
||||
def link_newname
|
||||
oh1 "Linking #{Formatter.identifier(newname)}"
|
||||
oh1 "Relinking #{Formatter.identifier(newname)}"
|
||||
new_keg = Keg.new(new_linked_keg_record)
|
||||
|
||||
# If old_keg wasn't linked then we just optlink a keg.
|
||||
@ -288,7 +296,8 @@ class Migrator
|
||||
new_keg.remove_linked_keg_record if new_keg.linked?
|
||||
|
||||
begin
|
||||
new_keg.link
|
||||
mode = OpenStruct.new(overwrite: true)
|
||||
new_keg.link(mode)
|
||||
rescue Keg::ConflictError => e
|
||||
onoe "Error while executing `brew link` step on #{newname}"
|
||||
puts e
|
||||
|
||||
@ -131,7 +131,7 @@ module OS
|
||||
xcodebuild_output = Utils.popen_read(xcodebuild_path, "-version")
|
||||
next unless $CHILD_STATUS.success?
|
||||
|
||||
xcode_version = xcodebuild_output[/Xcode (\d(\.\d)*)/, 1]
|
||||
xcode_version = xcodebuild_output[/Xcode (\d+(\.\d+)*)/, 1]
|
||||
return xcode_version if xcode_version
|
||||
|
||||
# Xcode 2.x's xcodebuild has a different version string
|
||||
|
||||
@ -2,6 +2,7 @@ require_relative "./rubocops/bottle_block_cop"
|
||||
require_relative "./rubocops/formula_desc_cop"
|
||||
require_relative "./rubocops/components_order_cop"
|
||||
require_relative "./rubocops/components_redundancy_cop"
|
||||
require_relative "./rubocops/dependency_order_cop"
|
||||
require_relative "./rubocops/homepage_cop"
|
||||
require_relative "./rubocops/text_cop"
|
||||
require_relative "./rubocops/caveats_cop"
|
||||
|
||||
166
Library/Homebrew/rubocops/dependency_order_cop.rb
Normal file
166
Library/Homebrew/rubocops/dependency_order_cop.rb
Normal file
@ -0,0 +1,166 @@
|
||||
require_relative "./extend/formula_cop"
|
||||
|
||||
module RuboCop
|
||||
module Cop
|
||||
module NewFormulaAudit
|
||||
# This cop checks for correct order of `depends_on` in a Formula
|
||||
#
|
||||
# precedence order:
|
||||
# build-time > run-time > normal > recommended > optional
|
||||
class DependencyOrder < FormulaCop
|
||||
def audit_formula(_node, _class_node, _parent_class_node, body_node)
|
||||
check_dependency_nodes_order(body_node)
|
||||
[:devel, :head, :stable].each do |block_name|
|
||||
block = find_block(body_node, block_name)
|
||||
next unless block
|
||||
check_dependency_nodes_order(block.body)
|
||||
end
|
||||
end
|
||||
|
||||
def check_dependency_nodes_order(parent_node)
|
||||
return if parent_node.nil?
|
||||
dependency_nodes = fetch_depends_on_nodes(parent_node)
|
||||
ordered = dependency_nodes.sort { |a, b| sort_by_dependency_name(a, b) }
|
||||
ordered = sort_dependencies_by_type(ordered)
|
||||
sort_conditional_dependencies!(ordered)
|
||||
verify_order_in_source(ordered)
|
||||
end
|
||||
|
||||
# Match all `depends_on` nodes among childnodes of given parent node
|
||||
def fetch_depends_on_nodes(parent_node)
|
||||
parent_node.each_child_node.select { |x| depends_on_node?(x) }
|
||||
end
|
||||
|
||||
def sort_by_dependency_name(a, b)
|
||||
a_name = dependency_name(a)
|
||||
b_name = dependency_name(b)
|
||||
if a_name < b_name
|
||||
-1
|
||||
elsif a_name > b_name
|
||||
1
|
||||
else
|
||||
0
|
||||
end
|
||||
end
|
||||
|
||||
# Separate dependencies according to precedence order:
|
||||
# build-time > run-time > normal > recommended > optional
|
||||
def sort_dependencies_by_type(dependency_nodes)
|
||||
ordered = []
|
||||
ordered.concat(dependency_nodes.select { |dep| buildtime_dependency? dep }.to_a)
|
||||
ordered.concat(dependency_nodes.select { |dep| runtime_dependency? dep }.to_a)
|
||||
ordered.concat(dependency_nodes.reject { |dep| negate_normal_dependency? dep }.to_a)
|
||||
ordered.concat(dependency_nodes.select { |dep| recommended_dependency? dep }.to_a)
|
||||
ordered.concat(dependency_nodes.select { |dep| optional_dependency? dep }.to_a)
|
||||
end
|
||||
|
||||
# `depends_on :apple if build.with? "foo"` should always be defined
|
||||
# after `depends_on :foo`
|
||||
# This method reorders dependencies array according to above rule
|
||||
def sort_conditional_dependencies!(ordered)
|
||||
length = ordered.size
|
||||
idx = 0
|
||||
while idx < length
|
||||
idx1, idx2 = nil
|
||||
ordered.each_with_index do |dep, pos|
|
||||
idx = pos+1
|
||||
match_nodes = build_with_dependency_name(dep)
|
||||
idx1 = pos if match_nodes && !match_nodes.empty?
|
||||
next unless idx1
|
||||
idx2 = nil
|
||||
ordered.drop(idx1+1).each_with_index do |dep2, pos2|
|
||||
next unless match_nodes.index(dependency_name(dep2))
|
||||
idx2 = pos2 if idx2.nil? || pos2 > idx2
|
||||
end
|
||||
break if idx2
|
||||
end
|
||||
insert_after!(ordered, idx1, idx2+idx1) if idx2
|
||||
end
|
||||
ordered
|
||||
end
|
||||
|
||||
# Verify actual order of sorted `depends_on` nodes in source code
|
||||
# Else raise RuboCop problem
|
||||
def verify_order_in_source(ordered)
|
||||
ordered.each_with_index do |dependency_node_1, idx|
|
||||
l1 = line_number(dependency_node_1)
|
||||
dependency_node_2 = nil
|
||||
ordered.drop(idx+1).each do |node2|
|
||||
l2 = line_number(node2)
|
||||
dependency_node_2 = node2 if l2 < l1
|
||||
end
|
||||
next unless dependency_node_2
|
||||
@offensive_nodes = [dependency_node_1, dependency_node_2]
|
||||
component_problem dependency_node_1, dependency_node_2
|
||||
end
|
||||
end
|
||||
|
||||
# Node pattern method to match
|
||||
# `depends_on` variants
|
||||
def_node_matcher :depends_on_node?, <<~EOS
|
||||
{(if _ (send nil? :depends_on ...) nil?)
|
||||
(send nil? :depends_on ...)}
|
||||
EOS
|
||||
|
||||
def_node_search :buildtime_dependency?, "(sym :build)"
|
||||
|
||||
def_node_search :recommended_dependency?, "(sym :recommended)"
|
||||
|
||||
def_node_search :runtime_dependency?, "(sym :run)"
|
||||
|
||||
def_node_search :optional_dependency?, "(sym :optional)"
|
||||
|
||||
def_node_search :negate_normal_dependency?, "(sym {:build :recommended :run :optional})"
|
||||
|
||||
# Node pattern method to extract `name` in `depends_on :name`
|
||||
def_node_search :dependency_name_node, <<~EOS
|
||||
{(send nil? :depends_on {(hash (pair $_ _)) $({str sym} _)})
|
||||
(if _ (send nil? :depends_on {(hash (pair $_ _)) $({str sym} _)}) nil?)}
|
||||
EOS
|
||||
|
||||
# Node pattern method to extract `name` in `build.with? :name`
|
||||
def_node_search :build_with_dependency_node, <<~EOS
|
||||
(send (send nil? :build) :with? $({str sym} _))
|
||||
EOS
|
||||
|
||||
def insert_after!(arr, idx1, idx2)
|
||||
arr.insert(idx2+1, arr.delete_at(idx1))
|
||||
end
|
||||
|
||||
def build_with_dependency_name(node)
|
||||
match_nodes = build_with_dependency_node(node)
|
||||
match_nodes = match_nodes.to_a.delete_if(&:nil?)
|
||||
match_nodes.map { |n| string_content(n) } unless match_nodes.empty?
|
||||
end
|
||||
|
||||
def dependency_name(dependency_node)
|
||||
match_node = dependency_name_node(dependency_node).to_a.first
|
||||
string_content(match_node) if match_node
|
||||
end
|
||||
|
||||
def autocorrect(_node)
|
||||
succeeding_node = @offensive_nodes[0]
|
||||
preceding_node = @offensive_nodes[1]
|
||||
lambda do |corrector|
|
||||
reorder_components(corrector, succeeding_node, preceding_node)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def component_problem(c1, c2)
|
||||
offending_node(c1)
|
||||
problem "dependency \"#{dependency_name(c1)}\" (line #{line_number(c1)}) should be put before dependency \"#{dependency_name(c2)}\" (line #{line_number(c2)})"
|
||||
end
|
||||
|
||||
# Reorder two nodes in the source, using the corrector instance in autocorrect method
|
||||
def reorder_components(corrector, node1, node2)
|
||||
indentation = " " * (start_column(node2) - line_start_column(node2))
|
||||
line_breaks = "\n"
|
||||
corrector.insert_before(node2.source_range, node1.source + line_breaks + indentation)
|
||||
corrector.remove(range_with_surrounding_space(range: node1.source_range, side: :left))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -4,6 +4,8 @@ require_relative "../../extend/string"
|
||||
module RuboCop
|
||||
module Cop
|
||||
class FormulaCop < Cop
|
||||
include RangeHelp
|
||||
|
||||
attr_accessor :file_path
|
||||
@registry = Cop.registry
|
||||
|
||||
|
||||
@ -108,10 +108,10 @@ class Sandbox
|
||||
|
||||
unless logs.empty?
|
||||
if @logfile
|
||||
log = open(@logfile, "w")
|
||||
File.open(@logfile, "w") do |log|
|
||||
log.write logs
|
||||
log.write "\nWe use time to filter sandbox log. Therefore, unrelated logs may be recorded.\n"
|
||||
log.close
|
||||
end
|
||||
end
|
||||
|
||||
if @failed && ARGV.verbose?
|
||||
|
||||
@ -326,8 +326,8 @@ class Tab < OpenStruct
|
||||
"time" => time,
|
||||
"source_modified_time" => source_modified_time.to_i,
|
||||
"HEAD" => self.HEAD,
|
||||
"stdlib" => (stdlib.to_s if stdlib),
|
||||
"compiler" => (compiler.to_s if compiler),
|
||||
"stdlib" => (stdlib&.to_s),
|
||||
"compiler" => (compiler&.to_s),
|
||||
"aliases" => aliases,
|
||||
"runtime_dependencies" => runtime_dependencies,
|
||||
"source" => source,
|
||||
|
||||
@ -141,6 +141,20 @@ shared_examples EnvActivation do
|
||||
|
||||
expect(subject["MAKEFLAGS"]).to eq("-j4")
|
||||
end
|
||||
|
||||
describe "#clear_sensitive_environment!" do
|
||||
it "removes sensitive environment variables" do
|
||||
subject["SECRET_TOKEN"] = "password"
|
||||
subject.clear_sensitive_environment!
|
||||
expect(subject).not_to include("SECRET_TOKEN")
|
||||
end
|
||||
|
||||
it "leaves non-sensitive environment variables alone" do
|
||||
subject["FOO"] = "bar"
|
||||
subject.clear_sensitive_environment!
|
||||
expect(subject["FOO"]).to eq "bar"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe Stdenv do
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
GEM
|
||||
remote: https://rubygems.org/
|
||||
specs:
|
||||
ast (2.3.0)
|
||||
ast (2.4.0)
|
||||
codecov (0.1.10)
|
||||
json
|
||||
simplecov
|
||||
@ -9,36 +9,36 @@ GEM
|
||||
diff-lcs (1.3)
|
||||
docile (1.1.5)
|
||||
json (2.1.0)
|
||||
parallel (1.12.0)
|
||||
parallel_tests (2.17.0)
|
||||
parallel (1.12.1)
|
||||
parallel_tests (2.21.2)
|
||||
parallel
|
||||
parser (2.4.0.2)
|
||||
ast (~> 2.3)
|
||||
parser (2.5.0.2)
|
||||
ast (~> 2.4.0)
|
||||
powerpack (0.1.1)
|
||||
rainbow (3.0.0)
|
||||
rspec (3.6.0)
|
||||
rspec-core (~> 3.6.0)
|
||||
rspec-expectations (~> 3.6.0)
|
||||
rspec-mocks (~> 3.6.0)
|
||||
rspec-core (3.6.0)
|
||||
rspec-support (~> 3.6.0)
|
||||
rspec-expectations (3.6.0)
|
||||
rspec (3.7.0)
|
||||
rspec-core (~> 3.7.0)
|
||||
rspec-expectations (~> 3.7.0)
|
||||
rspec-mocks (~> 3.7.0)
|
||||
rspec-core (3.7.1)
|
||||
rspec-support (~> 3.7.0)
|
||||
rspec-expectations (3.7.0)
|
||||
diff-lcs (>= 1.2.0, < 2.0)
|
||||
rspec-support (~> 3.6.0)
|
||||
rspec-support (~> 3.7.0)
|
||||
rspec-its (1.2.0)
|
||||
rspec-core (>= 3.0.0)
|
||||
rspec-expectations (>= 3.0.0)
|
||||
rspec-mocks (3.6.0)
|
||||
rspec-mocks (3.7.0)
|
||||
diff-lcs (>= 1.2.0, < 2.0)
|
||||
rspec-support (~> 3.6.0)
|
||||
rspec-support (~> 3.7.0)
|
||||
rspec-retry (0.5.6)
|
||||
rspec-core (> 3.3, < 3.8)
|
||||
rspec-support (3.6.0)
|
||||
rspec-support (3.7.1)
|
||||
rspec-wait (0.0.9)
|
||||
rspec (>= 3, < 4)
|
||||
rubocop (0.52.1)
|
||||
rubocop (0.53.0)
|
||||
parallel (~> 1.10)
|
||||
parser (>= 2.4.0.2, < 3.0)
|
||||
parser (>= 2.5)
|
||||
powerpack (~> 0.1)
|
||||
rainbow (>= 2.2.2, < 4.0)
|
||||
ruby-progressbar (~> 1.7)
|
||||
@ -62,7 +62,7 @@ DEPENDENCIES
|
||||
rspec-its
|
||||
rspec-retry
|
||||
rspec-wait
|
||||
rubocop (= 0.52.1)
|
||||
rubocop (= 0.53.0)
|
||||
simplecov
|
||||
|
||||
BUNDLED WITH
|
||||
|
||||
@ -201,45 +201,5 @@ describe Caveats do
|
||||
expect(caveats).to include(HOMEBREW_PREFIX/"share/fish/vendor_completions.d")
|
||||
end
|
||||
end
|
||||
|
||||
context "python caveats" do
|
||||
before do
|
||||
(f.prefix.resolved_path/"lib/python2.7/site-packages").mkpath
|
||||
end
|
||||
|
||||
context "when f is not keg_only" do
|
||||
let(:f) {
|
||||
formula do
|
||||
url "foo-1.0"
|
||||
end
|
||||
}
|
||||
let(:caveats) { described_class.new(f).caveats }
|
||||
let(:user_site_packages) { Language::Python.user_site_packages("python") }
|
||||
|
||||
it "give commands to run when Homebrew's site-packages is not in Python sys.path" do
|
||||
expect(caveats).to include("Homebrew's site-packages is not\nin your Python sys.path")
|
||||
expect(caveats).to include(user_site_packages)
|
||||
expect(caveats).to include("import site")
|
||||
end
|
||||
|
||||
it "gives commands to run when python pth files are installed" do
|
||||
allow(Homebrew).to receive(:_system).and_return(true)
|
||||
allow(Dir).to receive(:[]).with(any_args).and_return(["blah.pth"])
|
||||
expect(caveats).to include(".pth files to Homebrew's site-packages and your\nPython isn't configured")
|
||||
expect(caveats).to include(user_site_packages)
|
||||
expect(caveats).to include("import site")
|
||||
end
|
||||
end
|
||||
|
||||
it "gives commands to run when formula is keg_only" do
|
||||
f = formula do
|
||||
url "foo-1.0"
|
||||
keg_only "some reason"
|
||||
end
|
||||
caveats = described_class.new(f).caveats
|
||||
homebrew_site_packages = Language::Python.homebrew_site_packages
|
||||
expect(caveats).to include("echo #{f.opt_prefix}/lib/python2.7/site-packages >> #{homebrew_site_packages/f.name}.pth")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -29,7 +29,7 @@ describe "brew migrate", :integration_test do
|
||||
install_and_rename_coretap_formula "testball1", "testball2"
|
||||
|
||||
expect { brew "migrate", "testball1" }
|
||||
.to output(/Migrating testball1 to testball2/).to_stdout
|
||||
.to output(/Processing testball1 formula rename to testball2/).to_stdout
|
||||
.and not_to_output.to_stderr
|
||||
.and be_a_success
|
||||
end
|
||||
|
||||
@ -16,7 +16,7 @@ describe Homebrew do
|
||||
],
|
||||
}
|
||||
|
||||
allow(GitHub).to receive(:open).and_yield(json_response)
|
||||
allow(GitHub).to receive(:open_api).and_yield(json_response)
|
||||
|
||||
expect(described_class.search_taps("some-formula"))
|
||||
.to match(["homebrew/foo/some-formula"])
|
||||
|
||||
@ -116,7 +116,7 @@ describe GitHubPrivateRepositoryReleaseDownloadStrategy do
|
||||
describe "#fetch_release_metadata" do
|
||||
it "fetches release metadata from GitHub" do
|
||||
expected_release_url = "https://api.github.com/repos/owner/repo/releases/tags/tag"
|
||||
expect(GitHub).to receive(:open).with(expected_release_url).and_return({})
|
||||
expect(GitHub).to receive(:open_api).with(expected_release_url).and_return({})
|
||||
subject.send(:fetch_release_metadata)
|
||||
end
|
||||
end
|
||||
|
||||
@ -31,10 +31,6 @@ describe LanguageModuleRequirement, :needs_compat do
|
||||
it "does not satisfy invalid dependencies" do
|
||||
expect(described_class.new(:python, "notapackage")).not_to be_satisfied
|
||||
end
|
||||
|
||||
it "satisfies valid dependencies" do
|
||||
expect(described_class.new(:python, "datetime")).to be_satisfied
|
||||
end
|
||||
end
|
||||
|
||||
context "when the language is Ruby" do
|
||||
|
||||
@ -10,7 +10,7 @@ describe DependencyCollector do
|
||||
describe "#add" do
|
||||
resource = Resource.new
|
||||
|
||||
context "when xz, zip, and bzip2 are not available" do
|
||||
context "when xz, unzip, and bzip2 are not available" do
|
||||
it "creates a resource dependency from a '.xz' URL" do
|
||||
resource.url("http://example.com/foo.xz")
|
||||
allow_any_instance_of(Object).to receive(:which).with("xz")
|
||||
@ -19,8 +19,8 @@ describe DependencyCollector do
|
||||
|
||||
it "creates a resource dependency from a '.zip' URL" do
|
||||
resource.url("http://example.com/foo.zip")
|
||||
allow_any_instance_of(Object).to receive(:which).with("zip")
|
||||
expect(subject.add(resource)).to eq(Dependency.new("zip", [:build]))
|
||||
allow_any_instance_of(Object).to receive(:which).with("unzip")
|
||||
expect(subject.add(resource)).to eq(Dependency.new("unzip", [:build]))
|
||||
end
|
||||
|
||||
it "creates a resource dependency from a '.bz2' URL" do
|
||||
@ -39,7 +39,7 @@ describe DependencyCollector do
|
||||
|
||||
it "does not create a resource dependency from a '.zip' URL" do
|
||||
resource.url("http://example.com/foo.zip")
|
||||
allow_any_instance_of(Object).to receive(:which).with("zip").and_return(Pathname.new("foo"))
|
||||
allow_any_instance_of(Object).to receive(:which).with("unzip").and_return(Pathname.new("foo"))
|
||||
expect(subject.add(resource)).to be nil
|
||||
end
|
||||
|
||||
|
||||
75
Library/Homebrew/test/rubocops/dependency_order_cop_spec.rb
Normal file
75
Library/Homebrew/test/rubocops/dependency_order_cop_spec.rb
Normal file
@ -0,0 +1,75 @@
|
||||
require_relative "../../rubocops/dependency_order_cop"
|
||||
|
||||
describe RuboCop::Cop::NewFormulaAudit::DependencyOrder do
|
||||
subject(:cop) { described_class.new }
|
||||
|
||||
context "depends_on" do
|
||||
it "wrong conditional depends_on order" do
|
||||
expect_offense(<<~RUBY)
|
||||
class Foo < Formula
|
||||
homepage "http://example.com"
|
||||
url "http://example.com/foo-1.0.tgz"
|
||||
depends_on "apple" if build.with? "foo"
|
||||
depends_on "foo" => :optional
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ dependency "foo" (line 5) should be put before dependency "apple" (line 4)
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it "wrong alphabetical depends_on order" do
|
||||
expect_offense(<<~RUBY)
|
||||
class Foo < Formula
|
||||
homepage "http://example.com"
|
||||
url "http://example.com/foo-1.0.tgz"
|
||||
depends_on "foo"
|
||||
depends_on "bar"
|
||||
^^^^^^^^^^^^^^^^ dependency "bar" (line 5) should be put before dependency "foo" (line 4)
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it "wrong conditional depends_on order" do
|
||||
expect_offense(<<~RUBY)
|
||||
class Foo < Formula
|
||||
homepage "http://example.com"
|
||||
url "http://example.com/foo-1.0.tgz"
|
||||
head do
|
||||
depends_on "apple" if build.with? "foo"
|
||||
depends_on "bar"
|
||||
^^^^^^^^^^^^^^^^ dependency "bar" (line 6) should be put before dependency "apple" (line 5)
|
||||
depends_on "foo" => :optional
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ dependency "foo" (line 7) should be put before dependency "apple" (line 5)
|
||||
end
|
||||
depends_on "apple" if build.with? "foo"
|
||||
depends_on "foo" => :optional
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ dependency "foo" (line 10) should be put before dependency "apple" (line 9)
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
end
|
||||
|
||||
context "autocorrect" do
|
||||
it "wrong conditional depends_on order" do
|
||||
source = <<~EOS
|
||||
class Foo < Formula
|
||||
homepage "http://example.com"
|
||||
url "http://example.com/foo-1.0.tgz"
|
||||
depends_on "apple" if build.with? "foo"
|
||||
depends_on "foo" => :optional
|
||||
end
|
||||
EOS
|
||||
|
||||
correct_source = <<~EOS
|
||||
class Foo < Formula
|
||||
homepage "http://example.com"
|
||||
url "http://example.com/foo-1.0.tgz"
|
||||
depends_on "foo" => :optional
|
||||
depends_on "apple" if build.with? "foo"
|
||||
end
|
||||
EOS
|
||||
|
||||
corrected_source = autocorrect_source(source)
|
||||
expect(corrected_source).to eq(correct_source)
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -16,9 +16,9 @@ TEST_TMPDIR = ENV.fetch("HOMEBREW_TEST_TMPDIR") do |k|
|
||||
end
|
||||
|
||||
# Paths pointing into the Homebrew code base that persist across test runs
|
||||
HOMEBREW_LIBRARY_PATH = Pathname.new(File.expand_path("../../../..", __FILE__))
|
||||
HOMEBREW_LIBRARY_PATH = Pathname.new(File.expand_path("../../..", __dir__))
|
||||
HOMEBREW_SHIMS_PATH = HOMEBREW_LIBRARY_PATH.parent+"Homebrew/shims"
|
||||
HOMEBREW_LOAD_PATH = [File.expand_path("..", __FILE__), HOMEBREW_LIBRARY_PATH].join(":")
|
||||
HOMEBREW_LOAD_PATH = [File.expand_path(__dir__), HOMEBREW_LIBRARY_PATH].join(":")
|
||||
|
||||
# Paths redirected to a temporary directory and wiped at the end of the test run
|
||||
HOMEBREW_PREFIX = Pathname.new(TEST_TMPDIR).join("prefix")
|
||||
|
||||
@ -3,9 +3,9 @@ require "formula_installer"
|
||||
|
||||
describe Utils::Analytics do
|
||||
describe "::os_prefix_ci" do
|
||||
context "when anonymous_os_prefix_ci is not set" do
|
||||
context "when os_prefix_ci is not set" do
|
||||
before(:each) do
|
||||
described_class.clear_anonymous_os_prefix_ci_cache
|
||||
described_class.clear_os_prefix_ci
|
||||
end
|
||||
|
||||
it "returns OS_VERSION and prefix when HOMEBREW_PREFIX is not /usr/local" do
|
||||
|
||||
@ -109,7 +109,9 @@ def odeprecated(method, replacement = nil, disable: false, disable_on: nil, call
|
||||
|
||||
if ARGV.homebrew_developer? || disable ||
|
||||
Homebrew.raise_deprecation_exceptions?
|
||||
if replacement || tap_message
|
||||
developer_message = message + "Or, even better, submit a PR to fix it!"
|
||||
end
|
||||
raise MethodDeprecatedError, developer_message
|
||||
elsif !Homebrew.auditing?
|
||||
opoo "#{message}\n"
|
||||
|
||||
@ -3,13 +3,13 @@ require "erb"
|
||||
module Utils
|
||||
module Analytics
|
||||
class << self
|
||||
def clear_anonymous_os_prefix_ci_cache
|
||||
return unless instance_variable_defined?(:@anonymous_os_prefix_ci)
|
||||
remove_instance_variable(:@anonymous_os_prefix_ci)
|
||||
def clear_os_prefix_ci
|
||||
return unless instance_variable_defined?(:@os_prefix_ci)
|
||||
remove_instance_variable(:@os_prefix_ci)
|
||||
end
|
||||
|
||||
def os_prefix_ci
|
||||
@anonymous_os_prefix_ci ||= begin
|
||||
@os_prefix_ci ||= begin
|
||||
os = OS_VERSION
|
||||
prefix = ", non-/usr/local" if HOMEBREW_PREFIX.to_s != "/usr/local"
|
||||
ci = ", CI" if ENV["CI"]
|
||||
|
||||
@ -5,7 +5,7 @@ module Utils
|
||||
class Bottles
|
||||
class << self
|
||||
def tag
|
||||
@bottle_tag ||= "#{ENV["HOMEBREW_PROCESSOR"]}_#{ENV["HOMEBREW_SYSTEM"]}".downcase.to_sym
|
||||
@tag ||= "#{ENV["HOMEBREW_PROCESSOR"]}_#{ENV["HOMEBREW_SYSTEM"]}".downcase.to_sym
|
||||
end
|
||||
|
||||
def built_as?(f)
|
||||
|
||||
@ -27,7 +27,7 @@ end
|
||||
|
||||
module Utils
|
||||
def self.git_available?
|
||||
@git ||= quiet_system HOMEBREW_SHIMS_PATH/"scm/git", "--version"
|
||||
@git_available ||= quiet_system HOMEBREW_SHIMS_PATH/"scm/git", "--version"
|
||||
end
|
||||
|
||||
def self.git_path
|
||||
@ -61,7 +61,7 @@ module Utils
|
||||
end
|
||||
|
||||
def self.clear_git_available_cache
|
||||
@git = nil
|
||||
@git_available = nil
|
||||
@git_path = nil
|
||||
@git_version = nil
|
||||
end
|
||||
|
||||
@ -94,7 +94,7 @@ module GitHub
|
||||
def api_credentials_error_message(response_headers, needed_scopes)
|
||||
return if response_headers.empty?
|
||||
|
||||
@api_credentials_error_message_printed ||= begin
|
||||
@api_credentials_error_message ||= begin
|
||||
unauthorized = (response_headers["http/1.1"] == "401 Unauthorized")
|
||||
scopes = response_headers["x-accepted-oauth-scopes"].to_s.split(", ")
|
||||
needed_human_scopes = needed_scopes.join(", ")
|
||||
@ -125,7 +125,7 @@ module GitHub
|
||||
end
|
||||
end
|
||||
|
||||
def open(url, data: nil, scopes: [].freeze)
|
||||
def open_api(url, data: nil, scopes: [].freeze)
|
||||
# This is a no-op if the user is opting out of using the GitHub API.
|
||||
return block_given? ? yield({}) : {} if ENV["HOMEBREW_NO_GITHUB_API"]
|
||||
|
||||
@ -226,7 +226,7 @@ module GitHub
|
||||
end
|
||||
|
||||
def repository(user, repo)
|
||||
open(url_to("repos", user, repo))
|
||||
open_api(url_to("repos", user, repo))
|
||||
end
|
||||
|
||||
def search_code(**qualifiers)
|
||||
@ -255,7 +255,7 @@ module GitHub
|
||||
|
||||
def private_repo?(full_name)
|
||||
uri = url_to "repos", full_name
|
||||
open(uri) { |json| json["private"] }
|
||||
open_api(uri) { |json| json["private"] }
|
||||
end
|
||||
|
||||
def query_string(*main_params, **qualifiers)
|
||||
@ -275,6 +275,6 @@ module GitHub
|
||||
def search(entity, *queries, **qualifiers)
|
||||
uri = url_to "search", entity
|
||||
uri.query = query_string(*queries, **qualifiers)
|
||||
open(uri) { |json| json.fetch("items", []) }
|
||||
open_api(uri) { |json| json.fetch("items", []) }
|
||||
end
|
||||
end
|
||||
|
||||
4
bin/brew
4
bin/brew
@ -66,9 +66,9 @@ then
|
||||
|
||||
FILTERED_ENV=()
|
||||
# Filter all but the specific variables.
|
||||
for VAR in HOME SHELL PATH TERM LOGNAME USER CI TRAVIS TRAVIS_SUDO SSH_AUTH_SOCK SUDO_ASKPASS \
|
||||
for VAR in HOME SHELL PATH TERM LOGNAME USER CI TRAVIS SSH_AUTH_SOCK SUDO_ASKPASS \
|
||||
http_proxy https_proxy ftp_proxy no_proxy all_proxy HTTPS_PROXY FTP_PROXY ALL_PROXY \
|
||||
"${!HOMEBREW_@}"
|
||||
"${!HOMEBREW_@}" "${!TRAVIS_@}"
|
||||
do
|
||||
# Skip if variable value is empty.
|
||||
[[ -z "${!VAR}" ]] && continue
|
||||
|
||||
@ -38,15 +38,6 @@ tarballs should include the version in the filename whenever possible.
|
||||
We don’t accept software without a tagged version because they regularly break
|
||||
due to upstream changes and we can’t provide [bottles](Bottles.md) for them.
|
||||
|
||||
### Bindings
|
||||
First check that there is not already a binding available via
|
||||
[`gem`](https://rubygems.org/) or [`pip`](http://www.pip-installer.org/)
|
||||
etc.
|
||||
|
||||
If not, then put bindings in the formula they bind to. This is more
|
||||
useful to people. Just install the stuff! Having to faff around with
|
||||
foo-ruby, foo-perl etc. is a bad user experience.
|
||||
|
||||
### Niche (or self-submitted) stuff
|
||||
The software in question must:
|
||||
|
||||
|
||||
@ -11,8 +11,8 @@ Starting with OS X Lion (10.7), you need `sudo` to install to these like
|
||||
so: `sudo gem install`, `sudo easy_install` or `sudo cpan -i`.
|
||||
|
||||
An option to avoid sudo is to use an access control list:
|
||||
`chmod +a 'user:YOUR_NAME_HERE allow add_subdirectory,add_file,delete_child,directory_inherit' /Library/Python/2.7/site-packages`,
|
||||
for example, will let you add packages to Python 2.7 as yourself. That
|
||||
`chmod +a 'user:YOUR_NAME_HERE allow add_subdirectory,add_file,delete_child,directory_inherit' /Library/Python/3.6/site-packages`,
|
||||
for example, will let you add packages to Python 3.6 as yourself. That
|
||||
is probably safer than changing the group ownership of the directory.
|
||||
|
||||
### So why was I using sudo?
|
||||
@ -29,14 +29,14 @@ Rather than changing the rights on `/Library/Python`, we recommend the
|
||||
following options:
|
||||
|
||||
### With a brewed Python
|
||||
Note, `easy_install` is deprecated. We install `pip` (or `pip3` for
|
||||
Python 3) along with python/python3.
|
||||
Note, `easy_install` is deprecated. We install `pip` (or `pip2` for
|
||||
Python 2) along with python/python2.
|
||||
|
||||
We set up distutils such that `pip install` will always put modules in
|
||||
`$(brew --prefix)/lib/pythonX.Y/site-packages` and scripts in
|
||||
`$(brew --prefix)/share/python`. Therefore, you won’t need sudo!
|
||||
|
||||
Do `brew info python` or `brew info python3` for precise information
|
||||
Do `brew info python` or `brew info python@2` for precise information
|
||||
about the paths. Note, a brewed Python still searches for modules in
|
||||
`/Library/Python/X.Y/site-packages` and also in
|
||||
`~/Library/Python/X.Y/lib/python/site-packages`.
|
||||
|
||||
@ -4,33 +4,35 @@ This page describes how Python is handled in Homebrew for users. See [Python for
|
||||
|
||||
Homebrew should work with any [CPython](https://stackoverflow.com/questions/2324208/is-there-any-difference-between-cpython-and-python) and defaults to the macOS system Python.
|
||||
|
||||
Homebrew provides formulae to brew a more up-to-date Python 2.7.x and 3.x.
|
||||
Homebrew provides formulae to brew 3.x and a more up-to-date Python 2.7.x.
|
||||
|
||||
**Important:** If you choose to install a Python which isn't either of these two (system Python or brewed Python), the Homebrew team can only provide limited support.
|
||||
**Important:** If you choose to install a Python which isn't either of these two (system Python or brewed Python), the Homebrew team cannot support any breakage that may occur.
|
||||
|
||||
## Python 2.x or Python 3.x
|
||||
Homebrew provides one formula for Python 2.7.x and another for Python 3.x. The executables are organized as follows so that Python 2 and Python 3 can both be installed without conflict:
|
||||
* `python` points to the macOS system Python (with no manual PATH modification)
|
||||
* `python2` points to Homebrew's Python 2.7.x (if installed)
|
||||
## Python 3.x or Python 2.x
|
||||
Homebrew provides one formula for Python 3.x (`python`) and another for Python 2.7.x (`python@2`).
|
||||
|
||||
The executables are organized as follows so that Python 2 and Python 3 can both be installed without conflict:
|
||||
* `python3` points to Homebrew's Python 3.x (if installed)
|
||||
* `pip2` points to Homebrew's Python 2.7.x's pip (if installed)
|
||||
* `python2` points to Homebrew's Python 2.7.x (if installed)
|
||||
* `python` points to Homebrew's Python 2.7.x (if installed) otherwise the macOS system Python. Check out `brew info python` if you wish to add Homebrew's 3.x `python` to your `PATH`.
|
||||
* `pip3` points to Homebrew's Python 3.x's pip (if installed)
|
||||
* `pip` and `pip2` point to Homebrew's Python 2.7.x's pip (if installed)
|
||||
|
||||
([Wondering which one to choose?](https://wiki.python.org/moin/Python2orPython3))
|
||||
|
||||
## Setuptools, Pip, etc.
|
||||
The Python formulae install [pip](http://www.pip-installer.org) (as `pip2` or `pip3`) and [Setuptools](https://pypi.python.org/pypi/setuptools).
|
||||
The Python formulae install [pip](http://www.pip-installer.org) (as `pip` or `pip2`) and [Setuptools](https://pypi.python.org/pypi/setuptools).
|
||||
|
||||
Setuptools can be updated via pip, without having to re-brew Python:
|
||||
|
||||
```sh
|
||||
python2 -m pip install --upgrade setuptools
|
||||
python -m pip install --upgrade setuptools
|
||||
```
|
||||
|
||||
Similarly, pip can be used to upgrade itself via:
|
||||
|
||||
```sh
|
||||
python2 -m pip install --upgrade pip
|
||||
python -m pip install --upgrade pip
|
||||
```
|
||||
|
||||
### Note on `pip install --user`
|
||||
@ -39,7 +41,7 @@ The normal `pip install --user` is disabled for brewed Python. This is because o
|
||||
A possible workaround (which puts executable scripts in `~/Library/Python/<X>.<Y>/bin`) is:
|
||||
|
||||
```sh
|
||||
python2 -m pip install --user --install-option="--prefix=" <package-name>
|
||||
python -m pip install --user --install-option="--prefix=" <package-name>
|
||||
```
|
||||
|
||||
## `site-packages` and the `PYTHONPATH`
|
||||
@ -49,12 +51,12 @@ The `site-packages` is a directory that contains Python modules (especially bind
|
||||
$(brew --prefix)/lib/pythonX.Y/site-packages
|
||||
```
|
||||
|
||||
So, for Python 2.7.x, you'll find it at `/usr/local/lib/python2.7/site-packages`.
|
||||
So, for Python 3.6.x, you'll find it at `/usr/local/lib/python3.6/site-packages`.
|
||||
|
||||
Python 2.7 also searches for modules in:
|
||||
Python 3.6 also searches for modules in:
|
||||
|
||||
- `/Library/Python/2.7/site-packages`
|
||||
- `~/Library/Python/2.7/lib/python/site-packages`
|
||||
- `/Library/Python/3.6/site-packages`
|
||||
- `~/Library/Python/3.6/lib/python/site-packages`
|
||||
|
||||
Homebrew's `site-packages` directory is first created if (1) any Homebrew formula with Python bindings are installed, or (2) upon `brew install python`.
|
||||
|
||||
@ -62,9 +64,7 @@ Homebrew's `site-packages` directory is first created if (1) any Homebrew formul
|
||||
The reasoning for this location is to preserve your modules between (minor) upgrades or re-installations of Python. Additionally, Homebrew has a strict policy never to write stuff outside of the `brew --prefix`, so we don't spam your system.
|
||||
|
||||
## Homebrew-provided Python bindings
|
||||
Some formulae provide Python bindings. Sometimes a `--with-python` or `--with-python3` option has to be passed to `brew install` in order to build the Python bindings. (Check with `brew options <formula>`.)
|
||||
|
||||
Homebrew builds bindings against the first `python` (and `python-config`) in your `PATH`. (Check with `which python`).
|
||||
Some formulae provide Python bindings. Sometimes a `--with-python` or `--with-python@2` option has to be passed to `brew install` in order to build the Python bindings. (Check with `brew options <formula>`.)
|
||||
|
||||
**Warning!** Python may crash (see [Common Issues](Common-Issues.md)) if you `import <module>` from a brewed Python if you ran `brew install <formula_with_python_bindings>` against the system Python. If you decide to switch to the brewed Python, then reinstall all formulae with Python bindings (e.g. `pyside`, `wxwidgets`, `pygtk`, `pygobject`, `opencv`, `vtk` and `boost-python`).
|
||||
|
||||
@ -89,4 +89,4 @@ Homebrew will still install Python modules into Homebrew's `site-packages` and *
|
||||
Virtualenv has a `--system-site-packages` switch to allow "global" (i.e. Homebrew's) `site-packages` to be accessible from within the virtualenv.
|
||||
|
||||
## Why is Homebrew's Python being installed as a dependency?
|
||||
Formulae that declare an unconditional dependency on the `"python"` or `"python3"` formulae are bottled against Homebrew's Python 2.7.x or 3.x and require it to be installed.
|
||||
Formulae that declare an unconditional dependency on the `"python"` or `"python@2"` formulae are bottled against Homebrew's Python 3.x or 2.7.x and require it to be installed.
|
||||
|
||||
@ -96,7 +96,8 @@ With `--verbose` or `-v`, many commands print extra debugging information. Note
|
||||
|
||||
By default, `deps` shows required and recommended dependencies for
|
||||
`formulae`. To include the `:build` type dependencies, pass `--include-build`.
|
||||
Similarly, pass `--include-optional` to include `:optional` dependencies.
|
||||
Similarly, pass `--include-optional` to include `:optional` dependencies or
|
||||
`--include-test` to include `:test` dependencies.
|
||||
To skip `:recommended` type dependencies, pass `--skip-recommended`.
|
||||
To include requirements in addition to dependencies, pass `--include-requirements`.
|
||||
|
||||
@ -109,8 +110,8 @@ With `--verbose` or `-v`, many commands print extra debugging information. Note
|
||||
If `--installed` is passed, output a tree for every installed formula.
|
||||
|
||||
The `filters` placeholder is any combination of options `--include-build`,
|
||||
`--include-optional`, `--skip-recommended`, and `--include-requirements` as
|
||||
documented above.
|
||||
`--include-optional`, `--include-test`, `--skip-recommended`, and
|
||||
`--include-requirements` as documented above.
|
||||
|
||||
If `--annotate` is passed, the build, optional, and recommended dependencies
|
||||
are marked as such in the output.
|
||||
@ -121,7 +122,8 @@ With `--verbose` or `-v`, many commands print extra debugging information. Note
|
||||
dependencies of that formula.
|
||||
|
||||
The `filters` placeholder is any combination of options `--include-build`,
|
||||
`--include-optional`, and `--skip-recommended` as documented above.
|
||||
`--include-optional`, `--include-test`, and `--skip-recommended` as
|
||||
documented above.
|
||||
|
||||
* `desc` `formula`:
|
||||
Display `formula`'s name and one-line description.
|
||||
@ -559,8 +561,8 @@ With `--verbose` or `-v`, many commands print extra debugging information. Note
|
||||
repository's HEAD will be checked for updates when a new stable or devel
|
||||
version has been released.
|
||||
|
||||
If `formulae` are given, upgrade only the specified brews (but do so even
|
||||
if they are pinned; see `pin`, `unpin`).
|
||||
If `formulae` are given, upgrade only the specified brews (unless they
|
||||
are pinned; see `pin`, `unpin`).
|
||||
|
||||
* `uses` [`--installed`] [`--recursive`] [`--include-build`] [`--include-optional`] [`--skip-recommended`] [`--devel`|`--HEAD`] `formulae`:
|
||||
Show the formulae that specify `formulae` as a dependency. When given
|
||||
|
||||
@ -16,16 +16,16 @@ Applications should unconditionally bundle all of their Python-language dependen
|
||||
|
||||
### Python declarations
|
||||
|
||||
Formulae for apps that require Python 3 **should** declare an unconditional dependency on `"python"`. These apps **must** work with the current Homebrew Python 3.x formula.
|
||||
|
||||
Applications that are compatible with Python 2 **should** use the Apple-provided system Python in `/usr/bin` on systems that provide Python 2.7. To do this, declare:
|
||||
|
||||
```ruby
|
||||
depends_on "python" if MacOS.version <= :snow_leopard
|
||||
depends_on "python@2" if MacOS.version <= :snow_leopard
|
||||
```
|
||||
|
||||
No explicit Python dependency is needed on recent OS versions since `/usr/bin` is always in `PATH` for Homebrew formulae; on Leopard and older, the `python` in `PATH` is used if it's at least version 2.7, or else Homebrew's Python 2.7.x is installed.
|
||||
|
||||
Formulae for apps that require Python 3 **should** declare an unconditional dependency on `"python3"`. These apps **must** work with the current Homebrew Python 3.x formula.
|
||||
|
||||
### Installing
|
||||
|
||||
Applications should be installed into a Python [virtualenv](https://virtualenv.pypa.io/en/stable/) environment rooted in `libexec`. This prevents the app's Python modules from contaminating the system site-packages and vice versa.
|
||||
@ -66,7 +66,7 @@ This is exactly the same as writing:
|
||||
```ruby
|
||||
def install
|
||||
# Create a virtualenv in `libexec`. If your app needs Python 3, make sure that
|
||||
# `depends_on "python3"` is declared, and use `virtualenv_create(libexec, "python3")`.
|
||||
# `depends_on "python"` is declared, and use `virtualenv_create(libexec, "python")`.
|
||||
venv = virtualenv_create(libexec)
|
||||
# Install all of the resources declared on the formula into the virtualenv.
|
||||
venv.pip_install resources
|
||||
@ -121,9 +121,9 @@ in case you need to do different things for different resources.
|
||||
|
||||
## Bindings
|
||||
|
||||
Build bindings with the system Python by default (don't add an option) and they should be usable with any binary-compatible Python. If that isn't the case, it's an upstream bug; [here's some advice for resolving it](http://blog.tim-smith.us/2015/09/python-extension-modules-os-x/).
|
||||
To add bindings for Python 3, please add `depends_on "python"`.
|
||||
|
||||
To add bindings for Python 3, please add `depends_on "python3" => :optional` and make the bindings conditional on `build.with?("python3")`.
|
||||
Build Python 2 bindings with the system Python by default (don't add an option) and they should be usable with any binary-compatible Python. If that isn't the case, it's an upstream bug; [here's some advice for resolving it](http://blog.tim-smith.us/2015/09/python-extension-modules-os-x/).
|
||||
|
||||
### Dependencies
|
||||
|
||||
@ -153,7 +153,9 @@ Sometimes we have to `inreplace` a `Makefile` to use our prefix for the Python b
|
||||
|
||||
### Python declarations
|
||||
|
||||
Python 2 libraries do not need a `depends_on "python"` declaration; they will be built with the system Python, but should still be usable with any other Python 2.7. If this is not the case, it is an upstream bug; [here is some advice for resolving it](http://blog.tim-smith.us/2015/09/python-extension-modules-os-x/). Libraries built for Python 3 should include `depends_on "python3"`, which will bottle against Homebrew's Python 3.x. If a library supports both Python 2.x and Python 3.x, the `"python3"` dependency should be `:optional`. Python 2.x libraries must function when they are installed against either the system Python or brewed Python.
|
||||
Libraries built for Python 3 should include `depends_on "python"`, which will bottle against Homebrew's Python 3.x. Python 2.x libraries must function when they are installed against either the system Python or brewed Python.
|
||||
|
||||
Python 2 libraries do not need a `depends_on "python@2"` declaration; they will be built with the system Python, but should still be usable with any other Python 2.7. If this is not the case, it is an upstream bug; [here is some advice for resolving it](http://blog.tim-smith.us/2015/09/python-extension-modules-os-x/).
|
||||
|
||||
### Installing
|
||||
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
.\" generated with Ronn/v0.7.3
|
||||
.\" http://github.com/rtomayko/ronn/tree/0.7.3
|
||||
.
|
||||
.TH "BREW\-CASK" "1" "February 2018" "Homebrew" "brew-cask"
|
||||
.TH "BREW\-CASK" "1" "March 2018" "Homebrew" "brew-cask"
|
||||
.
|
||||
.SH "NAME"
|
||||
\fBbrew\-cask\fR \- a friendly binary installer for macOS
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
.\" generated with Ronn/v0.7.3
|
||||
.\" http://github.com/rtomayko/ronn/tree/0.7.3
|
||||
.
|
||||
.TH "BREW" "1" "February 2018" "Homebrew" "brew"
|
||||
.TH "BREW" "1" "March 2018" "Homebrew" "brew"
|
||||
.
|
||||
.SH "NAME"
|
||||
\fBbrew\fR \- The missing package manager for macOS
|
||||
@ -107,7 +107,7 @@ If \fB\-\-full\-name\fR is passed, list dependencies by their full name\.
|
||||
If \fB\-\-installed\fR is passed, only list those dependencies that are currently installed\.
|
||||
.
|
||||
.IP
|
||||
By default, \fBdeps\fR shows required and recommended dependencies for \fIformulae\fR\. To include the \fB:build\fR type dependencies, pass \fB\-\-include\-build\fR\. Similarly, pass \fB\-\-include\-optional\fR to include \fB:optional\fR dependencies\. To skip \fB:recommended\fR type dependencies, pass \fB\-\-skip\-recommended\fR\. To include requirements in addition to dependencies, pass \fB\-\-include\-requirements\fR\.
|
||||
By default, \fBdeps\fR shows required and recommended dependencies for \fIformulae\fR\. To include the \fB:build\fR type dependencies, pass \fB\-\-include\-build\fR\. Similarly, pass \fB\-\-include\-optional\fR to include \fB:optional\fR dependencies or \fB\-\-include\-test\fR to include \fB:test\fR dependencies\. To skip \fB:recommended\fR type dependencies, pass \fB\-\-skip\-recommended\fR\. To include requirements in addition to dependencies, pass \fB\-\-include\-requirements\fR\.
|
||||
.
|
||||
.TP
|
||||
\fBdeps\fR \fB\-\-tree\fR [\fB\-\-1\fR] [\fIfilters\fR] [\fB\-\-annotate\fR] (\fIformulae\fR|\fB\-\-installed\fR)
|
||||
@ -120,7 +120,7 @@ If \fB\-\-1\fR is passed, only one level of children is displayed\.
|
||||
If \fB\-\-installed\fR is passed, output a tree for every installed formula\.
|
||||
.
|
||||
.IP
|
||||
The \fIfilters\fR placeholder is any combination of options \fB\-\-include\-build\fR, \fB\-\-include\-optional\fR, \fB\-\-skip\-recommended\fR, and \fB\-\-include\-requirements\fR as documented above\.
|
||||
The \fIfilters\fR placeholder is any combination of options \fB\-\-include\-build\fR, \fB\-\-include\-optional\fR, \fB\-\-include\-test\fR, \fB\-\-skip\-recommended\fR, and \fB\-\-include\-requirements\fR as documented above\.
|
||||
.
|
||||
.IP
|
||||
If \fB\-\-annotate\fR is passed, the build, optional, and recommended dependencies are marked as such in the output\.
|
||||
@ -130,7 +130,7 @@ If \fB\-\-annotate\fR is passed, the build, optional, and recommended dependenci
|
||||
Show dependencies for installed or all available formulae\. Every line of output starts with the formula name, followed by a colon and all direct dependencies of that formula\.
|
||||
.
|
||||
.IP
|
||||
The \fIfilters\fR placeholder is any combination of options \fB\-\-include\-build\fR, \fB\-\-include\-optional\fR, and \fB\-\-skip\-recommended\fR as documented above\.
|
||||
The \fIfilters\fR placeholder is any combination of options \fB\-\-include\-build\fR, \fB\-\-include\-optional\fR, \fB\-\-include\-test\fR, and \fB\-\-skip\-recommended\fR as documented above\.
|
||||
.
|
||||
.TP
|
||||
\fBdesc\fR \fIformula\fR
|
||||
@ -576,7 +576,7 @@ If \fB\-\-cleanup\fR is specified then remove previously installed \fIformula\fR
|
||||
If \fB\-\-fetch\-HEAD\fR is passed, fetch the upstream repository to detect if the HEAD installation of the formula is outdated\. Otherwise, the repository\'s HEAD will be checked for updates when a new stable or devel version has been released\.
|
||||
.
|
||||
.IP
|
||||
If \fIformulae\fR are given, upgrade only the specified brews (but do so even if they are pinned; see \fBpin\fR, \fBunpin\fR)\.
|
||||
If \fIformulae\fR are given, upgrade only the specified brews (unless they are pinned; see \fBpin\fR, \fBunpin\fR)\.
|
||||
.
|
||||
.TP
|
||||
\fBuses\fR [\fB\-\-installed\fR] [\fB\-\-recursive\fR] [\fB\-\-include\-build\fR] [\fB\-\-include\-optional\fR] [\fB\-\-skip\-recommended\fR] [\fB\-\-devel\fR|\fB\-\-HEAD\fR] \fIformulae\fR
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user