Merge branch 'master' into exclude-executable-metafiles

Added tests in keg_test and pathname_test was
moved into keg_spec and pathname_spec.
This commit is contained in:
Naoto Kaneko 2017-02-27 14:23:53 +09:00
commit 928eaca267
214 changed files with 6751 additions and 5475 deletions

View File

@ -7,7 +7,7 @@
#: If `--dry-run` or `-n` is passed, show what would be removed, but do not
#: actually remove anything.
#:
#: If `-s` is passed, scrubs the cache, removing downloads for even the latest
#: If `-s` is passed, scrub the cache, removing downloads for even the latest
#: versions of formulae. Note downloads for any installed formulae will still not be
#: deleted. If you want to delete those too: `rm -rf $(brew --cache)`

View File

@ -1,11 +1,10 @@
#: * `desc` <formula>:
#: Display <formula>'s name and one-line description.
#:
#: * `desc` [`-s`|`-n`|`-d`] <pattern>:
#: * `desc` [`-s`|`-n`|`-d`] (<text>|`/`<text>`/`):
#: Search both name and description (`-s`), just the names (`-n`), or just the
#: descriptions (`-d`) for `<pattern>`. `<pattern>` is by default interpreted
#: as a literal string; if flanked by slashes, it is instead interpreted as a
#: regular expression. Formula descriptions are cached; the cache is created on
#: descriptions (`-d`) for <text>. If <text> is flanked by slashes, it is interpreted
#: as a regular expression. Formula descriptions are cached; the cache is created on
#: the first search, making that search slower than subsequent ones.
require "descriptions"

View File

@ -4,7 +4,7 @@
#: * `info` `--github` <formula>:
#: Open a browser to the GitHub History page for formula <formula>.
#:
#: To view formula history locally: `brew log -p <formula>`.
#: To view formula history locally: `brew log -p <formula>`
#:
#: * `info` `--json=`<version> (`--all`|`--installed`|<formulae>):
#: Print a JSON representation of <formulae>. Currently the only accepted value
@ -13,7 +13,7 @@
#: Pass `--all` to get information on all formulae, or `--installed` to get
#: information on all installed formulae.
#:
#: See the docs for examples of using the JSON:
#: See the docs for examples of using the JSON output:
#: <http://docs.brew.sh/Querying-Brew.html>
require "blacklist"

View File

@ -12,6 +12,7 @@ class Symbol
Formulary.factory(to_s, *args)
end
end
class String
def f(*args)
Formulary.factory(self, *args)

View File

@ -1,4 +1,4 @@
#: * `outdated` [`--quiet`|`--verbose`|`--json=v1`] [`--fetch-HEAD`]:
#: * `outdated` [`--quiet`|`--verbose`|`--json=`<version>] [`--fetch-HEAD`]:
#: Show formulae that have an updated version available.
#:
#: By default, version information is displayed in interactive shells, and

View File

@ -4,7 +4,7 @@
#:
#: This can be useful for debugging issues across all formulae
#: when making significant changes to `formula.rb`,
#: or to determine if any current formulae have Ruby issues
#: or to determine if any current formulae have Ruby issues.
require "readall"

View File

@ -2,7 +2,7 @@
#: Display all locally available formulae for brewing (including tapped ones).
#: No online search is performed if called without arguments.
#:
#: * `search` [`--desc`] <text>|`/`<text>`/`:
#: * `search` [`--desc`] (<text>|`/`<text>`/`):
#: Perform a substring search of formula names for <text>. If <text> is
#: surrounded with slashes, then it is interpreted as a regular expression.
#: The search for <text> is extended online to some popular taps.

View File

@ -12,7 +12,7 @@
#:
#: Pass `--installed` to get information on installed taps.
#:
#: See the docs for examples of using the JSON:
#: See the docs for examples of using the JSON output:
#: <http://docs.brew.sh/Querying-Brew.html>
require "tap"

View File

@ -1,7 +1,7 @@
#: * `unlink` [`--dry-run`] <formula>:
#: Remove symlinks for <formula> from the Homebrew prefix. This can be useful
#: for temporarily disabling a formula:
#: `brew unlink foo && commands && brew link foo`.
#: `brew unlink <formula> && <commands> && brew link <formula>`
#:
#: If `--dry-run` or `-n` is passed, Homebrew will list all files which would
#: be unlinked, but will not actually unlink or delete any files.

View File

@ -1,7 +1,7 @@
#: * `unpack` [`--git`|`--patch`] [`--destdir=`<path>] <formulae>:
#: Unpack the source files for <formulae> into subdirectories of the current
#: working directory. If `--destdir=`<path> is given, the subdirectories will
#: be created in the directory named by `<path>` instead.
#: be created in the directory named by <path> instead.
#:
#: If `--patch` is passed, patches for <formulae> will be applied to the
#: unpacked source.

View File

@ -12,8 +12,8 @@
#: `--include-build`. Similarly, pass `--include-optional` to include `:optional`
#: dependencies. To skip `:recommended` type dependencies, pass `--skip-recommended`.
#:
#: By default, `uses` shows usages of `formula` by stable builds. To find
#: cases where `formula` is used by development or HEAD build, pass
#: By default, `uses` shows usages of <formulae> by stable builds. To find
#: cases where <formulae> is used by development or HEAD build, pass
#: `--devel` or `--HEAD`.
require "formula"

View File

@ -75,6 +75,17 @@ class CompilerFailure
create(gcc: "4.5"),
create(gcc: "4.6"),
],
cxx14: [
create(:clang) { build 600 },
create(:gcc_4_0),
create(:gcc_4_2),
create(gcc: "4.3"),
create(gcc: "4.4"),
create(gcc: "4.5"),
create(gcc: "4.6"),
create(gcc: "4.7"),
create(gcc: "4.8"),
],
openmp: [
create(:clang),
],

View File

@ -174,30 +174,64 @@ class FormulaAuditor
@specs = %w[stable devel head].map { |s| formula.send(s) }.compact
end
def url_status_code(url, range: false)
# The system Curl is too old and unreliable with HTTPS homepages on
# Yosemite and below.
return "200" unless DevelopmentTools.curl_handles_most_https_homepages?
def self.check_http_content(url, user_agents: [:default])
return unless url.start_with? "http"
extra_args = [
"--connect-timeout", "15",
"--output", "/dev/null",
"--write-out", "%{http_code}"
]
extra_args << "--range" << "0-0" if range
extra_args << url
status_code = nil
[:browser, :default].each do |user_agent|
args = curl_args(
extra_args: extra_args,
show_output: true,
user_agent: user_agent,
)
status_code = Open3.popen3(*args) { |_, stdout, _, _| stdout.read }
break if status_code.start_with? "20"
details = nil
user_agent = nil
user_agents.each do |ua|
details = http_content_headers_and_checksum(url, user_agent: ua)
user_agent = ua
break if details[:status].to_s.start_with?("2")
end
status_code
return "The URL #{url} is not reachable" unless details[:status]
unless details[:status].start_with? "2"
return "The URL #{url} is not reachable (HTTP status code #{details[:status]})"
end
return unless url.start_with? "http:"
secure_url = url.sub "http", "https"
secure_details =
http_content_headers_and_checksum(secure_url, user_agent: user_agent)
if !details[:status].to_s.start_with?("2") ||
!secure_details[:status].to_s.start_with?("2")
return
end
etag_match = details[:etag] &&
details[:etag] == secure_details[:etag]
content_length_match =
details[:content_length] &&
details[:content_length] == secure_details[:content_length]
file_match = details[:file_hash] == secure_details[:file_hash]
return if !etag_match && !content_length_match && !file_match
"The URL #{url} could use HTTPS rather than HTTP"
end
def self.http_content_headers_and_checksum(url, user_agent: :default)
args = curl_args(
extra_args: ["--connect-timeout", "15", "--include", url],
show_output: true,
user_agent: user_agent,
)
output = Open3.popen3(*args) { |_, stdout, _, _| stdout.read }
status_code = :unknown
while status_code == :unknown || status_code.to_s.start_with?("3")
headers, _, output = output.partition("\r\n\r\n")
status_code = headers[%r{HTTP\/.* (\d+)}, 1]
end
{
status: status_code,
etag: headers[%r{ETag: ([wW]\/)?"(([^"]|\\")*)"}, 2],
content_length: headers[/Content-Length: (\d+)/, 1],
file_hash: Digest::SHA256.digest(output),
}
end
def audit_style
@ -295,6 +329,27 @@ class FormulaAuditor
problem "File should end with a newline" unless text.trailing_newline?
versioned_formulae = Dir[formula.path.to_s.gsub(/\.rb$/, "@*.rb")]
needs_versioned_alias = !versioned_formulae.empty? &&
formula.tap &&
formula.aliases.grep(/.@\d/).empty?
if needs_versioned_alias
_, last_alias_version = File.basename(versioned_formulae.sort.reverse.first)
.gsub(/\.rb$/, "")
.split("@")
major, minor, = formula.version.to_s.split(".")
alias_name = if last_alias_version.split(".").length == 1
"#{formula.name}@#{major}"
else
"#{formula.name}@#{major}.#{minor}"
end
problem <<-EOS.undent
Formula has other versions so create an alias:
cd #{formula.tap.alias_dir}
ln -s #{formula.path.to_s.gsub(formula.tap.path, "..")} #{alias_name}
EOS
end
return unless @strict
present = audit_components
@ -410,7 +465,8 @@ class FormulaAuditor
problem "Dependency '#{dep.name}' was renamed; use new name '#{dep_f.name}'."
end
if @@aliases.include?(dep.name)
if @@aliases.include?(dep.name) &&
(core_formula? || !dep_f.versioned_formula?)
problem "Dependency '#{dep.name}' is an alias; use the canonical name '#{dep.to_formula.full_name}'."
end
@ -549,6 +605,11 @@ class FormulaAuditor
def audit_homepage
homepage = formula.homepage
if homepage.nil? || homepage.empty?
problem "Formula should have a homepage."
return
end
unless homepage =~ %r{^https?://}
problem "The homepage should start with http or https (URL is #{homepage})."
end
@ -619,9 +680,13 @@ class FormulaAuditor
return unless @online
status_code = url_status_code(homepage)
return if status_code.start_with? "20"
problem "The homepage #{homepage} is not reachable (HTTP status code #{status_code})"
# The system Curl is too old and unreliable with HTTPS homepages on
# Yosemite and below.
return unless DevelopmentTools.curl_handles_most_https_homepages?
if http_content_problem = FormulaAuditor.check_http_content(homepage,
user_agents: [:browser, :default])
problem http_content_problem
end
end
def audit_bottle_spec
@ -671,11 +736,11 @@ class FormulaAuditor
%w[Stable Devel HEAD].each do |name|
next unless spec = formula.send(name.downcase)
ra = ResourceAuditor.new(spec, online: @online).audit
ra = ResourceAuditor.new(spec, online: @online, strict: @strict).audit
problems.concat ra.problems.map { |problem| "#{name}: #{problem}" }
spec.resources.each_value do |resource|
ra = ResourceAuditor.new(resource, online: @online).audit
ra = ResourceAuditor.new(resource, online: @online, strict: @strict).audit
problems.concat ra.problems.map { |problem|
"#{name} resource #{resource.name.inspect}: #{problem}"
}
@ -702,6 +767,7 @@ class FormulaAuditor
unstable_whitelist = %w[
aalib 1.4rc5
angolmois 2.0.0alpha2
automysqlbackup 3.0-rc6
aview 1.3.0rc1
distcc 3.2rc1
@ -709,6 +775,8 @@ class FormulaAuditor
ftgl 2.1.3-rc5
hidapi 0.8.0-rc1
libcaca 0.99b19
nethack4 4.3.0-beta2
opensyobon 1.0rc2
premake 4.4-beta5
pwnat 0.3-beta
pxz 4.999.9
@ -861,7 +929,7 @@ class FormulaAuditor
end
end
if text =~ /xcodebuild[ (]["'*]/ && !text.include?("SYMROOT=")
if text =~ /xcodebuild[ (]*["'*]*/ && !text.include?("SYMROOT=")
problem 'xcodebuild should be passed an explicit "SYMROOT"'
end
@ -1231,6 +1299,7 @@ class ResourceAuditor
@using = resource.using
@specs = resource.specs
@online = options[:online]
@strict = options[:strict]
@problems = []
end
@ -1490,38 +1559,26 @@ class ResourceAuditor
return unless @online
urls.each do |url|
check_insecure_mirror(url) if url.start_with? "http:"
next if !@strict && mirrors.include?(url)
strategy = DownloadStrategyDetector.detect(url, using)
if strategy <= CurlDownloadStrategy && !url.start_with?("file")
if http_content_problem = FormulaAuditor.check_http_content(url)
problem http_content_problem
end
elsif strategy <= GitDownloadStrategy
unless Utils.git_remote_exists url
problem "The URL #{url} is not a valid git URL"
end
elsif strategy <= SubversionDownloadStrategy
unless Utils.svn_remote_exists url
problem "The URL #{url} is not a valid svn URL"
end
end
end
end
def check_insecure_mirror(url)
details = get_content_details(url)
secure_url = url.sub "http", "https"
secure_details = get_content_details(secure_url)
return if details[:status].nil? || secure_details[:status].nil? || !details[:status].start_with?("2") || !secure_details[:status].start_with?("2")
etag_match = details[:etag] && details[:etag] == secure_details[:etag]
content_length_match = details[:content_length] && details[:content_length] == secure_details[:content_length]
file_match = details[:file_hash] == secure_details[:file_hash]
return if !etag_match && !content_length_match && !file_match
problem "The URL #{url} could use HTTPS rather than HTTP"
end
def problem(text)
@problems << text
end
def get_content_details(url)
out = {}
output, = curl_output "--connect-timeout", "15", "--include", url
split = output.partition("\r\n\r\n")
headers = split.first
out[:status] = headers[%r{HTTP\/.* (\d+)}, 1]
out[:etag] = headers[%r{ETag: ([wW]\/)?"(([^"]|\\")*)"}, 2]
out[:content_length] = headers[/Content-Length: (\d+)/, 1]
out[:file_hash] = Digest::SHA256.digest split.last
out
end
end

View File

@ -1,5 +1,5 @@
#: @hide_from_man_page
#: * `boneyard-formula-pr` [`--dry-run`] [`--local`] [`--reason=<reason>`] <formula-name> :
#: * `boneyard-formula-pr` [`--dry-run`] [`--local`] [`--reason=<reason>`] <formula> :
#: Creates a pull request to boneyard a formula.
#:
#: If `--dry-run` is passed, print what would be done rather than doing it.

View File

@ -1,6 +1,5 @@
#: * `bottle` [`--verbose`] [`--no-rebuild`] [`--keep-old`] [`--skip-relocation`] [`--root-url=<root_url>`] [`--force-core-tap`]:
#: * `bottle` [`--verbose`] [`--no-rebuild`] [`--keep-old`] [`--skip-relocation`] [`--root-url=`<URL>] [`--force-core-tap`]:
#: * `bottle` `--merge` [`--no-commit`] [`--keep-old`] [`--write`]:
#:
#: Generate a bottle (binary package) from a formula installed with
#: `--build-bottle`.

View File

@ -1,8 +1,7 @@
#: * `bump-formula-pr` [`--devel`] [`--dry-run`] [`--audit`|`--strict`] [`--message=`<message>] `--url=`<url> `--sha256=`<sha-256> <formula>:
#: * `bump-formula-pr` [`--devel`] [`--dry-run`] [`--audit`|`--strict`] [`--message=`<message>] `--tag=`<tag> `--revision=`<revision> <formula>:
#: Creates a pull request to update the formula with a new url or a new tag.
#: * `bump-formula-pr` [`--devel`] [`--dry-run` [`--write`]] [`--audit`|`--strict`] [`--mirror=`<URL>] [`--version=`<version>] [`--message=`<message>] (`--url=`<URL> `--sha256=`<sha-256>|`--tag=`<tag> `--revision=`<revision>) <formula>:
#: Creates a pull request to update the formula with a new URL or a new tag.
#:
#: If a <url> is specified, the <sha-256> checksum of the new download must
#: If a <URL> is specified, the <sha-256> checksum of the new download must
#: also be specified. A best effort to determine the <sha-256> and <formula>
#: name will be made if either or both values are not supplied by the user.
#:
@ -21,17 +20,17 @@
#:
#: If `--strict` is passed, run `brew audit --strict` before opening the PR.
#:
#: If `--mirror=`<url> is passed, use the value as a mirror url.
#: If `--mirror=`<URL> is passed, use the value as a mirror URL.
#:
#: If `--version=`<version> is passed, use the value to override the value
#: parsed from the url or tag. Note that `--version=0` can be used to delete
#: parsed from the URL or tag. Note that `--version=0` can be used to delete
#: an existing `version` override from a formula if it has become redundant.
#:
#: If `--message=`<message> is passed, append <message> to the default PR
#: message.
#:
#: Note that this command cannot be used to transition a formula from a
#: url-and-sha256 style specification into a tag-and-revision style
#: URL-and-sha256 style specification into a tag-and-revision style
#: specification, nor vice versa. It must use whichever style specification
#: the preexisting formula already uses.

View File

@ -3,8 +3,7 @@
#: Homebrew will attempt to automatically derive the formula name
#: and version, but if it fails, you'll have to make your own template. The `wget`
#: formula serves as a simple example. For the complete API have a look at
#:
#: <http://www.rubydoc.info/github/Homebrew/brew/master/Formula>
#: <http://www.rubydoc.info/github/Homebrew/brew/master/Formula>.
#:
#: If `--autotools` is passed, create a basic template for an Autotools-style build.
#: If `--cmake` is passed, create a basic template for a CMake-style build.

View File

@ -1,5 +1,5 @@
#: * `formula` <formula>:
#: Display the path where <formula> is
#: Display the path where <formula> is located.
require "formula"

View File

@ -1,4 +1,4 @@
#: * `linkage` [`--test`] [`--reverse`] <formula-name>:
#: * `linkage` [`--test`] [`--reverse`] <formula>:
#: Checks the library links of an installed formula.
#:
#: Only works on installed formulae. An error is raised if it is run on

View File

@ -1,5 +1,5 @@
#: @hide_from_man_page
#: * `mirror` [`--test`] <formula-name> [<formula-name> ...]:
#: * `mirror` [`--test`] <formulae>:
#: Reuploads the stable URL for a formula to Bintray to use it as a mirror.
module Homebrew

View File

@ -1,33 +1,42 @@
#: `pull` [`--bottle`] [`--bump`] [`--clean`] [`--ignore-whitespace`] [`--resolve`] [`--branch-okay`] [`--no-pbcopy`] [`--no-publish`] <patch-source> [<patch-source>]
#:
#: * `pull` [`--bottle`] [`--bump`] [`--clean`] [`--ignore-whitespace`] [`--resolve`] [`--branch-okay`] [`--no-pbcopy`] [`--no-publish`] <patch-source> [<patch-source>]:
#: Gets a patch from a GitHub commit or pull request and applies it to Homebrew.
#: Optionally, installs the formulae changed by the patch.
#:
#: Each <patch-source> may be one of:
#: * The ID number of a PR (Pull Request) in the homebrew/core GitHub
#:
#: ~ The ID number of a PR (pull request) in the homebrew/core GitHub
#: repository
#: * The URL of a PR on GitHub, using either the web page or API URL
#:
#: ~ The URL of a PR on GitHub, using either the web page or API URL
#: formats. In this form, the PR may be on Homebrew/brew,
#: Homebrew/homebrew-core or any tap.
#: * The URL of a commit on GitHub
#: * A "http://bot.brew.sh/job/..." string specifying a testing job ID
#:
#: If `--bottle` was passed, handle bottles, pulling the bottle-update
#: commit and publishing files on Bintray.
#: If `--bump` was passed, for one-formula PRs, automatically reword
#: commit message to our preferred format.
#: If `--clean` was passed, do not rewrite or otherwise modify the
#: commits found in the pulled PR.
#: If `--ignore-whitespace` was passed, silently ignore whitespace
#: discrepancies when applying diffs.
#: If `--resolve` was passed, when a patch fails to apply, leave in
#: progress and allow user to
#: resolve, instead of aborting.
#: If `--branch-okay` was passed, do not warn if pulling to a branch
#: besides master (useful for testing).
#: If `--no-pbcopy` was passed, do not copy anything to the system
# clipboard.
#: If `--no-publish` was passed, do not publish bottles to Bintray.
#: ~ The URL of a commit on GitHub
#:
#: ~ A "http://bot.brew.sh/job/..." string specifying a testing job ID
#:
#: If `--bottle` is passed, handle bottles, pulling the bottle-update
#: commit and publishing files on Bintray.
#:
#: If `--bump` is passed, for one-formula PRs, automatically reword
#: commit message to our preferred format.
#:
#: If `--clean` is passed, do not rewrite or otherwise modify the
#: commits found in the pulled PR.
#:
#: If `--ignore-whitespace` is passed, silently ignore whitespace
#: discrepancies when applying diffs.
#:
#: If `--resolve` is passed, when a patch fails to apply, leave in
#: progress and allow user to resolve, instead of aborting.
#:
#: If `--branch-okay` is passed, do not warn if pulling to a branch
#: besides master (useful for testing).
#:
#: If `--no-pbcopy` is passed, do not copy anything to the system
#: clipboard.
#:
#: If `--no-publish` is passed, do not publish bottles to Bintray.
require "net/http"
require "net/https"

View File

@ -1,7 +1,7 @@
#: * `release-notes` [<previous_tag>] [<end_ref>]:
#: * `release-notes` [`--markdown`] [<previous_tag>] [<end_ref>]:
#: Output the merged pull requests on Homebrew/brew between two Git refs.
#: If no `previous_tag` is provided it defaults to the newest tag.
#: If no `end_ref` is provided it defaults to `origin/master`.
#: If no <previous_tag> is provided it defaults to the newest tag.
#: If no <end_ref> is provided it defaults to `origin/master`.
#:
#: If `--markdown` is passed, output as a Markdown list.

View File

@ -1,4 +1,4 @@
#: * `tests` [`-v`] [`--coverage`] [`--generic`] [`--no-compat`] [`--only=`<test_script:test_method>] [`--seed` <seed>] [`--trace`] [`--online`] [`--official-cmd-taps`]:
#: * `tests` [`-v`] [`--coverage`] [`--generic`] [`--no-compat`] [`--only=`<test_script>`:`<test_method>] [`--seed` <seed>] [`--trace`] [`--online`] [`--official-cmd-taps`]:
#: Run Homebrew's unit and integration tests.
require "fileutils"
@ -82,6 +82,8 @@ module Homebrew
"--format", "ParallelTests::RSpec::RuntimeLogger",
"--out", "tmp/parallel_runtime_rspec.log"
]
spec_args << "--tag" << "~needs_macos" unless OS.mac?
run_tests "parallel_rspec", spec_files, spec_args
if (fs_leak_log = HOMEBREW_LIBRARY_PATH/"tmp/fs_leak.log").file?

View File

@ -1,14 +1,14 @@
#: * `update-test` [`--commit=<commit>`] [`--before=<date>`] [`--keep-tmp`]:
#: * `update-test` [`--commit=`<commit>] [`--before=`<date>] [`--keep-tmp`]:
#: Runs a test of `brew update` with a new repository clone.
#:
#: If no arguments are passed, use `origin/master` as the start commit.
#:
#: If `--commit=<commit>` is passed, use `<commit>` as the start commit.
#: If `--commit=`<commit> is passed, use <commit> as the start commit.
#:
#: If `--before=<date>` is passed, use the commit at `<date>` as the
#: If `--before=`<date> is passed, use the commit at <date> as the
#: start commit.
#:
#: If `--to-tag` is passed, set HOMEBREW_UPDATE_TO_TAG to test updating
#: If `--to-tag` is passed, set `HOMEBREW_UPDATE_TO_TAG` to test updating
#: between tags.
#:
#: If `--keep-tmp` is passed, retain the temporary directory containing

View File

@ -335,7 +335,7 @@ class Pathname
alias to_str to_s unless method_defined?(:to_str)
def cd
Dir.chdir(self) { yield }
Dir.chdir(self) { yield self }
end
def subdirs

View File

@ -1026,7 +1026,9 @@ class Formula
@prefix_returns_versioned_prefix = false
end
# Tell the user about any caveats regarding this package.
# Tell the user about any Homebrew-specific caveats or locations regarding
# this package. These should not contain setup instructions that would apply
# to installation through a different package manager on a different OS.
# @return [String]
# <pre>def caveats
# <<-EOS.undent

View File

@ -151,6 +151,28 @@ class FormulaInstaller
recursive_deps = formula.recursive_dependencies
recursive_formulae = recursive_deps.map(&:to_formula)
recursive_dependencies = []
recursive_formulae.each do |dep|
dep_recursive_dependencies = dep.recursive_dependencies.map(&:to_s)
if dep_recursive_dependencies.include?(formula.name)
recursive_dependencies << "#{formula.full_name} depends on #{dep.full_name}"
recursive_dependencies << "#{dep.full_name} depends on #{formula.full_name}"
end
end
unless recursive_dependencies.empty?
raise CannotInstallFormulaError, <<-EOS.undent
#{formula.full_name} contains a recursive dependency on itself:
#{recursive_dependencies.join("\n ")}
EOS
end
if recursive_formulae.flat_map(&:recursive_dependencies).map(&:to_s).include?(formula.name)
raise CannotInstallFormulaError, <<-EOS.undent
#{formula.full_name} contains a recursive dependency on itself!
EOS
end
if ENV["HOMEBREW_CHECK_RECURSIVE_VERSION_DEPENDENCIES"]
version_hash = {}
version_conflicts = Set.new

View File

@ -86,19 +86,19 @@ names, and other aspects of this manual are still subject to change.
If <token> is given, summarize the staged files associated with the
given Cask.
* `reinstall` <token> [ <token> ...]
* `reinstall` <token> [ <token> ... ]:
Reinstall the given Cask.
* `search` or `-S` [<text> | /<regexp>/]:
Without argument, display all Casks available for install, otherwise
Without an argument, display all Casks available for install; otherwise
perform a substring search of known Cask tokens for <text> or, if the
text is delimited by slashes (/<regexp>/), it is interpreted as a
Ruby regular expression.
* `style` [--fix] [ <token> ... ]:
Check the given Casks for correct style using [RuboCop Cask](https://github.com/caskroom/rubocop-cask).
If no tokens are given on the command line, all Casks are checked.
With `--fix`, auto-correct any style errors if possible.
Check the given Casks for correct style using [RuboCop Cask](https://github.com/caskroom/rubocop-cask).
If no tokens are given on the command line, all Casks are checked.
With `--fix`, auto-correct any style errors if possible.
* `uninstall` or `rm` or `remove` [--force] <token> [ <token> ... ]:
Uninstall the given Cask. With `--force`, uninstall even if the Cask
@ -111,7 +111,7 @@ names, and other aspects of this manual are still subject to change.
the Cask does not appear to be currently installed.
Removes all staged versions of the Cask distribution found under
`<Caskroom_path>/<token>`.
`<Caskroom_path>/`<token>.
If the Cask definition contains a `zap` stanza, performs additional
`zap` actions as defined there, such as removing local preference
@ -123,18 +123,18 @@ names, and other aspects of this manual are still subject to change.
## INTERNAL COMMANDS
* `_appcast_checkpoint` [--calculate] [ <token> ... | <URL> ... ]:
Given a `token`, returns the current appcast checkpoint, or calculates
the appcast checkpoint if the `--calculate` flag is specified.
Given a `URL`, calculates the appcast checkpoint for it.
Given a <token>, returns the current appcast checkpoint, or calculates
the appcast checkpoint if the `--calculate` flag is specified.
* `_stanza` <stanza_name> [ --table | --yaml | --inspect | --quiet ] [ <cask_token> ... ]:
Given a `stanza_name` and a `cask_token`, returns the current stanza
for a given Cask. If no `cask_token` is given, then data for all
Casks is returned.
Given a <URL>, calculates the appcast checkpoint for it.
* `_stanza` <stanza_name> [ --table | --yaml | --inspect | --quiet ] [ <token> ... ]:
Given a <stanza_name> and a <token>, returns the current stanza for a
given Cask. If no <token> is given, then data for all Casks is returned.
## OPTIONS
To make these options persistent, see the ENVIRONMENT section, below.
To make these options persistent, see the [ENVIRONMENT][] section, below.
Some of these (such as `--prefpanedir`) may be subject to removal
in a future version.
@ -150,7 +150,7 @@ in a future version.
Abort Cask installation if the Cask does not have a checksum defined.
* `--caskroom=<path>`:
Location of the Caskroom, where all binaries are stored. The default value is: `$(brew --prefix)/Caskroom`.
Set location of the Caskroom, where all binaries are stored. The default value is `$(brew --prefix)/Caskroom`.
* `--verbose`:
Give additional feedback during installation.
@ -218,17 +218,17 @@ the Homebrew command:
Most Homebrew-Cask commands can accept a Cask token as an argument. As
described above, the argument can take the form of:
* A token as returned by `brew cask search`, _eg_ `google-chrome`
* A token as returned by `brew cask search`, e.g. `google-chrome`
Homebrew-Cask also accepts three other forms in place of plain tokens:
* A fully-qualified token which includes the Tap name, _eg_
* A fully-qualified token which includes the Tap name, e.g.
`caskroom/fonts/font-symbola`
* A fully-qualified pathname to a Cask file, _eg_
* A fully-qualified pathname to a Cask file, e.g.
`/usr/local/Library/Taps/caskroom/homebrew-cask/Casks/google-chrome.rb`
* A `curl`-retrievable URI to a Cask file, _eg_
* A `curl`-retrievable URI to a Cask file, e.g.
`https://raw.githubusercontent.com/caskroom/homebrew-cask/f25b6babcd398abf48e33af3d887b2d00de1d661/Casks/google-chrome.rb`
## ENVIRONMENT
@ -239,17 +239,18 @@ information.
Environment variables specific to Homebrew-Cask:
* HOMEBREW\_CASK\_OPTS:
* `HOMEBREW_CASK_OPTS`:
This variable may contain any arguments normally used as options on
the command-line. This is particularly useful to make options persistent.
For example, you might add to your .bash_profile or .zshenv something like:
`export HOMEBREW_CASK_OPTS='--appdir=/Applications --caskroom=/etc/Caskroom'`.
export HOMEBREW_CASK_OPTS='--appdir=/Applications --caskroom=/etc/Caskroom'
## SEE ALSO
The Homebrew-Cask home page: <http://caskroom.io>.
The Homebrew-Cask home page: <http://caskroom.io>
The Homebrew-Cask GitHub page: <https://github.com/caskroom/homebrew-cask>.
The Homebrew-Cask GitHub page: <https://github.com/caskroom/homebrew-cask>
`brew`(1), `curl`(1)
@ -261,7 +262,7 @@ Man page format based on `brew.1.md` from Homebrew.
## BUGS
We still have bugs — and we are busy fixing them! If you have a problem, dont
We still have bugs - and we are busy fixing them! If you have a problem, don't
be shy about reporting it on our [GitHub issues page](https://github.com/caskroom/homebrew-cask/issues?state=open).
When reporting bugs, remember that Homebrew-Cask is an independent project from

View File

@ -40,7 +40,7 @@ With `--verbose` or `-v`, many commands print extra debugging information. Note
* `list`:
List all installed formulae.
* `search` <text>|`/`<text>`/`:
* `search` (<text>|`/`<text>`/`):
Perform a substring search of formula names for <text>. If <text> is
surrounded with slashes, then it is interpreted as a regular expression.
The search for <text> is extended online to some popular taps.
@ -214,7 +214,7 @@ can take several different forms:
to insecure HTTP.
While ensuring your downloads are fully secure, this is likely
to cause from-source Sourceforge, some GNU & GNOME based
to cause from-source SourceForge, some GNU & GNOME based
formulae to fail to download.
* `HOMEBREW_NO_GITHUB_API`:

View File

@ -8,16 +8,14 @@ class RubyRequirement < Requirement
super
end
satisfy build_env: false do
which_all("ruby").detect do |ruby|
version = /\d\.\d/.match Utils.popen_read(ruby, "--version")
next unless version
Version.create(version.to_s) >= Version.create(@version)
end
satisfy(build_env: false) { new_enough_ruby }
env do
ENV.prepend_path "PATH", new_enough_ruby
end
def message
s = "Ruby #{@version} is required to install this formula."
s = "Ruby >= #{@version} is required to install this formula."
s += super
s
end
@ -33,4 +31,28 @@ class RubyRequirement < Requirement
name
end
end
private
def new_enough_ruby
rubies.detect { |ruby| new_enough?(ruby) }
end
def rubies
rubies = which_all("ruby")
ruby_formula = Formula["ruby"]
if ruby_formula && ruby_formula.installed?
rubies.unshift ruby_formula.bin/"ruby"
end
rubies.uniq
end
def new_enough?(ruby)
version = Utils.popen_read(ruby, "-e", "print RUBY_VERSION").strip
version =~ /^\d+\.\d+/ && Version.create(version) >= min_version
end
def min_version
@min_version ||= Version.create(@version)
end
end

View File

@ -7,19 +7,35 @@ require "development_tools"
class SystemConfig
class << self
def gcc_4_2
@gcc_4_2 ||= DevelopmentTools.gcc_4_2_build_version if DevelopmentTools.installed?
@gcc_4_2 ||= if DevelopmentTools.installed?
DevelopmentTools.gcc_4_2_build_version
else
Version::NULL
end
end
def gcc_4_0
@gcc_4_0 ||= DevelopmentTools.gcc_4_0_build_version if DevelopmentTools.installed?
@gcc_4_0 ||= if DevelopmentTools.installed?
DevelopmentTools.gcc_4_0_build_version
else
Version::NULL
end
end
def clang
@clang ||= DevelopmentTools.clang_version if DevelopmentTools.installed?
@clang ||= if DevelopmentTools.installed?
DevelopmentTools.clang_version
else
Version::NULL
end
end
def clang_build
@clang_build ||= DevelopmentTools.clang_build_version if DevelopmentTools.installed?
@clang_build ||= if DevelopmentTools.installed?
DevelopmentTools.clang_build_version
else
Version::NULL
end
end
def head

View File

@ -1,7 +1,7 @@
require "extend/ARGV"
describe HomebrewArgvExtension do
subject { argv.extend(HomebrewArgvExtension) }
subject { argv.extend(described_class) }
let(:argv) { ["mxcl"] }
describe "#formulae" do

View File

@ -0,0 +1,189 @@
require "extend/ENV"
shared_examples EnvActivation do
subject { env.extend(described_class) }
let(:env) { {}.extend(EnvActivation) }
it "supports switching compilers" do
subject.clang
expect(subject["LD"]).to be nil
expect(subject["CC"]).to eq(subject["OBJC"])
end
describe "#with_build_environment" do
it "restores the environment" do
before = subject.dup
subject.with_build_environment do
subject["foo"] = "bar"
end
expect(subject["foo"]).to be nil
expect(subject).to eq(before)
end
it "ensures the environment is restored" do
before = subject.dup
expect {
subject.with_build_environment do
subject["foo"] = "bar"
raise StandardError
end
}.to raise_error(StandardError)
expect(subject["foo"]).to be nil
expect(subject).to eq(before)
end
it "returns the value of the block" do
expect(subject.with_build_environment { 1 }).to eq(1)
end
it "does not mutate the interface" do
expected = subject.methods
subject.with_build_environment do
expect(subject.methods).to eq(expected)
end
expect(subject.methods).to eq(expected)
end
end
describe "#append" do
it "appends to an existing key" do
subject["foo"] = "bar"
subject.append "foo", "1"
expect(subject["foo"]).to eq("bar 1")
end
it "appends to an existing empty key" do
subject["foo"] = ""
subject.append "foo", "1"
expect(subject["foo"]).to eq("1")
end
it "appends to a non-existant key" do
subject.append "foo", "1"
expect(subject["foo"]).to eq("1")
end
# NOTE: this may be a wrong behavior; we should probably reject objects that
# do not respond to #to_str. For now this documents existing behavior.
it "coerces a value to a string" do
subject.append "foo", 42
expect(subject["foo"]).to eq("42")
end
end
describe "#prepend" do
it "prepends to an existing key" do
subject["foo"] = "bar"
subject.prepend "foo", "1"
expect(subject["foo"]).to eq("1 bar")
end
it "prepends to an existing empty key" do
subject["foo"] = ""
subject.prepend "foo", "1"
expect(subject["foo"]).to eq("1")
end
it "prepends to a non-existant key" do
subject.prepend "foo", "1"
expect(subject["foo"]).to eq("1")
end
# NOTE: this may be a wrong behavior; we should probably reject objects that
# do not respond to #to_str. For now this documents existing behavior.
it "coerces a value to a string" do
subject.prepend "foo", 42
expect(subject["foo"]).to eq("42")
end
end
describe "#append_path" do
it "appends to a path" do
subject.append_path "FOO", "/usr/bin"
expect(subject["FOO"]).to eq("/usr/bin")
subject.append_path "FOO", "/bin"
expect(subject["FOO"]).to eq("/usr/bin#{File::PATH_SEPARATOR}/bin")
end
end
describe "#prepend_path" do
it "prepends to a path" do
subject.prepend_path "FOO", "/usr/bin"
expect(subject["FOO"]).to eq("/usr/bin")
subject.prepend_path "FOO", "/bin"
expect(subject["FOO"]).to eq("/bin#{File::PATH_SEPARATOR}/usr/bin")
end
end
describe "#compiler" do
it "allows switching compilers" do
[:clang, :gcc_4_2, :gcc_4_0].each do |compiler|
subject.public_send(compiler)
expect(subject.compiler).to eq(compiler)
end
end
end
example "deparallelize_block_form_restores_makeflags" do
subject["MAKEFLAGS"] = "-j4"
subject.deparallelize do
expect(subject["MAKEFLAGS"]).to be nil
end
expect(subject["MAKEFLAGS"]).to eq("-j4")
end
end
describe Stdenv do
include_examples EnvActivation
end
describe Superenv do
include_examples EnvActivation
it "initializes deps" do
expect(subject.deps).to eq([])
expect(subject.keg_only_deps).to eq([])
end
describe "#cxx11" do
it "raises an error when the compiler isn't supported" do
%w[gcc gcc-4.7].each do |compiler|
subject["HOMEBREW_CC"] = compiler
expect { subject.cxx11 }
.to raise_error(/The selected compiler doesn't support C\+\+11:/)
expect(subject["HOMEBREW_CCCFG"]).to be nil
end
end
it "supports gcc-5" do
subject["HOMEBREW_CC"] = "gcc-5"
subject.cxx11
expect(subject["HOMEBREW_CCCFG"]).to include("x")
end
example "supports gcc-6" do
subject["HOMEBREW_CC"] = "gcc-6"
subject.cxx11
expect(subject["HOMEBREW_CCCFG"]).to include("x")
end
it "supports clang" do
subject["HOMEBREW_CC"] = "clang"
subject.cxx11
expect(subject["HOMEBREW_CCCFG"]).to include("x")
expect(subject["HOMEBREW_CCCFG"]).to include("g")
end
end
end

View File

@ -1,202 +0,0 @@
require "testing_env"
require "extend/ENV"
require "testing_env"
class IntegrationCommandTestEnv < IntegrationCommandTestCase
def test_env
assert_match(/CMAKE_PREFIX_PATH="#{Regexp.escape(HOMEBREW_PREFIX)}[:"]/,
cmd("--env"))
end
def test_env_fish
assert_match(/set [-]gx CMAKE_PREFIX_PATH "#{Regexp.quote(HOMEBREW_PREFIX.to_s)}"/,
cmd("--env", "--shell=fish"))
end
def test_env_csh
assert_match(/setenv CMAKE_PREFIX_PATH #{Regexp.quote(HOMEBREW_PREFIX.to_s)};/,
cmd("--env", "--shell=tcsh"))
end
def test_env_bash
assert_match(/export CMAKE_PREFIX_PATH="#{Regexp.quote(HOMEBREW_PREFIX.to_s)}"/,
cmd("--env", "--shell=bash"))
end
def test_env_plain
assert_match(/CMAKE_PREFIX_PATH: #{Regexp.quote(HOMEBREW_PREFIX)}/,
cmd("--env", "--plain"))
end
end
module SharedEnvTests
def setup
super
@env = {}.extend(EnvActivation)
end
def test_switching_compilers
@env.clang
assert_nil @env["LD"]
assert_equal @env["OBJC"], @env["CC"]
end
def test_with_build_environment_restores_env
before = @env.dup
@env.with_build_environment do
@env["foo"] = "bar"
end
assert_nil @env["foo"]
assert_equal before, @env
end
def test_with_build_environment_ensures_env_restored
before = @env.dup
begin
@env.with_build_environment do
@env["foo"] = "bar"
raise Exception
end
rescue Exception
end
assert_nil @env["foo"]
assert_equal before, @env
end
def test_with_build_environment_returns_block_value
assert_equal 1, @env.with_build_environment { 1 }
end
def test_with_build_environment_does_not_mutate_interface
expected = @env.methods
@env.with_build_environment { assert_equal expected, @env.methods }
assert_equal expected, @env.methods
end
def test_append_existing_key
@env["foo"] = "bar"
@env.append "foo", "1"
assert_equal "bar 1", @env["foo"]
end
def test_append_existing_key_empty
@env["foo"] = ""
@env.append "foo", "1"
assert_equal "1", @env["foo"]
end
def test_append_missing_key
@env.append "foo", "1"
assert_equal "1", @env["foo"]
end
def test_prepend_existing_key
@env["foo"] = "bar"
@env.prepend "foo", "1"
assert_equal "1 bar", @env["foo"]
end
def test_prepend_existing_key_empty
@env["foo"] = ""
@env.prepend "foo", "1"
assert_equal "1", @env["foo"]
end
def test_prepend_missing_key
@env.prepend "foo", "1"
assert_equal "1", @env["foo"]
end
# NOTE: this may be a wrong behavior; we should probably reject objects that
# do not respond to #to_str. For now this documents existing behavior.
def test_append_coerces_value_to_string
@env.append "foo", 42
assert_equal "42", @env["foo"]
end
def test_prepend_coerces_value_to_string
@env.prepend "foo", 42
assert_equal "42", @env["foo"]
end
def test_append_path
@env.append_path "FOO", "/usr/bin"
assert_equal "/usr/bin", @env["FOO"]
@env.append_path "FOO", "/bin"
assert_equal "/usr/bin#{File::PATH_SEPARATOR}/bin", @env["FOO"]
end
def test_prepend_path
@env.prepend_path "FOO", "/usr/bin"
assert_equal "/usr/bin", @env["FOO"]
@env.prepend_path "FOO", "/bin"
assert_equal "/bin#{File::PATH_SEPARATOR}/usr/bin", @env["FOO"]
end
def test_switching_compilers_updates_compiler
[:clang, :gcc_4_2, :gcc_4_0].each do |compiler|
@env.send(compiler)
assert_equal compiler, @env.compiler
end
end
def test_deparallelize_block_form_restores_makeflags
@env["MAKEFLAGS"] = "-j4"
@env.deparallelize do
assert_nil @env["MAKEFLAGS"]
end
assert_equal "-j4", @env["MAKEFLAGS"]
end
end
class StdenvTests < Homebrew::TestCase
include SharedEnvTests
def setup
super
@env.extend(Stdenv)
end
end
class SuperenvTests < Homebrew::TestCase
include SharedEnvTests
def setup
super
@env.extend(Superenv)
end
def test_initializes_deps
assert_equal [], @env.deps
assert_equal [], @env.keg_only_deps
end
def test_unsupported_cxx11
%w[gcc gcc-4.7].each do |compiler|
@env["HOMEBREW_CC"] = compiler
assert_raises do
@env.cxx11
end
refute_match "x", @env["HOMEBREW_CCCFG"]
end
end
def test_supported_cxx11_gcc_5
@env["HOMEBREW_CC"] = "gcc-5"
@env.cxx11
assert_match "x", @env["HOMEBREW_CCCFG"]
end
def test_supported_cxx11_gcc_6
@env["HOMEBREW_CC"] = "gcc-6"
@env.cxx11
assert_match "x", @env["HOMEBREW_CCCFG"]
end
def test_supported_cxx11_clang
@env["HOMEBREW_CC"] = "clang"
@env.cxx11
assert_match "x", @env["HOMEBREW_CCCFG"]
assert_match "g", @env["HOMEBREW_CCCFG"]
end
end

View File

@ -419,9 +419,8 @@ class FormulaAuditorTests < Homebrew::TestCase
EOS
fa.audit_homepage
assert_equal ["The homepage should start with http or https " \
"(URL is #{fa.formula.homepage}).", "The homepage #{fa.formula.homepage} is not reachable " \
"(HTTP status code 000)"], fa.problems
assert_equal ["The homepage should start with http or https (URL is #{fa.formula.homepage})."],
fa.problems
formula_homepages = {
"bar" => "http://www.freedesktop.org/wiki/bar",
@ -466,4 +465,49 @@ class FormulaAuditorTests < Homebrew::TestCase
end
end
end
def test_audit_without_homepage
fa = formula_auditor "foo", <<-EOS.undent, online: true
class Foo < Formula
url "http://example.com/foo-1.0.tgz"
end
EOS
fa.audit_homepage
assert_match "Formula should have a homepage.", fa.problems.first
end
def test_audit_xcodebuild_suggests_symroot
fa = formula_auditor "foo", <<-EOS.undent
class Foo < Formula
url "http://example.com/foo-1.0.tgz"
homepage "http://example.com"
def install
xcodebuild "-project", "meow.xcodeproject"
end
end
EOS
fa.audit_text
assert_match 'xcodebuild should be passed an explicit "SYMROOT"', fa.problems.first
end
def test_audit_bare_xcodebuild_suggests_symroot_also
fa = formula_auditor "foo", <<-EOS.undent
class Foo < Formula
url "http://example.com/foo-1.0.tgz"
homepage "http://example.com"
def install
xcodebuild
end
end
EOS
fa.audit_text
assert_match 'xcodebuild should be passed an explicit "SYMROOT"', fa.problems.first
end
end

View File

@ -1,21 +0,0 @@
require "testing_env"
class IntegrationCommandTestBottle < IntegrationCommandTestCase
def test_bottle
cmd("install", "--build-bottle", testball)
assert_match "Formula not from core or any taps",
cmd_fail("bottle", "--no-rebuild", testball)
setup_test_formula "testball"
# `brew bottle` should not fail with dead symlink
# https://github.com/Homebrew/legacy-homebrew/issues/49007
(HOMEBREW_CELLAR/"testball/0.1").cd do
FileUtils.ln_s "not-exist", "symlink"
end
assert_match(/testball-0\.1.*\.bottle\.tar\.gz/,
cmd("bottle", "--no-rebuild", "testball"))
ensure
FileUtils.rm_f Dir["testball-0.1*.bottle.tar.gz"]
end
end

View File

@ -0,0 +1,52 @@
require "build_options"
require "options"
RSpec::Matchers.alias_matcher :be_built_with, :be_with
RSpec::Matchers.alias_matcher :be_built_without, :be_without
describe BuildOptions do
subject { described_class.new(args, opts) }
let(:bad_build) { described_class.new(bad_args, opts) }
let(:args) { Options.create(%w[--with-foo --with-bar --without-qux]) }
let(:opts) { Options.create(%w[--with-foo --with-bar --without-baz --without-qux]) }
let(:bad_args) { Options.create(%w[--with-foo --with-bar --without-bas --without-qux --without-abc]) }
specify "#include?" do
expect(subject).to include("with-foo")
expect(subject).not_to include("with-qux")
expect(subject).not_to include("--with-foo")
end
specify "#with?" do
expect(subject).to be_built_with("foo")
expect(subject).to be_built_with("bar")
expect(subject).to be_built_with("baz")
end
specify "#without?" do
expect(subject).to be_built_without("qux")
expect(subject).to be_built_without("xyz")
end
specify "#used_options" do
expect(subject.used_options).to include("--with-foo")
expect(subject.used_options).to include("--with-bar")
end
specify "#unused_options" do
expect(subject.unused_options).to include("--without-baz")
end
specify "#invalid_options" do
expect(subject.invalid_options).to be_empty
expect(bad_build.invalid_options).to include("--without-bas")
expect(bad_build.invalid_options).to include("--without-abc")
expect(bad_build.invalid_options).not_to include("--with-foo")
expect(bad_build.invalid_options).not_to include("--with-baz")
end
specify "#invalid_option_names" do
expect(subject.invalid_option_names).to be_empty
expect(bad_build.invalid_option_names).to eq(%w[--without-abc --without-bas])
end
end

View File

@ -1,50 +0,0 @@
require "testing_env"
require "build_options"
require "options"
class BuildOptionsTests < Homebrew::TestCase
def setup
super
args = Options.create(%w[--with-foo --with-bar --without-qux])
opts = Options.create(%w[--with-foo --with-bar --without-baz --without-qux])
@build = BuildOptions.new(args, opts)
bad_args = Options.create(%w[--with-foo --with-bar --without-bas --without-qux --without-abc])
@bad_build = BuildOptions.new(bad_args, opts)
end
def test_include
assert_includes @build, "with-foo"
refute_includes @build, "with-qux"
refute_includes @build, "--with-foo"
end
def test_with_without
assert @build.with?("foo")
assert @build.with?("bar")
assert @build.with?("baz")
assert @build.without?("qux")
assert @build.without?("xyz")
end
def test_used_options
assert_includes @build.used_options, "--with-foo"
assert_includes @build.used_options, "--with-bar"
end
def test_unused_options
assert_includes @build.unused_options, "--without-baz"
end
def test_invalid_options
assert_empty @build.invalid_options
assert_includes @bad_build.invalid_options, "--without-bas"
assert_includes @bad_build.invalid_options, "--without-abc"
refute_includes @bad_build.invalid_options, "--with-foo"
refute_includes @bad_build.invalid_options, "--with-baz"
end
def test_invalid_option_names
assert_empty @build.invalid_option_names
assert_equal @bad_build.invalid_option_names, %w[--without-abc --without-bas]
end
end

View File

@ -1,22 +0,0 @@
require "testing_env"
class IntegrationCommandTestBundle < IntegrationCommandTestCase
def test_bundle
needs_test_cmd_taps
setup_remote_tap("homebrew/bundle")
HOMEBREW_REPOSITORY.cd do
shutup do
system "git", "init"
system "git", "commit", "--allow-empty", "-m", "This is a test commit"
end
end
mktmpdir do |path|
FileUtils.touch "#{path}/Brewfile"
Dir.chdir path do
assert_equal "The Brewfile's dependencies are satisfied.",
cmd("bundle", "check")
end
end
end
end

View File

@ -1,8 +0,0 @@
require "testing_env"
class IntegrationCommandTestCacheFormula < IntegrationCommandTestCase
def test_cache_formula
assert_match %r{#{HOMEBREW_CACHE}/testball-},
cmd("--cache", testball)
end
end

View File

@ -1,8 +0,0 @@
require "testing_env"
class IntegrationCommandTestCache < IntegrationCommandTestCase
def test_cache
assert_equal HOMEBREW_CACHE.to_s,
cmd("--cache")
end
end

View File

@ -1,10 +0,0 @@
require "testing_env"
class IntegrationCommandTestCask < IntegrationCommandTestCase
def test_cask
needs_test_cmd_taps
needs_macos
setup_remote_tap("caskroom/cask")
cmd("cask", "list", "--caskroom=#{HOMEBREW_PREFIX}/Caskroom")
end
end

View File

@ -1,8 +0,0 @@
require "testing_env"
class IntegrationCommandTestCat < IntegrationCommandTestCase
def test_cat
formula_file = setup_test_formula "testball"
assert_equal formula_file.read.chomp, cmd("cat", "testball")
end
end

View File

@ -0,0 +1,29 @@
require "formula"
require "caveats"
describe Caveats do
subject { described_class.new(f) }
let(:f) { formula { url "foo-1.0" } }
specify "#f" do
expect(subject.f).to eq(f)
end
describe "#empty?" do
it "returns true if the Formula has no caveats" do
expect(subject).to be_empty
end
it "returns false if the Formula has caveats" do
f = formula do
url "foo-1.0"
def caveats
"something"
end
end
expect(described_class.new(f)).not_to be_empty
end
end
end

View File

@ -1,30 +0,0 @@
require "testing_env"
require "formula"
require "caveats"
class CaveatsTests < Homebrew::TestCase
def setup
super
@f = formula { url "foo-1.0" }
@c = Caveats.new @f
end
def test_f
assert_equal @f, @c.f
end
def test_empty?
assert @c.empty?
f = formula do
url "foo-1.0"
def caveats
"something"
end
end
c = Caveats.new f
refute c.empty?
end
end

View File

@ -1,8 +0,0 @@
require "testing_env"
class IntegrationCommandTestCellarFormula < IntegrationCommandTestCase
def test_cellar_formula
assert_match "#{HOMEBREW_CELLAR}/testball",
cmd("--cellar", testball)
end
end

View File

@ -1,8 +0,0 @@
require "testing_env"
class IntegrationCommandTestCellar < IntegrationCommandTestCase
def test_cellar
assert_equal HOMEBREW_CELLAR.to_s,
cmd("--cellar")
end
end

View File

@ -5,13 +5,6 @@ require "fileutils"
require "pathname"
require "testing_env"
class IntegrationCommandTestCleanup < IntegrationCommandTestCase
def test_cleanup
(HOMEBREW_CACHE/"test").write "test"
assert_match "#{HOMEBREW_CACHE}/test", cmd("cleanup", "--prune=all")
end
end
class CleanupTests < Homebrew::TestCase
def setup
super

View File

@ -0,0 +1,15 @@
describe "brew --cache", :integration_test do
it "print the location of Homebrew's cache when no argument is given" do
expect { brew "--cache" }
.to output("#{HOMEBREW_CACHE}\n").to_stdout
.and not_to_output.to_stderr
.and be_a_success
end
it "prints all cache files for a given Formula" do
expect { brew "--cache", testball }
.to output(%r{#{HOMEBREW_CACHE}/testball-}).to_stdout
.and not_to_output.to_stderr
.and be_a_success
end
end

View File

@ -0,0 +1,15 @@
describe "brew --cellar", :integration_test do
it "print the location of Homebrew's Cellar when no argument is given" do
expect { brew "--cellar" }
.to output("#{HOMEBREW_CELLAR}\n").to_stdout
.and not_to_output.to_stderr
.and be_a_success
end
it "returns the Cellar subdirectory for a given Formula" do
expect { brew "--cellar", testball }
.to output(%r{#{HOMEBREW_CELLAR}/testball}).to_stdout
.and not_to_output.to_stderr
.and be_a_success
end
end

View File

@ -0,0 +1,44 @@
describe "brew --env", :integration_test do
it "prints the Homebrew build environment variables" do
expect { brew "--env" }
.to output(/CMAKE_PREFIX_PATH="#{Regexp.escape(HOMEBREW_PREFIX)}[:"]/).to_stdout
.and not_to_output.to_stderr
.and be_a_success
end
describe "--shell=bash" do
it "prints the Homebrew build environment variables in Bash syntax" do
expect { brew "--env", "--shell=bash" }
.to output(/export CMAKE_PREFIX_PATH="#{Regexp.quote(HOMEBREW_PREFIX.to_s)}"/).to_stdout
.and not_to_output.to_stderr
.and be_a_success
end
end
describe "--shell=fish" do
it "prints the Homebrew build environment variables in Fish syntax" do
expect { brew "--env", "--shell=fish" }
.to output(/set [-]gx CMAKE_PREFIX_PATH "#{Regexp.quote(HOMEBREW_PREFIX.to_s)}"/).to_stdout
.and not_to_output.to_stderr
.and be_a_success
end
end
describe "--shell=tcsh" do
it "prints the Homebrew build environment variables in Tcsh syntax" do
expect { brew "--env", "--shell=tcsh" }
.to output(/setenv CMAKE_PREFIX_PATH #{Regexp.quote(HOMEBREW_PREFIX.to_s)};/).to_stdout
.and not_to_output.to_stderr
.and be_a_success
end
end
describe "--plain" do
it "prints the Homebrew build environment variables without quotes" do
expect { brew "--env", "--plain" }
.to output(/CMAKE_PREFIX_PATH: #{Regexp.quote(HOMEBREW_PREFIX)}/).to_stdout
.and not_to_output.to_stderr
.and be_a_success
end
end
end

View File

@ -0,0 +1,15 @@
describe "brew --prefix", :integration_test do
it "prints the Homebrew prefix when no argument is given" do
expect { brew "--prefix" }
.to output("#{HOMEBREW_PREFIX}\n").to_stdout
.and not_to_output.to_stderr
.and be_a_success
end
it "prints a given Formula's prefix" do
expect { brew "--prefix", testball }
.to output(%r{#{HOMEBREW_CELLAR}/testball}).to_stdout
.and not_to_output.to_stderr
.and be_a_success
end
end

View File

@ -0,0 +1,15 @@
describe "brew --repository", :integration_test do
it "prints the path of the Homebrew repository" do
expect { brew "--repository" }
.to output("#{HOMEBREW_REPOSITORY}\n").to_stdout
.and not_to_output.to_stderr
.and be_a_success
end
it "prints the path of a given Tap" do
expect { brew "--repository", "foo/bar" }
.to output("#{HOMEBREW_LIBRARY}/Taps/foo/homebrew-bar\n").to_stdout
.and not_to_output.to_stderr
.and be_a_success
end
end

View File

@ -0,0 +1,8 @@
describe "brew --version", :integration_test do
it "prints the Homebrew version" do
expect { brew "--version" }
.to output(/^Homebrew #{Regexp.escape(HOMEBREW_VERSION.to_s)}\n/).to_stdout
.and not_to_output.to_stderr
.and be_a_success
end
end

View File

@ -0,0 +1,24 @@
describe "brew bundle", :integration_test, :needs_test_cmd_taps do
describe "check" do
it "checks if a Brewfile's dependencies are satisfied" do
setup_remote_tap "homebrew/bundle"
HOMEBREW_REPOSITORY.cd do
shutup do
system "git", "init"
system "git", "commit", "--allow-empty", "-m", "This is a test commit"
end
end
Dir.mktmpdir do |path|
FileUtils.touch "#{path}/Brewfile"
Dir.chdir path do
expect { brew "bundle", "check" }
.to output("The Brewfile's dependencies are satisfied.\n").to_stdout
.and not_to_output.to_stderr
.and be_a_success
end
end
end
end
end

View File

@ -0,0 +1,8 @@
describe "brew cask", :integration_test, :needs_macos, :needs_official_cmd_taps do
describe "list" do
it "returns a list of installed Casks" do
setup_remote_tap("caskroom/cask")
expect { brew "cask", "list" }.to be_a_success
end
end
end

View File

@ -0,0 +1,11 @@
describe "brew cat", :integration_test do
it "prints the content of a given Formula" do
formula_file = setup_test_formula "testball"
content = formula_file.read
expect { brew "cat", "testball" }
.to output(content).to_stdout
.and not_to_output.to_stderr
.and be_a_success
end
end

View File

@ -0,0 +1,12 @@
describe "brew cleanup", :integration_test do
describe "--prune=all" do
it "removes all files in Homebrew's cache" do
(HOMEBREW_CACHE/"test").write "test"
expect { brew "cleanup", "--prune=all" }
.to output(%r{#{Regexp.escape(HOMEBREW_CACHE)}/test}).to_stdout
.and not_to_output.to_stderr
.and be_a_success
end
end
end

View File

@ -0,0 +1,13 @@
describe "brew command", :integration_test do
it "returns the file for a given command" do
expect { brew "command", "info" }
.to output(%r{#{Regexp.escape(HOMEBREW_LIBRARY_PATH)}/cmd/info.rb}).to_stdout
.and be_a_success
end
it "fails when the given command is unknown" do
expect { brew "command", "does-not-exist" }
.to output(/Unknown command/).to_stderr
.and be_a_failure
end
end

View File

@ -0,0 +1,7 @@
describe "brew commands", :integration_test do
it "prints a list of all available commands" do
expect { brew "commands" }
.to output(/Built-in commands/).to_stdout
.and be_a_success
end
end

View File

@ -0,0 +1,8 @@
describe "brew config", :integration_test do
it "prints information about the current Homebrew configuration" do
expect { brew "config" }
.to output(/HOMEBREW_VERSION: #{HOMEBREW_VERSION}/).to_stdout
.and not_to_output.to_stderr
.and be_a_success
end
end

View File

@ -0,0 +1,21 @@
describe "brew custom-external-command", :integration_test do
it "is supported" do
Dir.mktmpdir do |path|
path = Pathname.new(path)
cmd = "custom-external-command-#{rand}"
file = path/"brew-#{cmd}"
file.write <<-EOS.undent
#!/bin/sh
echo 'I am #{cmd}.'
EOS
FileUtils.chmod "+x", file
expect { brew cmd, "PATH" => "#{path}#{File::PATH_SEPARATOR}#{ENV["PATH"]}" }
.to output("I am #{cmd}.\n").to_stdout
.and not_to_output.to_stderr
.and be_a_success
end
end
end

View File

@ -0,0 +1,40 @@
describe "brew desc", :integration_test do
let(:desc_cache) { HOMEBREW_CACHE/"desc_cache.json" }
it "shows a given Formula's description" do
setup_test_formula "testball"
expect { brew "desc", "testball" }
.to output("testball: Some test\n").to_stdout
.and not_to_output.to_stderr
.and be_a_success
end
it "fails when both --search and --name are specified" do
expect { brew "desc", "--search", "--name" }
.to output(/Pick one, and only one/).to_stderr
.and not_to_output.to_stdout
.and be_a_failure
end
describe "--search" do
it "fails when no search term is given" do
expect { brew "desc", "--search" }
.to output(/You must provide a search term/).to_stderr
.and not_to_output.to_stdout
.and be_a_failure
end
end
describe "--description" do
it "creates a description cache" do
expect(desc_cache).not_to exist
shutup do
expect { brew "desc", "--description", "testball" }.to be_a_success
end
expect(desc_cache).to exist
end
end
end

View File

@ -0,0 +1,6 @@
describe "brew doctor", :integration_test do
specify "check_integration_test" do
expect { brew "doctor", "check_integration_test" }
.to output(/This is an integration test/).to_stderr
end
end

View File

@ -0,0 +1,13 @@
describe "brew fetch", :integration_test do
it "downloads the Formula's URL" do
setup_test_formula "testball"
expect(HOMEBREW_CACHE/"testball-0.1.tbz").not_to exist
shutup do
expect { brew "fetch", "testball" }.to be_a_success
end
expect(HOMEBREW_CACHE/"testball-0.1.tbz").to exist
end
end

View File

@ -0,0 +1,47 @@
describe "brew", :integration_test do
it "prints help when no argument is given" do
expect { brew }
.to output(/Example usage:\n/).to_stderr
.and be_a_failure
end
describe "help" do
it "prints help" do
expect { brew "help" }
.to output(/Example usage:\n/).to_stdout
.and be_a_success
end
it "prints help for a documented Ruby command" do
expect { brew "help", "cat" }
.to output(/^brew cat/).to_stdout
.and be_a_success
end
it "prints help for a documented shell command" do
expect { brew "help", "update" }
.to output(/^brew update/).to_stdout
.and be_a_success
end
it "prints help for a documented Ruby developer command" do
expect { brew "help", "update-test" }
.to output(/^brew update-test/).to_stdout
.and be_a_success
end
it "fails when given an unknown command" do
expect { brew "help", "command-that-does-not-exist" }
.to output(/Unknown command: command-that-does-not-exist/).to_stderr
.and be_a_failure
end
end
describe "cat" do
it "prints help when no argument is given" do
expect { brew "cat" }
.to output(/^brew cat/).to_stderr
.and be_a_failure
end
end
end

View File

@ -0,0 +1,17 @@
describe "brew home", :integration_test do
it "opens the Homebrew homepage when no argument is given" do
expect { brew "home", "HOMEBREW_BROWSER" => "echo" }
.to output("#{HOMEBREW_WWW}\n").to_stdout
.and not_to_output.to_stderr
.and be_a_success
end
it "opens the homepage for a given Formula" do
setup_test_formula "testball"
expect { brew "home", "testball", "HOMEBREW_BROWSER" => "echo" }
.to output("#{Formula["testball"].homepage}\n").to_stdout
.and not_to_output.to_stderr
.and be_a_success
end
end

View File

@ -0,0 +1,30 @@
require "cmd/info"
describe "brew info", :integration_test do
it "prints information about a given Formula" do
setup_test_formula "testball"
expect { brew "info", "testball" }
.to output(/testball: stable 0.1/).to_stdout
.and not_to_output.to_stderr
.and be_a_success
end
end
describe Homebrew do
let(:remote) { "https://github.com/Homebrew/homebrew-core" }
specify "::github_remote_path" do
expect(subject.github_remote_path(remote, "Formula/git.rb"))
.to eq("https://github.com/Homebrew/homebrew-core/blob/master/Formula/git.rb")
expect(subject.github_remote_path("#{remote}.git", "Formula/git.rb"))
.to eq("https://github.com/Homebrew/homebrew-core/blob/master/Formula/git.rb")
expect(subject.github_remote_path("git@github.com:user/repo", "foo.rb"))
.to eq("https://github.com/user/repo/blob/master/foo.rb")
expect(subject.github_remote_path("https://mywebsite.com", "foo/bar.rb"))
.to eq("https://mywebsite.com/foo/bar.rb")
end
end

View File

@ -0,0 +1,243 @@
describe "brew install", :integration_test do
it "installs Formulae" do
setup_test_formula "testball1"
expect { brew "install", "testball1", "--head" }
.to output(/Specify `\-\-HEAD`/).to_stderr
.and not_to_output.to_stdout
.and be_a_failure
expect { brew "install", "testball1", "--HEAD" }
.to output(/No head is defined/).to_stderr
.and not_to_output.to_stdout
.and be_a_failure
expect { brew "install", "testball1", "--devel" }
.to output(/No devel block/).to_stderr
.and not_to_output.to_stdout
.and be_a_failure
expect { brew "install", "testball1" }
.to output(%r{#{HOMEBREW_CELLAR}/testball1/0\.1}).to_stdout
.and not_to_output.to_stderr
.and be_a_success
expect { brew "install", "testball1" }
.to output(/testball1\-0\.1 already installed/).to_stderr
.and not_to_output.to_stdout
.and be_a_success
expect { brew "install", "macruby" }
.to output(/MacRuby is not packaged/).to_stderr
.and not_to_output.to_stdout
.and be_a_failure
expect { brew "install", "formula" }
.to output(/No available formula/).to_stderr
.and output(/Searching for similarly named formulae/).to_stdout
.and be_a_failure
expect { brew "install", "testball" }
.to output(/This similarly named formula was found/).to_stdout
.and output(/No available formula/).to_stderr
.and be_a_failure
setup_test_formula "testball2"
expect { brew "install", "testball" }
.to output(/These similarly named formulae were found/).to_stdout
.and output(/No available formula/).to_stderr
.and be_a_failure
install_and_rename_coretap_formula "testball1", "testball2"
expect { brew "install", "testball2" }
.to output(/testball1 already installed, it's just not migrated/).to_stderr
.and output(/You can migrate formula with `brew migrate testball2`/).to_stdout
.and be_a_success
end
specify "install failures" do
path = setup_test_formula "testball1", <<-EOS.undent
version "1.0"
EOS
expect { brew "install", "testball1" }
.to output(%r{#{HOMEBREW_CELLAR}/testball1/1\.0}).to_stdout
.and not_to_output.to_stderr
.and be_a_success
FileUtils.rm path
setup_test_formula "testball1", <<-EOS.undent
version "2.0"
devel do
url "#{Formulary.factory("testball1").stable.url}"
sha256 "#{TESTBALL_SHA256}"
version "3.0"
end
EOS
expect { brew "install", "testball1" }
.to output(/first `brew unlink testball1`/).to_stderr
.and not_to_output.to_stdout
.and be_a_failure
expect { brew "unlink", "testball1" }
.to output(%r{#{HOMEBREW_CELLAR}/testball1/1\.0}).to_stdout
.and not_to_output.to_stderr
.and be_a_success
expect { brew "install", "testball1", "--devel" }
.to output(%r{#{HOMEBREW_CELLAR}/testball1/3\.0}).to_stdout
.and not_to_output.to_stderr
.and be_a_success
expect { brew "unlink", "testball1" }
.to output(%r{#{HOMEBREW_CELLAR}/testball1/3\.0}).to_stdout
.and not_to_output.to_stderr
.and be_a_success
expect { brew "install", "testball1" }
.to output(%r{#{HOMEBREW_CELLAR}/testball1/2\.0}).to_stdout
.and not_to_output.to_stderr
.and be_a_success
shutup do
expect { brew "switch", "testball1", "3.0" }.to be_a_success
end
expect { brew "install", "testball1" }
.to output(/already installed, however linked version is/).to_stderr
.and output(/`brew switch testball1 2.0`/).to_stdout
.and be_a_success
expect { brew "unlink", "testball1" }
.to output(%r{#{HOMEBREW_CELLAR}/testball1/3\.0}).to_stdout
.and not_to_output.to_stderr
.and be_a_success
expect { brew "install", "testball1" }
.to output(/just not linked/).to_stderr
.and not_to_output.to_stdout
.and be_a_success
end
it "can install keg-only Formulae" do
path_keg_only = setup_test_formula "testball1", <<-EOS.undent
version "1.0"
keg_only "test reason"
EOS
expect { brew "install", "testball1" }
.to output(%r{#{HOMEBREW_CELLAR}/testball1/1\.0}).to_stdout
.and not_to_output.to_stderr
.and be_a_success
FileUtils.rm path_keg_only
setup_test_formula "testball1", <<-EOS.undent
version "2.0"
keg_only "test reason"
EOS
expect { brew "install", "testball1" }
.to output(/keg-only and another version is linked to opt/).to_stderr
.and output(/Use `brew install --force`/).to_stdout
.and be_a_success
expect { brew "install", "testball1", "--force" }
.to output(%r{#{HOMEBREW_CELLAR}/testball1/2\.0}).to_stdout
.and not_to_output.to_stderr
.and be_a_success
end
it "can install HEAD Formulae" do
repo_path = HOMEBREW_CACHE.join("repo")
repo_path.join("bin").mkpath
repo_path.cd do
shutup do
system "git", "init"
system "git", "remote", "add", "origin", "https://github.com/Homebrew/homebrew-foo"
FileUtils.touch "bin/something.bin"
FileUtils.touch "README"
system "git", "add", "--all"
system "git", "commit", "-m", "Initial repo commit"
end
end
setup_test_formula "testball1", <<-EOS.undent
version "1.0"
head "file://#{repo_path}", :using => :git
def install
prefix.install Dir["*"]
end
EOS
# Ignore dependencies, because we'll try to resolve requirements in build.rb
# and there will be the git requirement, but we cannot instantiate git
# formula since we only have testball1 formula.
expect { brew "install", "testball1", "--HEAD", "--ignore-dependencies" }
.to output(%r{#{HOMEBREW_CELLAR}/testball1/HEAD\-d5eb689}).to_stdout
.and output(/Cloning into/).to_stderr
.and be_a_success
expect { brew "install", "testball1", "--HEAD", "--ignore-dependencies" }
.to output(/testball1\-HEAD\-d5eb689 already installed/).to_stderr
.and not_to_output.to_stdout
.and be_a_success
expect { brew "unlink", "testball1" }
.to output(%r{#{HOMEBREW_CELLAR}/testball1/HEAD\-d5eb689}).to_stdout
.and not_to_output.to_stderr
.and be_a_success
expect { brew "install", "testball1" }
.to output(%r{#{HOMEBREW_CELLAR}/testball1/1\.0}).to_stdout
.and not_to_output.to_stderr
.and be_a_success
end
it "ignores invalid options" do
setup_test_formula "testball1"
expect { brew "install", "testball1", "--with-fo" }
.to output(/testball1: this formula has no \-\-with\-fo option so it will be ignored!/).to_stderr
.and output(/Downloading file/).to_stdout
.and be_a_success
end
it "succeeds when a non-fatal requirement isn't satisfied" do
setup_test_formula "testball1", <<-EOS.undent
class NonFatalRequirement < Requirement
satisfy { false }
end
depends_on NonFatalRequirement
EOS
# FIXME: This should output to STDERR.
expect { brew "install", "testball1" }
.to output(/NonFatalRequirement unsatisfied!/).to_stdout
.and not_to_output.to_stderr
.and be_a_success
end
it "fails when a fatal requirement isn't satisfied" do
setup_test_formula "testball1", <<-EOS.undent
class FatalRequirement < Requirement
fatal true
satisfy { false }
end
depends_on FatalRequirement
EOS
# FIXME: This should output to STDERR.
expect { brew "install", "testball1" }
.to output(/FatalRequirement unsatisfied!/).to_stdout
.and output(/An unsatisfied requirement failed this build./).to_stderr
.and be_a_failure
end
end

View File

@ -0,0 +1,24 @@
describe "brew irb", :integration_test do
it "starts an interactive Homebrew shell session" do
setup_test_formula "testball"
irb_test = HOMEBREW_TEMP/"irb-test.rb"
irb_test.write <<-EOS.undent
"testball".f
:testball.f
exit
EOS
expect { brew "irb", irb_test }
.to output(/Interactive Homebrew Shell/).to_stdout
.and not_to_output.to_stderr
.and be_a_success
end
specify "--examples" do
expect { brew "irb", "--examples" }
.to output(/'v8'\.f # => instance of the v8 formula/).to_stdout
.and not_to_output.to_stderr
.and be_a_success
end
end

View File

@ -0,0 +1,23 @@
describe "brew leaves", :integration_test do
it "prints all Formulae that are not dependencies of other Formulae" do
setup_test_formula "foo"
setup_test_formula "bar"
expect { brew "leaves" }
.to be_a_success
.and not_to_output.to_stdout
.and not_to_output.to_stderr
(HOMEBREW_CELLAR/"foo/0.1/somedir").mkpath
expect { brew "leaves" }
.to output("foo\n").to_stdout
.and not_to_output.to_stderr
.and be_a_success
(HOMEBREW_CELLAR/"bar/0.1/somedir").mkpath
expect { brew "leaves" }
.to output("bar\n").to_stdout
.and not_to_output.to_stderr
.and be_a_success
end
end

View File

@ -0,0 +1,56 @@
describe "brew link", :integration_test do
it "fails when no argument is given" do
expect { brew "link" }
.to output(/This command requires a keg argument/).to_stderr
.and not_to_output.to_stdout
.and be_a_failure
end
it "does not fail if the given Formula is already linked" do
setup_test_formula "testball1"
shutup do
expect { brew "install", "testball1" }.to be_a_success
expect { brew "link", "testball1" }.to be_a_success
end
end
it "links a given Formula" do
setup_test_formula "testball1"
shutup do
expect { brew "install", "testball1" }.to be_a_success
expect { brew "unlink", "testball1" }.to be_a_success
end
expect { brew "link", "--dry-run", "testball1" }
.to output(/Would link/).to_stdout
.and not_to_output.to_stderr
.and be_a_success
expect { brew "link", "--dry-run", "--overwrite", "testball1" }
.to output(/Would remove/).to_stdout
.and not_to_output.to_stderr
.and be_a_success
expect { brew "link", "testball1" }
.to output(/Linking/).to_stdout
.and not_to_output.to_stderr
.and be_a_success
end
it "refuses to link keg-only Formulae" do
setup_test_formula "testball1", <<-EOS.undent
keg_only "just because"
EOS
shutup do
expect { brew "install", "testball1" }.to be_a_success
end
expect { brew "link", "testball1" }
.to output(/testball1 is keg-only/).to_stderr
.and output(/Note that doing so can interfere with building software\./).to_stdout
.and be_a_success
end
end

View File

@ -0,0 +1,24 @@
describe "brew linkapps", :integration_test do
let(:home_dir) { @home_dir = Pathname.new(Dir.mktmpdir) }
let(:apps_dir) { home_dir/"Applications" }
after(:each) do
home_dir.rmtree unless @home_dir.nil?
end
it "symlinks applications" do
apps_dir.mkpath
setup_test_formula "testball"
source_app = HOMEBREW_CELLAR/"testball/0.1/TestBall.app"
source_app.mkpath
expect { brew "linkapps", "--local", "HOME" => home_dir }
.to output(/Linking: #{Regexp.escape(source_app)}/).to_stdout
.and output(/`brew linkapps` has been deprecated/).to_stderr
.and be_a_success
expect(apps_dir/"TestBall.app").to be_a_symlink
end
end

View File

@ -0,0 +1,14 @@
describe "brew list", :integration_test do
let(:formulae) { %w[bar foo qux] }
it "prints all installed Formulae" do
formulae.each do |f|
(HOMEBREW_CELLAR/f/"1.0/somedir").mkpath
end
expect { brew "list" }
.to output("#{formulae.join("\n")}\n").to_stdout
.and not_to_output.to_stderr
.and be_a_success
end
end

View File

@ -0,0 +1,41 @@
describe "brew log", :integration_test do
it "shows the Git log for the Homebrew repository when no argument is given" do
HOMEBREW_REPOSITORY.cd do
shutup do
system "git", "init"
system "git", "commit", "--allow-empty", "-m", "This is a test commit"
end
end
expect { brew "log" }
.to output(/This is a test commit/).to_stdout
.and not_to_output.to_stderr
.and be_a_success
end
it "shows the Git log for a given Formula" do
setup_test_formula "testball"
core_tap = CoreTap.new
core_tap.path.cd do
shutup do
system "git", "init"
system "git", "add", "--all"
system "git", "commit", "-m", "This is a test commit for Testball"
end
end
core_tap_url = "file://#{core_tap.path}"
shallow_tap = Tap.fetch("homebrew", "shallow")
shutup do
system "git", "clone", "--depth=1", core_tap_url, shallow_tap.path
end
expect { brew "log", "#{shallow_tap}/testball" }
.to output(/This is a test commit for Testball/).to_stdout
.and output(/Warning: The git repository is a shallow clone/).to_stderr
.and be_a_success
expect(shallow_tap.path/".git/shallow").to exist, "A shallow clone should have been created."
end
end

View File

@ -0,0 +1,46 @@
describe "brew migrate", :integration_test do
before(:each) do
setup_test_formula "testball1"
setup_test_formula "testball2"
end
it "fails when no argument is given" do
expect { brew "migrate" }
.to output(/Invalid usage/).to_stderr
.and not_to_output.to_stdout
.and be_a_failure
end
it "fails when a given Formula doesn't exist" do
expect { brew "migrate", "testball" }
.to output(/No available formula with the name "testball"/).to_stderr
.and not_to_output.to_stdout
.and be_a_failure
end
it "fails if a given Formula doesn't replace another one" do
expect { brew "migrate", "testball1" }
.to output(/testball1 doesn't replace any formula/).to_stderr
.and not_to_output.to_stdout
.and be_a_failure
end
it "migrates a renamed Formula" do
install_and_rename_coretap_formula "testball1", "testball2"
expect { brew "migrate", "testball1" }
.to output(/Migrating testball1 to testball2/).to_stdout
.and not_to_output.to_stderr
.and be_a_success
end
it "fails if a given Formula is not installed" do
install_and_rename_coretap_formula "testball1", "testball2"
(HOMEBREW_CELLAR/"testball1").rmtree
expect { brew "migrate", "testball1" }
.to output(/Error: No such keg/).to_stderr
.and not_to_output.to_stdout
.and be_a_failure
end
end

View File

@ -0,0 +1,41 @@
describe "brew missing", :integration_test do
before(:each) do
setup_test_formula "foo"
setup_test_formula "bar"
end
def make_prefix(name)
(HOMEBREW_CELLAR/name/"1.0").mkpath
end
it "prints missing dependencies" do
make_prefix "bar"
expect { brew "missing" }
.to output("foo\n").to_stdout
.and not_to_output.to_stderr
.and be_a_success
end
it "prints nothing if all dependencies are installed" do
make_prefix "foo"
make_prefix "bar"
expect { brew "missing" }
.to be_a_success
.and not_to_output.to_stdout
.and not_to_output.to_stderr
end
describe "--hide=" do
it "pretends that the specified Formulae are not installed" do
make_prefix "foo"
make_prefix "bar"
expect { brew "missing", "--hide=foo" }
.to output("bar: foo\n").to_stdout
.and not_to_output.to_stderr
.and be_a_success
end
end
end

View File

@ -0,0 +1,12 @@
describe "brew options", :integration_test do
it "prints a given Formula's options" do
setup_test_formula "testball", <<-EOS.undent
depends_on "bar" => :recommended
EOS
expect { brew "options", "testball" }
.to output("--with-foo\n\tBuild with foo\n--without-bar\n\tBuild without bar support\n\n").to_stdout
.and not_to_output.to_stderr
.and be_a_success
end
end

View File

@ -0,0 +1,11 @@
describe "brew outdated", :integration_test do
it "prints outdated Formulae" do
setup_test_formula "testball"
(HOMEBREW_CELLAR/"testball/0.0.1/foo").mkpath
expect { brew "outdated" }
.to output("testball\n").to_stdout
.and not_to_output.to_stderr
.and be_a_success
end
end

View File

@ -0,0 +1,13 @@
describe "brew pin", :integration_test do
it "pins a Formula's version" do
setup_test_formula "testball"
(HOMEBREW_CELLAR/"testball/0.0.1/foo").mkpath
shutup do
expect { brew "pin", "testball" }.to be_a_success
expect { brew "upgrade" }.to be_a_success
end
expect(HOMEBREW_CELLAR/"testball/0.1").not_to be_a_directory
end
end

View File

@ -0,0 +1,28 @@
describe "brew prune", :integration_test do
it "removes empty directories and broken symlinks" do
share = (HOMEBREW_PREFIX/"share")
(share/"pruneable/directory/here").mkpath
(share/"notpruneable/file").write "I'm here"
FileUtils.ln_s "/i/dont/exist/no/really/i/dont", share/"pruneable_symlink"
expect { brew "prune", "--dry-run" }
.to output(%r{Would remove \(empty directory\): .*/pruneable/directory/here}).to_stdout
.and not_to_output.to_stderr
.and be_a_success
expect { brew "prune" }
.to output(/Pruned 1 symbolic links and 3 directories/).to_stdout
.and not_to_output.to_stderr
.and be_a_success
expect(share/"pruneable").not_to be_a_directory
expect(share/"notpruneable").to be_a_directory
expect(share/"pruneable_symlink").not_to be_a_symlink
expect { brew "prune", "--verbose" }
.to output(/Nothing pruned/).to_stdout
.and not_to_output.to_stderr
.and be_a_success
end
end

View File

@ -0,0 +1,20 @@
describe "brew readall", :integration_test do
it "imports all Formulae for a given Tap" do
formula_file = setup_test_formula "testball"
alias_file = CoreTap.new.alias_dir/"foobar"
alias_file.parent.mkpath
FileUtils.ln_s formula_file, alias_file
expect { brew "readall", "--aliases", "--syntax" }
.to be_a_success
.and not_to_output.to_stdout
.and not_to_output.to_stderr
expect { brew "readall", "homebrew/core" }
.to be_a_success
.and not_to_output.to_stdout
.and not_to_output.to_stderr
end
end

View File

@ -0,0 +1,44 @@
require "extend/ENV"
describe "brew reinstall", :integration_test do
before(:each) do
setup_test_formula "testball"
shutup do
expect { brew "install", "testball", "--with-foo" }.to be_a_success
end
end
it "reinstalls a Formula" do
foo_dir = HOMEBREW_CELLAR/"testball/0.1/foo"
expect(foo_dir).to exist
foo_dir.rmtree
expect { brew "reinstall", "testball" }
.to output(/Reinstalling testball --with-foo/).to_stdout
.and not_to_output.to_stderr
.and be_a_success
expect(foo_dir).to exist
end
it "reinstalls a Formula even when one of the options is invalid" do
expect { brew "reinstall", "testball", "--with-fo" }
.to output(/Reinstalling testball --with-foo/).to_stdout
.and output(/testball: this formula has no \-\-with-fo option so it will be ignored!/).to_stderr
.and be_a_success
end
it "refuses to reinstall a pinned Formula, but doesn't fail" do
(HOMEBREW_CELLAR/"testball/0.1").mkpath
HOMEBREW_PINNED_KEGS.mkpath
FileUtils.ln_s HOMEBREW_CELLAR/"testball/0.1", HOMEBREW_PINNED_KEGS/"testball"
expect { brew "reinstall", "testball" }
.to output(/testball is pinned. You must unpin it to reinstall./).to_stderr
.and not_to_output.to_stdout
.and be_a_success
HOMEBREW_PINNED_KEGS.rmtree
end
end

View File

@ -0,0 +1,57 @@
describe "brew search", :integration_test do
before(:each) do
setup_test_formula "testball"
end
it "lists all available Formulae when no argument is given" do
expect { brew "search" }
.to output(/testball/).to_stdout
.and not_to_output.to_stderr
.and be_a_success
end
it "supports searching by name" do
expect { brew "search", "testball" }
.to output(/testball/).to_stdout
.and not_to_output.to_stderr
.and be_a_success
end
it "supports searching a fully-qualified name " do
expect { brew "search", "homebrew/homebrew-core/testball" }
.to output(/testball/).to_stdout
.and not_to_output.to_stderr
.and be_a_success
end
describe "--desc" do
let(:desc_cache) { HOMEBREW_CACHE/"desc_cache.json" }
it "supports searching in descriptions and creates a description cache" do
expect(desc_cache).not_to exist
expect { brew "search", "--desc", "Some test" }
.to output(/testball/).to_stdout
.and not_to_output.to_stderr
.and be_a_success
expect(desc_cache).to exist
end
end
{
"macports" => "https://www.macports.org/ports.php?by=name&substr=testball",
"fink" => "http://pdb.finkproject.org/pdb/browse.php?summary=testball",
"debian" => "https://packages.debian.org/search?keywords=testball&searchon=names&suite=all&section=all",
"opensuse" => "https://software.opensuse.org/search?q=testball",
"fedora" => "https://admin.fedoraproject.org/pkgdb/packages/%2Atestball%2A/",
"ubuntu" => "http://packages.ubuntu.com/search?keywords=testball&searchon=names&suite=all&section=all",
}.each do |flag, url|
specify "--#{flag}" do
expect { brew "search", "--#{flag}", "testball", "HOMEBREW_BROWSER" => "echo" }
.to output("#{url}\n").to_stdout
.and not_to_output.to_stderr
.and be_a_success
end
end
end

View File

@ -0,0 +1,10 @@
describe "brew services", :integration_test, :needs_macos, :needs_official_cmd_taps do
it "allows controlling services" do
setup_remote_tap "homebrew/services"
expect { brew "services", "list" }
.to output("Warning: No services available to control with `brew services`\n").to_stderr
.and not_to_output.to_stdout
.and be_a_success
end
end

View File

@ -0,0 +1,8 @@
describe "brew sh", :integration_test do
it "runs a shell with the Homebrew environment" do
expect { brew "sh", "SHELL" => which("true") }
.to output(/Your shell has been configured/).to_stdout
.and not_to_output.to_stderr
.and be_a_success
end
end

View File

@ -0,0 +1,34 @@
describe "brew switch", :integration_test do
it "allows switching between Formula versions" do
expect { brew "switch" }
.to output(/Usage: brew switch <name> <version>/).to_stderr
.and not_to_output.to_stdout
.and be_a_failure
expect { brew "switch", "testball", "0.1" }
.to output(/testball not found/).to_stderr
.and not_to_output.to_stdout
.and be_a_failure
setup_test_formula "testball", <<-EOS.undent
keg_only "just because"
EOS
shutup do
expect { brew "install", "testball" }.to be_a_success
end
testball_rack = HOMEBREW_CELLAR/"testball"
FileUtils.cp_r testball_rack/"0.1", testball_rack/"0.2"
expect { brew "switch", "testball", "0.2" }
.to output(/link created/).to_stdout
.and not_to_output.to_stderr
.and be_a_success
expect { brew "switch", "testball", "0.3" }
.to output("Versions available: 0.1, 0.2\n").to_stdout
.and output(/testball does not have a version "0.3"/).to_stderr
.and be_a_failure
end
end

View File

@ -0,0 +1,10 @@
describe "brew tap-new", :integration_test do
it "initializes a new Tap with a ReadMe file" do
expect { brew "tap-new", "homebrew/foo", "--verbose" }
.to be_a_success
.and not_to_output.to_stdout
.and not_to_output.to_stderr
expect(HOMEBREW_LIBRARY/"Taps/homebrew/homebrew-foo/README.md").to exist
end
end

View File

@ -0,0 +1,12 @@
describe "brew uninstall", :integration_test do
it "uninstalls a given Formula" do
shutup do
expect { brew "install", testball }.to be_a_success
end
expect { brew "uninstall", "--force", testball }
.to output(/Uninstalling testball/).to_stdout
.and not_to_output.to_stderr
.and be_a_success
end
end

View File

@ -0,0 +1,14 @@
describe "brew unlink", :integration_test do
it "unlinks a Formula" do
setup_test_formula "testball"
shutup do
expect { brew "install", "testball" }.to be_a_success
end
expect { brew "unlink", "--dry-run", "testball" }
.to output(/Would remove/).to_stdout
.and not_to_output.to_stderr
.and be_a_success
end
end

View File

@ -0,0 +1,24 @@
describe "brew unlinkapps", :integration_test do
let(:home_dir) { @home_dir = Pathname.new(Dir.mktmpdir) }
let(:apps_dir) { home_dir/"Applications" }
after(:each) do
home_dir.rmtree unless @home_dir.nil?
end
it "unlinks symlinked applications" do
apps_dir.mkpath
setup_test_formula "testball"
source_app = HOMEBREW_CELLAR/"testball/0.1/TestBall.app"
source_app.mkpath
FileUtils.ln_s source_app, apps_dir/"TestBall.app"
expect { brew "unlinkapps", "--local", "HOME" => home_dir }
.to output(%r{Unlinking: #{Regexp.escape(apps_dir)}/TestBall.app}).to_stdout
.and output(/`brew unlinkapps` has been deprecated/).to_stderr
.and be_a_success
end
end

View File

@ -0,0 +1,16 @@
describe "brew unpack", :integration_test do
it "unpacks a given Formula's archive" do
setup_test_formula "testball"
Dir.mktmpdir do |path|
path = Pathname.new(path)
shutup do
expect { brew "unpack", "testball", "--destdir=#{path}" }
.to be_a_success
end
expect(path/"testball-0.1").to be_a_directory
end
end
end

View File

@ -0,0 +1,14 @@
describe "brew unpin", :integration_test do
it "unpins a Formula's version" do
setup_test_formula "testball"
(HOMEBREW_CELLAR/"testball/0.0.1/foo").mkpath
shutup do
expect { brew "pin", "testball" }.to be_a_success
expect { brew "unpin", "testball" }.to be_a_success
expect { brew "upgrade" }.to be_a_success
end
expect(HOMEBREW_CELLAR/"testball/0.1").to be_a_directory
end
end

View File

@ -0,0 +1,127 @@
require "cmd/update-report"
require "formula_versions"
require "yaml"
describe Reporter do
def perform_update(fixture_name = "")
allow(Formulary).to receive(:factory).and_return(double(pkg_version: "1.0"))
allow(FormulaVersions).to receive(:new).and_return(double(formula_at_revision: "2.0"))
diff = YAML.load_file("#{TEST_FIXTURE_DIR}/updater_fixture.yaml")[fixture_name]
allow(subject).to receive(:diff).and_return(diff || "")
hub.add(subject) if subject.updated?
end
let(:reporter_class) do
Class.new(described_class) do
def initialize(tap)
@tap = tap
ENV["HOMEBREW_UPDATE_BEFORE#{repo_var}"] = "12345678"
ENV["HOMEBREW_UPDATE_AFTER#{repo_var}"] = "abcdef00"
super(tap)
end
end
end
subject { reporter_class.new(tap) }
let(:tap) { CoreTap.new }
let(:hub) { ReporterHub.new }
specify "without revision variable" do
ENV.delete_if { |k, _v| k.start_with? "HOMEBREW_UPDATE" }
expect {
described_class.new(tap)
}.to raise_error(Reporter::ReporterRevisionUnsetError)
end
specify "without any changes" do
perform_update
expect(hub).to be_empty
end
specify "without Formula changes" do
perform_update("update_git_diff_output_without_formulae_changes")
expect(hub.select_formula(:M)).to be_empty
expect(hub.select_formula(:A)).to be_empty
expect(hub.select_formula(:D)).to be_empty
end
specify "with Formula changes" do
perform_update("update_git_diff_output_with_formulae_changes")
expect(hub.select_formula(:M)).to eq(%w[xar yajl])
expect(hub.select_formula(:A)).to eq(%w[antiword bash-completion ddrescue dict lua])
end
specify "with removed Formulae" do
perform_update("update_git_diff_output_with_removed_formulae")
expect(hub.select_formula(:D)).to eq(%w[libgsasl])
end
specify "with changed file type" do
perform_update("update_git_diff_output_with_changed_filetype")
expect(hub.select_formula(:M)).to eq(%w[elixir])
expect(hub.select_formula(:A)).to eq(%w[libbson])
expect(hub.select_formula(:D)).to eq(%w[libgsasl])
end
specify "with renamed Formula" do
allow(tap).to receive(:formula_renames).and_return("cv" => "progress")
perform_update("update_git_diff_output_with_formula_rename")
expect(hub.select_formula(:A)).to be_empty
expect(hub.select_formula(:D)).to be_empty
expect(hub.select_formula(:R)).to eq([["cv", "progress"]])
end
context "when updating a Tap other than the core Tap" do
let(:tap) { Tap.new("foo", "bar") }
before(:each) do
(tap.path/"Formula").mkpath
end
after(:each) do
tap.path.parent.rmtree
end
specify "with restructured Tap" do
perform_update("update_git_diff_output_with_restructured_tap")
expect(hub.select_formula(:A)).to be_empty
expect(hub.select_formula(:D)).to be_empty
expect(hub.select_formula(:R)).to be_empty
end
specify "with renamed Formula and restructured Tap" do
allow(tap).to receive(:formula_renames).and_return("xchat" => "xchat2")
perform_update("update_git_diff_output_with_formula_rename_and_restructuring")
expect(hub.select_formula(:A)).to be_empty
expect(hub.select_formula(:D)).to be_empty
expect(hub.select_formula(:R)).to eq([%w[foo/bar/xchat foo/bar/xchat2]])
end
specify "with simulated 'homebrew/php' restructuring" do
perform_update("update_git_diff_simulate_homebrew_php_restructuring")
expect(hub.select_formula(:A)).to be_empty
expect(hub.select_formula(:D)).to be_empty
expect(hub.select_formula(:R)).to be_empty
end
specify "with Formula changes" do
perform_update("update_git_diff_output_with_tap_formulae_changes")
expect(hub.select_formula(:A)).to eq(%w[foo/bar/lua])
expect(hub.select_formula(:M)).to eq(%w[foo/bar/git])
expect(hub.select_formula(:D)).to be_empty
end
end
end

View File

@ -0,0 +1,12 @@
describe "brew upgrade", :integration_test do
it "upgrades a Formula to the latest version" do
setup_test_formula "testball"
(HOMEBREW_CELLAR/"testball/0.0.1/foo").mkpath
shutup do
expect { brew "upgrade" }.to be_a_success
end
expect(HOMEBREW_CELLAR/"testball/0.1").to be_a_directory
end
end

View File

@ -0,0 +1,25 @@
describe "brew uses", :integration_test do
it "prints the Formulae a given Formula is used by" do
setup_test_formula "foo"
setup_test_formula "bar"
setup_test_formula "baz", <<-EOS.undent
url "https://example.com/baz-1.0"
depends_on "bar"
EOS
expect { brew "uses", "baz" }
.to be_a_success
.and not_to_output.to_stdout
.and not_to_output.to_stderr
expect { brew "uses", "bar" }
.to output("baz\n").to_stdout
.and not_to_output.to_stderr
.and be_a_success
expect { brew "uses", "--recursive", "foo" }
.to output(/(bar\nbaz|baz\nbar)/).to_stdout
.and not_to_output.to_stderr
.and be_a_success
end
end

View File

@ -1,11 +0,0 @@
require "testing_env"
class IntegrationCommandTestCommand < IntegrationCommandTestCase
def test_command
assert_equal "#{HOMEBREW_LIBRARY_PATH}/cmd/info.rb",
cmd("command", "info")
assert_match "Unknown command",
cmd_fail("command", "I-don't-exist")
end
end

View File

@ -4,13 +4,6 @@ require "cmd/commands"
require "fileutils"
require "testing_env"
class IntegrationCommandTestCommands < IntegrationCommandTestCase
def test_commands
assert_match "Built-in commands",
cmd("commands")
end
end
class CommandsTests < Homebrew::TestCase
def setup
super

View File

@ -0,0 +1,122 @@
require "compilers"
require "software_spec"
describe CompilerSelector do
subject { described_class.new(software_spec, versions, compilers) }
let(:compilers) { [:clang, :gcc, :llvm, :gnu] }
let(:software_spec) { SoftwareSpec.new }
let(:cc) { :clang }
let(:versions) do
double(
gcc_4_0_build_version: Version::NULL,
gcc_build_version: Version.create("5666"),
llvm_build_version: Version::NULL,
clang_build_version: Version.create("425"),
)
end
before(:each) do
allow(versions).to receive(:non_apple_gcc_version) do |name|
case name
when "gcc-4.8" then Version.create("4.8.1")
when "gcc-4.7" then Version.create("4.7.1")
else Version::NULL
end
end
end
describe "#compiler" do
it "raises an error if no matching compiler can be found" do
software_spec.fails_with(:clang)
software_spec.fails_with(:llvm)
software_spec.fails_with(:gcc)
software_spec.fails_with(gcc: "4.8")
software_spec.fails_with(gcc: "4.7")
expect { subject.compiler }.to raise_error(CompilerSelectionError)
end
it "defaults to cc" do
expect(subject.compiler).to eq(cc)
end
it "returns gcc if it fails with clang" do
software_spec.fails_with(:clang)
expect(subject.compiler).to eq(:gcc)
end
it "returns clang if it fails with llvm" do
software_spec.fails_with(:llvm)
expect(subject.compiler).to eq(:clang)
end
it "returns clang if it fails with gcc" do
software_spec.fails_with(:gcc)
expect(subject.compiler).to eq(:clang)
end
it "returns clang if it fails with non-Apple gcc" do
software_spec.fails_with(gcc: "4.8")
expect(subject.compiler).to eq(:clang)
end
it "still returns gcc-4.8 if it fails with gcc without a specific version" do
software_spec.fails_with(:clang)
software_spec.fails_with(:gcc)
expect(subject.compiler).to eq("gcc-4.8")
end
it "returns gcc if it fails with clang and llvm" do
software_spec.fails_with(:clang)
software_spec.fails_with(:llvm)
expect(subject.compiler).to eq(:gcc)
end
it "returns clang if it fails with gcc and llvm" do
software_spec.fails_with(:gcc)
software_spec.fails_with(:llvm)
expect(subject.compiler).to eq(:clang)
end
example "returns gcc if it fails with a specific gcc version" do
software_spec.fails_with(:clang)
software_spec.fails_with(gcc: "4.8")
expect(subject.compiler).to eq(:gcc)
end
example "returns a lower version of gcc if it fails with the highest version" do
software_spec.fails_with(:clang)
software_spec.fails_with(:gcc)
software_spec.fails_with(:llvm)
software_spec.fails_with(gcc: "4.8")
expect(subject.compiler).to eq("gcc-4.7")
end
it "prefers gcc" do
software_spec.fails_with(:clang)
software_spec.fails_with(:gcc)
expect(subject.compiler).to eq("gcc-4.8")
end
it "raises an error when gcc is missing" do
allow(versions).to receive(:gcc_build_version).and_return(Version::NULL)
software_spec.fails_with(:clang)
software_spec.fails_with(:llvm)
software_spec.fails_with(gcc: "4.8")
software_spec.fails_with(gcc: "4.7")
expect { subject.compiler }.to raise_error(CompilerSelectionError)
end
it "raises an error when llvm and gcc are missing" do
allow(versions).to receive(:gcc_build_version).and_return(Version::NULL)
software_spec.fails_with(:clang)
software_spec.fails_with(gcc: "4.8")
software_spec.fails_with(gcc: "4.7")
expect { subject.compiler }.to raise_error(CompilerSelectionError)
end
end
end

View File

@ -1,117 +0,0 @@
require "testing_env"
require "compilers"
require "software_spec"
class CompilerSelectorTests < Homebrew::TestCase
class Double < SoftwareSpec
def <<(cc)
fails_with(cc)
self
end
end
class CompilerVersions
attr_accessor :gcc_4_0_build_version, :gcc_build_version,
:clang_build_version
def initialize
@gcc_4_0_build_version = Version::NULL
@gcc_build_version = Version.create("5666")
@llvm_build_version = Version::NULL
@clang_build_version = Version.create("425")
end
def non_apple_gcc_version(name)
case name
when "gcc-4.8" then Version.create("4.8.1")
when "gcc-4.7" then Version.create("4.7.1")
else Version::NULL
end
end
end
def setup
super
@f = Double.new
@cc = :clang
@versions = CompilerVersions.new
@selector = CompilerSelector.new(
@f, @versions, [:clang, :gcc, :llvm, :gnu]
)
end
def actual_cc
@selector.compiler
end
def test_all_compiler_failures
@f << :clang << :llvm << :gcc << { gcc: "4.8" } << { gcc: "4.7" }
assert_raises(CompilerSelectionError) { actual_cc }
end
def test_no_compiler_failures
assert_equal @cc, actual_cc
end
def test_fails_with_clang
@f << :clang
assert_equal :gcc, actual_cc
end
def test_fails_with_llvm
@f << :llvm
assert_equal :clang, actual_cc
end
def test_fails_with_gcc
@f << :gcc
assert_equal :clang, actual_cc
end
def test_fails_with_non_apple_gcc
@f << { gcc: "4.8" }
assert_equal :clang, actual_cc
end
def test_mixed_failures_1
@f << :clang << :gcc
assert_equal "gcc-4.8", actual_cc
end
def test_mixed_failures_2
@f << :clang << :llvm
assert_equal :gcc, actual_cc
end
def test_mixed_failures_3
@f << :gcc << :llvm
assert_equal :clang, actual_cc
end
def test_mixed_failures_4
@f << :clang << { gcc: "4.8" }
assert_equal :gcc, actual_cc
end
def test_mixed_failures_5
@f << :clang << :gcc << :llvm << { gcc: "4.8" }
assert_equal "gcc-4.7", actual_cc
end
def test_gcc_precedence
@f << :clang << :gcc
assert_equal "gcc-4.8", actual_cc
end
def test_missing_gcc
@versions.gcc_build_version = Version::NULL
@f << :clang << :llvm << { gcc: "4.8" } << { gcc: "4.7" }
assert_raises(CompilerSelectionError) { actual_cc }
end
def test_missing_llvm_and_gcc
@versions.gcc_build_version = Version::NULL
@f << :clang << { gcc: "4.8" } << { gcc: "4.7" }
assert_raises(CompilerSelectionError) { actual_cc }
end
end

Some files were not shown because too many files have changed in this diff Show More