aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNaoto Kaneko2017-02-27 14:23:53 +0900
committerNaoto Kaneko2017-02-27 14:23:53 +0900
commit928eaca26720fd38b07c1e7df3f9f567477d48db (patch)
treec08fd030cca960e74bab72b59ce057684e554334
parentccc9b2dc6dc27026673db3c8871c691be9541342 (diff)
parente3f4701f385c286a2cc72c5d07870cc9a6ce0bf4 (diff)
downloadbrew-928eaca26720fd38b07c1e7df3f9f567477d48db.tar.bz2
Merge branch 'master' into exclude-executable-metafiles
Added tests in keg_test and pathname_test was moved into keg_spec and pathname_spec.
-rw-r--r--Library/Homebrew/cmd/cleanup.rb2
-rw-r--r--Library/Homebrew/cmd/desc.rb7
-rw-r--r--Library/Homebrew/cmd/info.rb4
-rw-r--r--Library/Homebrew/cmd/irb.rb1
-rw-r--r--Library/Homebrew/cmd/outdated.rb2
-rw-r--r--Library/Homebrew/cmd/readall.rb2
-rw-r--r--Library/Homebrew/cmd/search.rb2
-rw-r--r--Library/Homebrew/cmd/tap-info.rb2
-rw-r--r--Library/Homebrew/cmd/unlink.rb2
-rw-r--r--Library/Homebrew/cmd/unpack.rb2
-rw-r--r--Library/Homebrew/cmd/uses.rb4
-rw-r--r--Library/Homebrew/compilers.rb11
-rw-r--r--Library/Homebrew/dev-cmd/audit.rb173
-rw-r--r--Library/Homebrew/dev-cmd/boneyard-formula-pr.rb2
-rw-r--r--Library/Homebrew/dev-cmd/bottle.rb3
-rw-r--r--Library/Homebrew/dev-cmd/bump-formula-pr.rb13
-rw-r--r--Library/Homebrew/dev-cmd/create.rb3
-rw-r--r--Library/Homebrew/dev-cmd/formula.rb2
-rw-r--r--Library/Homebrew/dev-cmd/linkage.rb2
-rw-r--r--Library/Homebrew/dev-cmd/mirror.rb2
-rw-r--r--Library/Homebrew/dev-cmd/pull.rb53
-rw-r--r--Library/Homebrew/dev-cmd/release-notes.rb6
-rw-r--r--Library/Homebrew/dev-cmd/tests.rb4
-rw-r--r--Library/Homebrew/dev-cmd/update-test.rb8
-rw-r--r--Library/Homebrew/extend/pathname.rb2
-rw-r--r--Library/Homebrew/formula.rb4
-rw-r--r--Library/Homebrew/formula_installer.rb22
-rw-r--r--Library/Homebrew/manpages/brew-cask.1.md49
-rw-r--r--Library/Homebrew/manpages/brew.1.md.erb4
-rw-r--r--Library/Homebrew/requirements/ruby_requirement.rb36
-rw-r--r--Library/Homebrew/system_config.rb24
-rw-r--r--Library/Homebrew/test/ARGV_spec.rb2
-rw-r--r--Library/Homebrew/test/ENV_spec.rb189
-rw-r--r--Library/Homebrew/test/ENV_test.rb202
-rw-r--r--Library/Homebrew/test/audit_test.rb50
-rw-r--r--Library/Homebrew/test/bottle_test.rb21
-rw-r--r--Library/Homebrew/test/build_options_spec.rb52
-rw-r--r--Library/Homebrew/test/build_options_test.rb50
-rw-r--r--Library/Homebrew/test/bundle_test.rb22
-rw-r--r--Library/Homebrew/test/cache_formula_test.rb8
-rw-r--r--Library/Homebrew/test/cache_test.rb8
-rw-r--r--Library/Homebrew/test/cask_test.rb10
-rw-r--r--Library/Homebrew/test/cat_test.rb8
-rw-r--r--Library/Homebrew/test/caveats_spec.rb29
-rw-r--r--Library/Homebrew/test/caveats_test.rb30
-rw-r--r--Library/Homebrew/test/cellar_formula_test.rb8
-rw-r--r--Library/Homebrew/test/cellar_test.rb8
-rw-r--r--Library/Homebrew/test/cleanup_test.rb7
-rw-r--r--Library/Homebrew/test/cmd/--cache_spec.rb15
-rw-r--r--Library/Homebrew/test/cmd/--cellar_spec.rb15
-rw-r--r--Library/Homebrew/test/cmd/--env_spec.rb44
-rw-r--r--Library/Homebrew/test/cmd/--prefix_spec.rb15
-rw-r--r--Library/Homebrew/test/cmd/--repository_spec.rb15
-rw-r--r--Library/Homebrew/test/cmd/--version_spec.rb8
-rw-r--r--Library/Homebrew/test/cmd/bundle_spec.rb24
-rw-r--r--Library/Homebrew/test/cmd/cask_spec.rb8
-rw-r--r--Library/Homebrew/test/cmd/cat_spec.rb11
-rw-r--r--Library/Homebrew/test/cmd/cleanup_spec.rb12
-rw-r--r--Library/Homebrew/test/cmd/command_spec.rb13
-rw-r--r--Library/Homebrew/test/cmd/commands_spec.rb7
-rw-r--r--Library/Homebrew/test/cmd/config_spec.rb8
-rw-r--r--Library/Homebrew/test/cmd/custom-external-command_spec.rb21
-rw-r--r--Library/Homebrew/test/cmd/desc_spec.rb40
-rw-r--r--Library/Homebrew/test/cmd/doctor_spec.rb6
-rw-r--r--Library/Homebrew/test/cmd/fetch_spec.rb13
-rw-r--r--Library/Homebrew/test/cmd/help_spec.rb47
-rw-r--r--Library/Homebrew/test/cmd/home_spec.rb17
-rw-r--r--Library/Homebrew/test/cmd/info_spec.rb30
-rw-r--r--Library/Homebrew/test/cmd/install_spec.rb243
-rw-r--r--Library/Homebrew/test/cmd/irb_spec.rb24
-rw-r--r--Library/Homebrew/test/cmd/leaves_spec.rb23
-rw-r--r--Library/Homebrew/test/cmd/link_spec.rb56
-rw-r--r--Library/Homebrew/test/cmd/linkapps_spec.rb24
-rw-r--r--Library/Homebrew/test/cmd/list_spec.rb14
-rw-r--r--Library/Homebrew/test/cmd/log_spec.rb41
-rw-r--r--Library/Homebrew/test/cmd/migrate_spec.rb46
-rw-r--r--Library/Homebrew/test/cmd/missing_spec.rb41
-rw-r--r--Library/Homebrew/test/cmd/options_spec.rb12
-rw-r--r--Library/Homebrew/test/cmd/outdated_spec.rb11
-rw-r--r--Library/Homebrew/test/cmd/pin_spec.rb13
-rw-r--r--Library/Homebrew/test/cmd/prune_spec.rb28
-rw-r--r--Library/Homebrew/test/cmd/readall_spec.rb20
-rw-r--r--Library/Homebrew/test/cmd/reinstall_spec.rb44
-rw-r--r--Library/Homebrew/test/cmd/search_spec.rb57
-rw-r--r--Library/Homebrew/test/cmd/services_spec.rb10
-rw-r--r--Library/Homebrew/test/cmd/sh_spec.rb8
-rw-r--r--Library/Homebrew/test/cmd/switch_spec.rb34
-rw-r--r--Library/Homebrew/test/cmd/tap-new_spec.rb10
-rw-r--r--Library/Homebrew/test/cmd/uninstall_spec.rb12
-rw-r--r--Library/Homebrew/test/cmd/unlink_spec.rb14
-rw-r--r--Library/Homebrew/test/cmd/unlinkapps_spec.rb24
-rw-r--r--Library/Homebrew/test/cmd/unpack_spec.rb16
-rw-r--r--Library/Homebrew/test/cmd/unpin_spec.rb14
-rw-r--r--Library/Homebrew/test/cmd/update-report_spec.rb127
-rw-r--r--Library/Homebrew/test/cmd/upgrade_spec.rb12
-rw-r--r--Library/Homebrew/test/cmd/uses_spec.rb25
-rw-r--r--Library/Homebrew/test/command_test.rb11
-rw-r--r--Library/Homebrew/test/commands_test.rb7
-rw-r--r--Library/Homebrew/test/compiler_selector_spec.rb122
-rw-r--r--Library/Homebrew/test/compiler_selector_test.rb117
-rw-r--r--Library/Homebrew/test/config_test.rb8
-rw-r--r--Library/Homebrew/test/create_test.rb12
-rw-r--r--Library/Homebrew/test/custom_command_test.rb18
-rw-r--r--Library/Homebrew/test/dependency_expansion_spec.rb136
-rw-r--r--Library/Homebrew/test/dependency_expansion_test.rb138
-rw-r--r--Library/Homebrew/test/deps_spec.rb31
-rw-r--r--Library/Homebrew/test/deps_test.rb16
-rw-r--r--Library/Homebrew/test/desc_test.rb17
-rw-r--r--Library/Homebrew/test/dev-cmd/bottle_spec.rb30
-rw-r--r--Library/Homebrew/test/dev-cmd/create_spec.rb13
-rw-r--r--Library/Homebrew/test/dev-cmd/edit_spec.rb16
-rw-r--r--Library/Homebrew/test/dev-cmd/formula_spec.rb10
-rw-r--r--Library/Homebrew/test/dev-cmd/pull_spec.rb60
-rw-r--r--Library/Homebrew/test/dev-cmd/tap_spec.rb75
-rw-r--r--Library/Homebrew/test/dev-cmd/test_spec.rb56
-rw-r--r--Library/Homebrew/test/doctor_test.rb8
-rw-r--r--Library/Homebrew/test/edit_test.rb11
-rw-r--r--Library/Homebrew/test/fetch_test.rb11
-rw-r--r--Library/Homebrew/test/formula_cmd_test.rb8
-rw-r--r--Library/Homebrew/test/formula_spec.rb1295
-rw-r--r--Library/Homebrew/test/formula_test.rb1205
-rw-r--r--Library/Homebrew/test/formulary_spec.rb8
-rw-r--r--Library/Homebrew/test/help_test.rb21
-rw-r--r--Library/Homebrew/test/home_test.rb12
-rw-r--r--Library/Homebrew/test/info_test.rb29
-rw-r--r--Library/Homebrew/test/inreplace_spec.rb251
-rw-r--r--Library/Homebrew/test/inreplace_test.rb119
-rw-r--r--Library/Homebrew/test/install_test.rb136
-rw-r--r--Library/Homebrew/test/irb_test.rb19
-rw-r--r--Library/Homebrew/test/java_requirement_spec.rb107
-rw-r--r--Library/Homebrew/test/java_requirement_test.rb50
-rw-r--r--Library/Homebrew/test/keg_spec.rb490
-rw-r--r--Library/Homebrew/test/keg_test.rb479
-rw-r--r--Library/Homebrew/test/leaves_test.rb15
-rw-r--r--Library/Homebrew/test/link_test.rb23
-rw-r--r--Library/Homebrew/test/linkapps_test.rb15
-rw-r--r--Library/Homebrew/test/list_test.rb13
-rw-r--r--Library/Homebrew/test/log_formula_test.rb27
-rw-r--r--Library/Homebrew/test/log_test.rb13
-rw-r--r--Library/Homebrew/test/migrate_test.rb18
-rw-r--r--Library/Homebrew/test/migrator_spec.rb264
-rw-r--r--Library/Homebrew/test/migrator_test.rb251
-rw-r--r--Library/Homebrew/test/missing_test.rb34
-rw-r--r--Library/Homebrew/test/options_spec.rb148
-rw-r--r--Library/Homebrew/test/options_test.rb160
-rw-r--r--Library/Homebrew/test/os/mac/bottle_tag_test.rb79
-rw-r--r--Library/Homebrew/test/os/mac/dependency_collector_spec.rb50
-rw-r--r--Library/Homebrew/test/os/mac/dependency_collector_test.rb59
-rw-r--r--Library/Homebrew/test/os/mac/diagnostic_spec.rb42
-rw-r--r--Library/Homebrew/test/os/mac/diagnostic_test.rb45
-rw-r--r--Library/Homebrew/test/outdated_test.rb10
-rw-r--r--Library/Homebrew/test/patching_spec.rb289
-rw-r--r--Library/Homebrew/test/patching_test.rb248
-rw-r--r--Library/Homebrew/test/pathname_spec.rb307
-rw-r--r--Library/Homebrew/test/pathname_test.rb268
-rw-r--r--Library/Homebrew/test/pin_unpin_test.rb18
-rw-r--r--Library/Homebrew/test/prefix_formula_test.rb8
-rw-r--r--Library/Homebrew/test/prefix_test.rb8
-rw-r--r--Library/Homebrew/test/prune_test.rb21
-rw-r--r--Library/Homebrew/test/pull_offline_test.rb10
-rw-r--r--Library/Homebrew/test/pull_test.rb27
-rw-r--r--Library/Homebrew/test/readall_test.rb12
-rw-r--r--Library/Homebrew/test/reinstall_pinned_test.rb15
-rw-r--r--Library/Homebrew/test/reinstall_test.rb24
-rw-r--r--Library/Homebrew/test/repository_test.rb10
-rw-r--r--Library/Homebrew/test/resource_spec.rb147
-rw-r--r--Library/Homebrew/test/resource_test.rb133
-rw-r--r--Library/Homebrew/test/search_test.rb30
-rw-r--r--Library/Homebrew/test/services_test.rb11
-rw-r--r--Library/Homebrew/test/sh_test.rb8
-rw-r--r--Library/Homebrew/test/spec_helper.rb8
-rw-r--r--Library/Homebrew/test/support/helper/formula.rb19
-rw-r--r--Library/Homebrew/test/support/helper/spec/shared_context/integration_test.rb82
-rw-r--r--Library/Homebrew/test/switch_test.rb20
-rw-r--r--Library/Homebrew/test/tab_spec.rb341
-rw-r--r--Library/Homebrew/test/tab_test.rb318
-rw-r--r--Library/Homebrew/test/tap_new_test.rb9
-rw-r--r--Library/Homebrew/test/tap_test.rb30
-rw-r--r--Library/Homebrew/test/test_formula_test.rb30
-rw-r--r--Library/Homebrew/test/uninstall_test.rb7
-rw-r--r--Library/Homebrew/test/unlink_test.rb10
-rw-r--r--Library/Homebrew/test/unlinkapps_test.rb19
-rw-r--r--Library/Homebrew/test/unpack_test.rb13
-rw-r--r--Library/Homebrew/test/update_report_test.rb135
-rw-r--r--Library/Homebrew/test/upgrade_test.rb12
-rw-r--r--Library/Homebrew/test/uses_test.rb16
-rw-r--r--Library/Homebrew/test/utils/bottles/bottles_spec.rb80
-rw-r--r--Library/Homebrew/test/utils_spec.rb8
-rw-r--r--Library/Homebrew/test/version_test.rb8
-rw-r--r--Library/Homebrew/utils.rb7
-rw-r--r--Library/Homebrew/utils/git.rb5
-rw-r--r--Library/Homebrew/utils/svn.rb11
-rw-r--r--README.md6
-rw-r--r--docs/Acceptable-Formulae.md4
-rw-r--r--docs/Brew-Test-Bot-For-Core-Contributors.md6
-rw-r--r--docs/Brew-Test-Bot.md6
-rw-r--r--docs/Common-Issues.md3
-rw-r--r--docs/External-Commands.md6
-rw-r--r--docs/FAQ.md5
-rw-r--r--docs/Formula-Cookbook.md6
-rw-r--r--docs/Gems,-Eggs-and-Perl-Modules.md2
-rw-r--r--docs/Homebrew-and-Python.md2
-rw-r--r--docs/How-To-Open-a-Homebrew-Pull-Request.md4
-rw-r--r--docs/Interesting-Taps-&-Forks.md2
-rw-r--r--docs/Node-for-Formula-Authors.md26
-rw-r--r--docs/Prose-Style-Guidelines.md4
-rw-r--r--docs/Python-for-Formula-Authors.md12
-rw-r--r--docs/Querying-Brew.md8
-rw-r--r--docs/Tips-N'-Tricks.md2
-rw-r--r--docs/Versions.md2
-rw-r--r--docs/brew-tap.md2
-rw-r--r--docs/brew.1.html136
-rw-r--r--manpages/brew-cask.1127
-rw-r--r--manpages/brew.1128
214 files changed, 6752 insertions, 5476 deletions
diff --git a/Library/Homebrew/cmd/cleanup.rb b/Library/Homebrew/cmd/cleanup.rb
index 5b46e0872..126309579 100644
--- a/Library/Homebrew/cmd/cleanup.rb
+++ b/Library/Homebrew/cmd/cleanup.rb
@@ -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)`
diff --git a/Library/Homebrew/cmd/desc.rb b/Library/Homebrew/cmd/desc.rb
index 3ef02288b..53291602e 100644
--- a/Library/Homebrew/cmd/desc.rb
+++ b/Library/Homebrew/cmd/desc.rb
@@ -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"
diff --git a/Library/Homebrew/cmd/info.rb b/Library/Homebrew/cmd/info.rb
index 1850ae003..b06d99466 100644
--- a/Library/Homebrew/cmd/info.rb
+++ b/Library/Homebrew/cmd/info.rb
@@ -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"
diff --git a/Library/Homebrew/cmd/irb.rb b/Library/Homebrew/cmd/irb.rb
index d162e3f4a..5561845e7 100644
--- a/Library/Homebrew/cmd/irb.rb
+++ b/Library/Homebrew/cmd/irb.rb
@@ -12,6 +12,7 @@ class Symbol
Formulary.factory(to_s, *args)
end
end
+
class String
def f(*args)
Formulary.factory(self, *args)
diff --git a/Library/Homebrew/cmd/outdated.rb b/Library/Homebrew/cmd/outdated.rb
index 9ed7a0f79..a18f4e399 100644
--- a/Library/Homebrew/cmd/outdated.rb
+++ b/Library/Homebrew/cmd/outdated.rb
@@ -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
diff --git a/Library/Homebrew/cmd/readall.rb b/Library/Homebrew/cmd/readall.rb
index 7c1a085c9..3591e0c09 100644
--- a/Library/Homebrew/cmd/readall.rb
+++ b/Library/Homebrew/cmd/readall.rb
@@ -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"
diff --git a/Library/Homebrew/cmd/search.rb b/Library/Homebrew/cmd/search.rb
index d69164eb9..e834a00b5 100644
--- a/Library/Homebrew/cmd/search.rb
+++ b/Library/Homebrew/cmd/search.rb
@@ -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.
diff --git a/Library/Homebrew/cmd/tap-info.rb b/Library/Homebrew/cmd/tap-info.rb
index b46de30c1..225b70097 100644
--- a/Library/Homebrew/cmd/tap-info.rb
+++ b/Library/Homebrew/cmd/tap-info.rb
@@ -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"
diff --git a/Library/Homebrew/cmd/unlink.rb b/Library/Homebrew/cmd/unlink.rb
index a105f9c56..3f858b2c4 100644
--- a/Library/Homebrew/cmd/unlink.rb
+++ b/Library/Homebrew/cmd/unlink.rb
@@ -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.
diff --git a/Library/Homebrew/cmd/unpack.rb b/Library/Homebrew/cmd/unpack.rb
index 4e6584e70..60d796d9f 100644
--- a/Library/Homebrew/cmd/unpack.rb
+++ b/Library/Homebrew/cmd/unpack.rb
@@ -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.
diff --git a/Library/Homebrew/cmd/uses.rb b/Library/Homebrew/cmd/uses.rb
index 5f6611dfc..b1122c90a 100644
--- a/Library/Homebrew/cmd/uses.rb
+++ b/Library/Homebrew/cmd/uses.rb
@@ -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"
diff --git a/Library/Homebrew/compilers.rb b/Library/Homebrew/compilers.rb
index 628e71e9b..36e50a177 100644
--- a/Library/Homebrew/compilers.rb
+++ b/Library/Homebrew/compilers.rb
@@ -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),
],
diff --git a/Library/Homebrew/dev-cmd/audit.rb b/Library/Homebrew/dev-cmd/audit.rb
index 9ffef0f99..a8c18f7b6 100644
--- a/Library/Homebrew/dev-cmd/audit.rb
+++ b/Library/Homebrew/dev-cmd/audit.rb
@@ -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"
- end
- status_code
+ 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
+
+ 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:"
- 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)
+ next if !@strict && mirrors.include?(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"
+ 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 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
diff --git a/Library/Homebrew/dev-cmd/boneyard-formula-pr.rb b/Library/Homebrew/dev-cmd/boneyard-formula-pr.rb
index 3066d2ee6..7531ef9cf 100644
--- a/Library/Homebrew/dev-cmd/boneyard-formula-pr.rb
+++ b/Library/Homebrew/dev-cmd/boneyard-formula-pr.rb
@@ -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.
diff --git a/Library/Homebrew/dev-cmd/bottle.rb b/Library/Homebrew/dev-cmd/bottle.rb
index 7367e5c37..91bdcba93 100644
--- a/Library/Homebrew/dev-cmd/bottle.rb
+++ b/Library/Homebrew/dev-cmd/bottle.rb
@@ -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`.
diff --git a/Library/Homebrew/dev-cmd/bump-formula-pr.rb b/Library/Homebrew/dev-cmd/bump-formula-pr.rb
index bfe9c7776..6c7b7d5b5 100644
--- a/Library/Homebrew/dev-cmd/bump-formula-pr.rb
+++ b/Library/Homebrew/dev-cmd/bump-formula-pr.rb
@@ -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.
diff --git a/Library/Homebrew/dev-cmd/create.rb b/Library/Homebrew/dev-cmd/create.rb
index b4cda0fad..9c58dc71a 100644
--- a/Library/Homebrew/dev-cmd/create.rb
+++ b/Library/Homebrew/dev-cmd/create.rb
@@ -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.
diff --git a/Library/Homebrew/dev-cmd/formula.rb b/Library/Homebrew/dev-cmd/formula.rb
index 71687dfa7..67d11edce 100644
--- a/Library/Homebrew/dev-cmd/formula.rb
+++ b/Library/Homebrew/dev-cmd/formula.rb
@@ -1,5 +1,5 @@
#: * `formula` <formula>:
-#: Display the path where <formula> is
+#: Display the path where <formula> is located.
require "formula"
diff --git a/Library/Homebrew/dev-cmd/linkage.rb b/Library/Homebrew/dev-cmd/linkage.rb
index 44e0f224e..e4da827f2 100644
--- a/Library/Homebrew/dev-cmd/linkage.rb
+++ b/Library/Homebrew/dev-cmd/linkage.rb
@@ -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
diff --git a/Library/Homebrew/dev-cmd/mirror.rb b/Library/Homebrew/dev-cmd/mirror.rb
index bd5868726..10811493c 100644
--- a/Library/Homebrew/dev-cmd/mirror.rb
+++ b/Library/Homebrew/dev-cmd/mirror.rb
@@ -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
diff --git a/Library/Homebrew/dev-cmd/pull.rb b/Library/Homebrew/dev-cmd/pull.rb
index c2342d39c..98a62e578 100644
--- a/Library/Homebrew/dev-cmd/pull.rb
+++ b/Library/Homebrew/dev-cmd/pull.rb
@@ -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"
diff --git a/Library/Homebrew/dev-cmd/release-notes.rb b/Library/Homebrew/dev-cmd/release-notes.rb
index 919243764..eb398fcfb 100644
--- a/Library/Homebrew/dev-cmd/release-notes.rb
+++ b/Library/Homebrew/dev-cmd/release-notes.rb
@@ -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.
diff --git a/Library/Homebrew/dev-cmd/tests.rb b/Library/Homebrew/dev-cmd/tests.rb
index 9cabb3d61..0c8621a01 100644
--- a/Library/Homebrew/dev-cmd/tests.rb
+++ b/Library/Homebrew/dev-cmd/tests.rb
@@ -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?
diff --git a/Library/Homebrew/dev-cmd/update-test.rb b/Library/Homebrew/dev-cmd/update-test.rb
index 3b8dc11f9..9704426dd 100644
--- a/Library/Homebrew/dev-cmd/update-test.rb
+++ b/Library/Homebrew/dev-cmd/update-test.rb
@@ -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
diff --git a/Library/Homebrew/extend/pathname.rb b/Library/Homebrew/extend/pathname.rb
index 12dca4320..eb254c624 100644
--- a/Library/Homebrew/extend/pathname.rb
+++ b/Library/Homebrew/extend/pathname.rb
@@ -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
diff --git a/Library/Homebrew/formula.rb b/Library/Homebrew/formula.rb
index 35bf52584..443619206 100644
--- a/Library/Homebrew/formula.rb
+++ b/Library/Homebrew/formula.rb
@@ -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
diff --git a/Library/Homebrew/formula_installer.rb b/Library/Homebrew/formula_installer.rb
index c9f478bb1..1f91ad5c4 100644
--- a/Library/Homebrew/formula_installer.rb
+++ b/Library/Homebrew/formula_installer.rb
@@ -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
diff --git a/Library/Homebrew/manpages/brew-cask.1.md b/Library/Homebrew/manpages/brew-cask.1.md
index a9da5bca6..e882f09d1 100644
--- a/Library/Homebrew/manpages/brew-cask.1.md
+++ b/Library/Homebrew/manpages/brew-cask.1.md
@@ -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, don’t
+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
diff --git a/Library/Homebrew/manpages/brew.1.md.erb b/Library/Homebrew/manpages/brew.1.md.erb
index a7f099e9d..05fc1cb23 100644
--- a/Library/Homebrew/manpages/brew.1.md.erb
+++ b/Library/Homebrew/manpages/brew.1.md.erb
@@ -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`:
diff --git a/Library/Homebrew/requirements/ruby_requirement.rb b/Library/Homebrew/requirements/ruby_requirement.rb
index a890435a5..327c13170 100644
--- a/Library/Homebrew/requirements/ruby_requirement.rb
+++ b/Library/Homebrew/requirements/ruby_requirement.rb
@@ -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
diff --git a/Library/Homebrew/system_config.rb b/Library/Homebrew/system_config.rb
index 043f60919..56826f62d 100644
--- a/Library/Homebrew/system_config.rb
+++ b/Library/Homebrew/system_config.rb
@@ -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
diff --git a/Library/Homebrew/test/ARGV_spec.rb b/Library/Homebrew/test/ARGV_spec.rb
index bcb7c3f70..89ef9cabc 100644
--- a/Library/Homebrew/test/ARGV_spec.rb
+++ b/Library/Homebrew/test/ARGV_spec.rb
@@ -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
diff --git a/Library/Homebrew/test/ENV_spec.rb b/Library/Homebrew/test/ENV_spec.rb
new file mode 100644
index 000000000..7b50ca1d4
--- /dev/null
+++ b/Library/Homebrew/test/ENV_spec.rb
@@ -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
diff --git a/Library/Homebrew/test/ENV_test.rb b/Library/Homebrew/test/ENV_test.rb
deleted file mode 100644
index cbfd01e25..000000000
--- a/Library/Homebrew/test/ENV_test.rb
+++ /dev/null
@@ -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
diff --git a/Library/Homebrew/test/audit_test.rb b/Library/Homebrew/test/audit_test.rb
index 9165edef1..66e5af567 100644
--- a/Library/Homebrew/test/audit_test.rb
+++ b/Library/Homebrew/test/audit_test.rb
@@ -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
diff --git a/Library/Homebrew/test/bottle_test.rb b/Library/Homebrew/test/bottle_test.rb
deleted file mode 100644
index 7981ccf79..000000000
--- a/Library/Homebrew/test/bottle_test.rb
+++ /dev/null
@@ -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
diff --git a/Library/Homebrew/test/build_options_spec.rb b/Library/Homebrew/test/build_options_spec.rb
new file mode 100644
index 000000000..5acc12f30
--- /dev/null
+++ b/Library/Homebrew/test/build_options_spec.rb
@@ -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
diff --git a/Library/Homebrew/test/build_options_test.rb b/Library/Homebrew/test/build_options_test.rb
deleted file mode 100644
index 05e7ccd94..000000000
--- a/Library/Homebrew/test/build_options_test.rb
+++ /dev/null
@@ -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
diff --git a/Library/Homebrew/test/bundle_test.rb b/Library/Homebrew/test/bundle_test.rb
deleted file mode 100644
index ae47977d8..000000000
--- a/Library/Homebrew/test/bundle_test.rb
+++ /dev/null
@@ -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
diff --git a/Library/Homebrew/test/cache_formula_test.rb b/Library/Homebrew/test/cache_formula_test.rb
deleted file mode 100644
index 6dcb6a745..000000000
--- a/Library/Homebrew/test/cache_formula_test.rb
+++ /dev/null
@@ -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
diff --git a/Library/Homebrew/test/cache_test.rb b/Library/Homebrew/test/cache_test.rb
deleted file mode 100644
index 3a9e6b011..000000000
--- a/Library/Homebrew/test/cache_test.rb
+++ /dev/null
@@ -1,8 +0,0 @@
-require "testing_env"
-
-class IntegrationCommandTestCache < IntegrationCommandTestCase
- def test_cache
- assert_equal HOMEBREW_CACHE.to_s,
- cmd("--cache")
- end
-end
diff --git a/Library/Homebrew/test/cask_test.rb b/Library/Homebrew/test/cask_test.rb
deleted file mode 100644
index d5b81facb..000000000
--- a/Library/Homebrew/test/cask_test.rb
+++ /dev/null
@@ -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
diff --git a/Library/Homebrew/test/cat_test.rb b/Library/Homebrew/test/cat_test.rb
deleted file mode 100644
index bb37b5fde..000000000
--- a/Library/Homebrew/test/cat_test.rb
+++ /dev/null
@@ -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
diff --git a/Library/Homebrew/test/caveats_spec.rb b/Library/Homebrew/test/caveats_spec.rb
new file mode 100644
index 000000000..d8be9dc52
--- /dev/null
+++ b/Library/Homebrew/test/caveats_spec.rb
@@ -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
diff --git a/Library/Homebrew/test/caveats_test.rb b/Library/Homebrew/test/caveats_test.rb
deleted file mode 100644
index 3a582b907..000000000
--- a/Library/Homebrew/test/caveats_test.rb
+++ /dev/null
@@ -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
diff --git a/Library/Homebrew/test/cellar_formula_test.rb b/Library/Homebrew/test/cellar_formula_test.rb
deleted file mode 100644
index 38a934a7b..000000000
--- a/Library/Homebrew/test/cellar_formula_test.rb
+++ /dev/null
@@ -1,8 +0,0 @@
-require "testing_env"
-
-class IntegrationCommandTestCellarFormula < IntegrationCommandTestCase
- def test_cellar_formula
- assert_match "#{HOMEBREW_CELLAR}/testball",
- cmd("--cellar", testball)
- end
-end
diff --git a/Library/Homebrew/test/cellar_test.rb b/Library/Homebrew/test/cellar_test.rb
deleted file mode 100644
index 74d5389f8..000000000
--- a/Library/Homebrew/test/cellar_test.rb
+++ /dev/null
@@ -1,8 +0,0 @@
-require "testing_env"
-
-class IntegrationCommandTestCellar < IntegrationCommandTestCase
- def test_cellar
- assert_equal HOMEBREW_CELLAR.to_s,
- cmd("--cellar")
- end
-end
diff --git a/Library/Homebrew/test/cleanup_test.rb b/Library/Homebrew/test/cleanup_test.rb
index e6fc31dfe..bc7a6713c 100644
--- a/Library/Homebrew/test/cleanup_test.rb
+++ b/Library/Homebrew/test/cleanup_test.rb
@@ -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
diff --git a/Library/Homebrew/test/cmd/--cache_spec.rb b/Library/Homebrew/test/cmd/--cache_spec.rb
new file mode 100644
index 000000000..fb3c9cee6
--- /dev/null
+++ b/Library/Homebrew/test/cmd/--cache_spec.rb
@@ -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
diff --git a/Library/Homebrew/test/cmd/--cellar_spec.rb b/Library/Homebrew/test/cmd/--cellar_spec.rb
new file mode 100644
index 000000000..6c8d7dea6
--- /dev/null
+++ b/Library/Homebrew/test/cmd/--cellar_spec.rb
@@ -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
diff --git a/Library/Homebrew/test/cmd/--env_spec.rb b/Library/Homebrew/test/cmd/--env_spec.rb
new file mode 100644
index 000000000..7dd84132a
--- /dev/null
+++ b/Library/Homebrew/test/cmd/--env_spec.rb
@@ -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
diff --git a/Library/Homebrew/test/cmd/--prefix_spec.rb b/Library/Homebrew/test/cmd/--prefix_spec.rb
new file mode 100644
index 000000000..80ef73a97
--- /dev/null
+++ b/Library/Homebrew/test/cmd/--prefix_spec.rb
@@ -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
diff --git a/Library/Homebrew/test/cmd/--repository_spec.rb b/Library/Homebrew/test/cmd/--repository_spec.rb
new file mode 100644
index 000000000..d3e531f7b
--- /dev/null
+++ b/Library/Homebrew/test/cmd/--repository_spec.rb
@@ -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
diff --git a/Library/Homebrew/test/cmd/--version_spec.rb b/Library/Homebrew/test/cmd/--version_spec.rb
new file mode 100644
index 000000000..8992629d7
--- /dev/null
+++ b/Library/Homebrew/test/cmd/--version_spec.rb
@@ -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
diff --git a/Library/Homebrew/test/cmd/bundle_spec.rb b/Library/Homebrew/test/cmd/bundle_spec.rb
new file mode 100644
index 000000000..755f9ab3d
--- /dev/null
+++ b/Library/Homebrew/test/cmd/bundle_spec.rb
@@ -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
diff --git a/Library/Homebrew/test/cmd/cask_spec.rb b/Library/Homebrew/test/cmd/cask_spec.rb
new file mode 100644
index 000000000..e46843cab
--- /dev/null
+++ b/Library/Homebrew/test/cmd/cask_spec.rb
@@ -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
diff --git a/Library/Homebrew/test/cmd/cat_spec.rb b/Library/Homebrew/test/cmd/cat_spec.rb
new file mode 100644
index 000000000..8c230abee
--- /dev/null
+++ b/Library/Homebrew/test/cmd/cat_spec.rb
@@ -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
diff --git a/Library/Homebrew/test/cmd/cleanup_spec.rb b/Library/Homebrew/test/cmd/cleanup_spec.rb
new file mode 100644
index 000000000..9e2cf493f
--- /dev/null
+++ b/Library/Homebrew/test/cmd/cleanup_spec.rb
@@ -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
diff --git a/Library/Homebrew/test/cmd/command_spec.rb b/Library/Homebrew/test/cmd/command_spec.rb
new file mode 100644
index 000000000..5d6a67b70
--- /dev/null
+++ b/Library/Homebrew/test/cmd/command_spec.rb
@@ -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
diff --git a/Library/Homebrew/test/cmd/commands_spec.rb b/Library/Homebrew/test/cmd/commands_spec.rb
new file mode 100644
index 000000000..f42072956
--- /dev/null
+++ b/Library/Homebrew/test/cmd/commands_spec.rb
@@ -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
diff --git a/Library/Homebrew/test/cmd/config_spec.rb b/Library/Homebrew/test/cmd/config_spec.rb
new file mode 100644
index 000000000..7687fcdc7
--- /dev/null
+++ b/Library/Homebrew/test/cmd/config_spec.rb
@@ -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
diff --git a/Library/Homebrew/test/cmd/custom-external-command_spec.rb b/Library/Homebrew/test/cmd/custom-external-command_spec.rb
new file mode 100644
index 000000000..8ccc21fa7
--- /dev/null
+++ b/Library/Homebrew/test/cmd/custom-external-command_spec.rb
@@ -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
diff --git a/Library/Homebrew/test/cmd/desc_spec.rb b/Library/Homebrew/test/cmd/desc_spec.rb
new file mode 100644
index 000000000..b09819d81
--- /dev/null
+++ b/Library/Homebrew/test/cmd/desc_spec.rb
@@ -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
diff --git a/Library/Homebrew/test/cmd/doctor_spec.rb b/Library/Homebrew/test/cmd/doctor_spec.rb
new file mode 100644
index 000000000..530adcd98
--- /dev/null
+++ b/Library/Homebrew/test/cmd/doctor_spec.rb
@@ -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
diff --git a/Library/Homebrew/test/cmd/fetch_spec.rb b/Library/Homebrew/test/cmd/fetch_spec.rb
new file mode 100644
index 000000000..111d9f85c
--- /dev/null
+++ b/Library/Homebrew/test/cmd/fetch_spec.rb
@@ -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
diff --git a/Library/Homebrew/test/cmd/help_spec.rb b/Library/Homebrew/test/cmd/help_spec.rb
new file mode 100644
index 000000000..6d94d7444
--- /dev/null
+++ b/Library/Homebrew/test/cmd/help_spec.rb
@@ -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
diff --git a/Library/Homebrew/test/cmd/home_spec.rb b/Library/Homebrew/test/cmd/home_spec.rb
new file mode 100644
index 000000000..5a4070492
--- /dev/null
+++ b/Library/Homebrew/test/cmd/home_spec.rb
@@ -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
diff --git a/Library/Homebrew/test/cmd/info_spec.rb b/Library/Homebrew/test/cmd/info_spec.rb
new file mode 100644
index 000000000..8deef3d23
--- /dev/null
+++ b/Library/Homebrew/test/cmd/info_spec.rb
@@ -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
diff --git a/Library/Homebrew/test/cmd/install_spec.rb b/Library/Homebrew/test/cmd/install_spec.rb
new file mode 100644
index 000000000..c1240a30e
--- /dev/null
+++ b/Library/Homebrew/test/cmd/install_spec.rb
@@ -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
diff --git a/Library/Homebrew/test/cmd/irb_spec.rb b/Library/Homebrew/test/cmd/irb_spec.rb
new file mode 100644
index 000000000..44410fabe
--- /dev/null
+++ b/Library/Homebrew/test/cmd/irb_spec.rb
@@ -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
diff --git a/Library/Homebrew/test/cmd/leaves_spec.rb b/Library/Homebrew/test/cmd/leaves_spec.rb
new file mode 100644
index 000000000..cd93d7e3d
--- /dev/null
+++ b/Library/Homebrew/test/cmd/leaves_spec.rb
@@ -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
diff --git a/Library/Homebrew/test/cmd/link_spec.rb b/Library/Homebrew/test/cmd/link_spec.rb
new file mode 100644
index 000000000..7b85c96dc
--- /dev/null
+++ b/Library/Homebrew/test/cmd/link_spec.rb
@@ -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
diff --git a/Library/Homebrew/test/cmd/linkapps_spec.rb b/Library/Homebrew/test/cmd/linkapps_spec.rb
new file mode 100644
index 000000000..42118a215
--- /dev/null
+++ b/Library/Homebrew/test/cmd/linkapps_spec.rb
@@ -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
diff --git a/Library/Homebrew/test/cmd/list_spec.rb b/Library/Homebrew/test/cmd/list_spec.rb
new file mode 100644
index 000000000..df7394d7b
--- /dev/null
+++ b/Library/Homebrew/test/cmd/list_spec.rb
@@ -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
diff --git a/Library/Homebrew/test/cmd/log_spec.rb b/Library/Homebrew/test/cmd/log_spec.rb
new file mode 100644
index 000000000..bdbca8912
--- /dev/null
+++ b/Library/Homebrew/test/cmd/log_spec.rb
@@ -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
diff --git a/Library/Homebrew/test/cmd/migrate_spec.rb b/Library/Homebrew/test/cmd/migrate_spec.rb
new file mode 100644
index 000000000..18c94fa01
--- /dev/null
+++ b/Library/Homebrew/test/cmd/migrate_spec.rb
@@ -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
diff --git a/Library/Homebrew/test/cmd/missing_spec.rb b/Library/Homebrew/test/cmd/missing_spec.rb
new file mode 100644
index 000000000..4668e72e0
--- /dev/null
+++ b/Library/Homebrew/test/cmd/missing_spec.rb
@@ -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
diff --git a/Library/Homebrew/test/cmd/options_spec.rb b/Library/Homebrew/test/cmd/options_spec.rb
new file mode 100644
index 000000000..33fe8b107
--- /dev/null
+++ b/Library/Homebrew/test/cmd/options_spec.rb
@@ -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
diff --git a/Library/Homebrew/test/cmd/outdated_spec.rb b/Library/Homebrew/test/cmd/outdated_spec.rb
new file mode 100644
index 000000000..2ce0825e8
--- /dev/null
+++ b/Library/Homebrew/test/cmd/outdated_spec.rb
@@ -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
diff --git a/Library/Homebrew/test/cmd/pin_spec.rb b/Library/Homebrew/test/cmd/pin_spec.rb
new file mode 100644
index 000000000..9ffc052c3
--- /dev/null
+++ b/Library/Homebrew/test/cmd/pin_spec.rb
@@ -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
diff --git a/Library/Homebrew/test/cmd/prune_spec.rb b/Library/Homebrew/test/cmd/prune_spec.rb
new file mode 100644
index 000000000..c5a9df70c
--- /dev/null
+++ b/Library/Homebrew/test/cmd/prune_spec.rb
@@ -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
diff --git a/Library/Homebrew/test/cmd/readall_spec.rb b/Library/Homebrew/test/cmd/readall_spec.rb
new file mode 100644
index 000000000..9165e0cb0
--- /dev/null
+++ b/Library/Homebrew/test/cmd/readall_spec.rb
@@ -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
diff --git a/Library/Homebrew/test/cmd/reinstall_spec.rb b/Library/Homebrew/test/cmd/reinstall_spec.rb
new file mode 100644
index 000000000..63584e6be
--- /dev/null
+++ b/Library/Homebrew/test/cmd/reinstall_spec.rb
@@ -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
diff --git a/Library/Homebrew/test/cmd/search_spec.rb b/Library/Homebrew/test/cmd/search_spec.rb
new file mode 100644
index 000000000..06b7073d8
--- /dev/null
+++ b/Library/Homebrew/test/cmd/search_spec.rb
@@ -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
diff --git a/Library/Homebrew/test/cmd/services_spec.rb b/Library/Homebrew/test/cmd/services_spec.rb
new file mode 100644
index 000000000..c456fea17
--- /dev/null
+++ b/Library/Homebrew/test/cmd/services_spec.rb
@@ -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
diff --git a/Library/Homebrew/test/cmd/sh_spec.rb b/Library/Homebrew/test/cmd/sh_spec.rb
new file mode 100644
index 000000000..5260ddb75
--- /dev/null
+++ b/Library/Homebrew/test/cmd/sh_spec.rb
@@ -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
diff --git a/Library/Homebrew/test/cmd/switch_spec.rb b/Library/Homebrew/test/cmd/switch_spec.rb
new file mode 100644
index 000000000..c27c96c14
--- /dev/null
+++ b/Library/Homebrew/test/cmd/switch_spec.rb
@@ -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
diff --git a/Library/Homebrew/test/cmd/tap-new_spec.rb b/Library/Homebrew/test/cmd/tap-new_spec.rb
new file mode 100644
index 000000000..ea4b8aa73
--- /dev/null
+++ b/Library/Homebrew/test/cmd/tap-new_spec.rb
@@ -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
diff --git a/Library/Homebrew/test/cmd/uninstall_spec.rb b/Library/Homebrew/test/cmd/uninstall_spec.rb
new file mode 100644
index 000000000..65f69e802
--- /dev/null
+++ b/Library/Homebrew/test/cmd/uninstall_spec.rb
@@ -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
diff --git a/Library/Homebrew/test/cmd/unlink_spec.rb b/Library/Homebrew/test/cmd/unlink_spec.rb
new file mode 100644
index 000000000..5961651fe
--- /dev/null
+++ b/Library/Homebrew/test/cmd/unlink_spec.rb
@@ -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
diff --git a/Library/Homebrew/test/cmd/unlinkapps_spec.rb b/Library/Homebrew/test/cmd/unlinkapps_spec.rb
new file mode 100644
index 000000000..1e21bd851
--- /dev/null
+++ b/Library/Homebrew/test/cmd/unlinkapps_spec.rb
@@ -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
diff --git a/Library/Homebrew/test/cmd/unpack_spec.rb b/Library/Homebrew/test/cmd/unpack_spec.rb
new file mode 100644
index 000000000..244fc0852
--- /dev/null
+++ b/Library/Homebrew/test/cmd/unpack_spec.rb
@@ -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
diff --git a/Library/Homebrew/test/cmd/unpin_spec.rb b/Library/Homebrew/test/cmd/unpin_spec.rb
new file mode 100644
index 000000000..4f14626d8
--- /dev/null
+++ b/Library/Homebrew/test/cmd/unpin_spec.rb
@@ -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
diff --git a/Library/Homebrew/test/cmd/update-report_spec.rb b/Library/Homebrew/test/cmd/update-report_spec.rb
new file mode 100644
index 000000000..3665e3c78
--- /dev/null
+++ b/Library/Homebrew/test/cmd/update-report_spec.rb
@@ -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
diff --git a/Library/Homebrew/test/cmd/upgrade_spec.rb b/Library/Homebrew/test/cmd/upgrade_spec.rb
new file mode 100644
index 000000000..84f5c09f4
--- /dev/null
+++ b/Library/Homebrew/test/cmd/upgrade_spec.rb
@@ -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
diff --git a/Library/Homebrew/test/cmd/uses_spec.rb b/Library/Homebrew/test/cmd/uses_spec.rb
new file mode 100644
index 000000000..2a6f48cb7
--- /dev/null
+++ b/Library/Homebrew/test/cmd/uses_spec.rb
@@ -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
diff --git a/Library/Homebrew/test/command_test.rb b/Library/Homebrew/test/command_test.rb
deleted file mode 100644
index d5c7aaa88..000000000
--- a/Library/Homebrew/test/command_test.rb
+++ /dev/null
@@ -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
diff --git a/Library/Homebrew/test/commands_test.rb b/Library/Homebrew/test/commands_test.rb
index 5f5dc9586..da88ee2d5 100644
--- a/Library/Homebrew/test/commands_test.rb
+++ b/Library/Homebrew/test/commands_test.rb
@@ -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
diff --git a/Library/Homebrew/test/compiler_selector_spec.rb b/Library/Homebrew/test/compiler_selector_spec.rb
new file mode 100644
index 000000000..0f6f6b5f2
--- /dev/null
+++ b/Library/Homebrew/test/compiler_selector_spec.rb
@@ -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
diff --git a/Library/Homebrew/test/compiler_selector_test.rb b/Library/Homebrew/test/compiler_selector_test.rb
deleted file mode 100644
index aa1a6f97e..000000000
--- a/Library/Homebrew/test/compiler_selector_test.rb
+++ /dev/null
@@ -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
diff --git a/Library/Homebrew/test/config_test.rb b/Library/Homebrew/test/config_test.rb
deleted file mode 100644
index 81da4660a..000000000
--- a/Library/Homebrew/test/config_test.rb
+++ /dev/null
@@ -1,8 +0,0 @@
-require "testing_env"
-
-class IntegrationCommandTestConfig < IntegrationCommandTestCase
- def test_config
- assert_match "HOMEBREW_VERSION: #{HOMEBREW_VERSION}",
- cmd("config")
- end
-end
diff --git a/Library/Homebrew/test/create_test.rb b/Library/Homebrew/test/create_test.rb
deleted file mode 100644
index aeee428aa..000000000
--- a/Library/Homebrew/test/create_test.rb
+++ /dev/null
@@ -1,12 +0,0 @@
-require "testing_env"
-
-class IntegrationCommandTestCreate < IntegrationCommandTestCase
- def test_create
- url = "file://#{TEST_FIXTURE_DIR}/tarballs/testball-0.1.tbz"
- cmd("create", url, "HOMEBREW_EDITOR" => "/bin/cat")
-
- formula_file = CoreTap.new.formula_dir/"testball.rb"
- assert formula_file.exist?, "The formula source should have been created"
- assert_match %Q(sha256 "#{TESTBALL_SHA256}"), formula_file.read
- end
-end
diff --git a/Library/Homebrew/test/custom_command_test.rb b/Library/Homebrew/test/custom_command_test.rb
deleted file mode 100644
index 8d05bc6c7..000000000
--- a/Library/Homebrew/test/custom_command_test.rb
+++ /dev/null
@@ -1,18 +0,0 @@
-require "testing_env"
-
-class IntegrationCommandTestCustomCommand < IntegrationCommandTestCase
- def test_custom_command
- mktmpdir do |path|
- cmd = "int-test-#{rand}"
- file = "#{path}/brew-#{cmd}"
-
- File.open(file, "w") do |f|
- f.write "#!/bin/sh\necho 'I am #{cmd}'\n"
- end
- FileUtils.chmod 0777, file
-
- assert_match "I am #{cmd}",
- cmd(cmd, "PATH" => "#{path}#{File::PATH_SEPARATOR}#{ENV["PATH"]}")
- end
- end
-end
diff --git a/Library/Homebrew/test/dependency_expansion_spec.rb b/Library/Homebrew/test/dependency_expansion_spec.rb
new file mode 100644
index 000000000..f955237a9
--- /dev/null
+++ b/Library/Homebrew/test/dependency_expansion_spec.rb
@@ -0,0 +1,136 @@
+require "dependency"
+
+describe Dependency do
+ def build_dep(name, tags = [], deps = [])
+ dep = described_class.new(name.to_s, tags)
+ allow(dep).to receive(:to_formula).and_return(double(deps: deps, name: name))
+ dep
+ end
+
+ let(:foo) { build_dep(:foo) }
+ let(:bar) { build_dep(:bar) }
+ let(:baz) { build_dep(:baz) }
+ let(:qux) { build_dep(:qux) }
+ let(:deps) { [foo, bar, baz, qux] }
+ let(:formula) { double(deps: deps, name: "f") }
+
+ describe "::expand" do
+ it "yields dependent and dependency pairs" do
+ i = 0
+ described_class.expand(formula) do |dependent, dep|
+ expect(dependent).to eq(formula)
+ expect(deps[i]).to eq(dep)
+ i += 1
+ end
+ end
+
+ it "returns the dependencies" do
+ expect(described_class.expand(formula)).to eq(deps)
+ end
+
+ it "prunes all when given a block with ::prune" do
+ expect(described_class.expand(formula) { described_class.prune }).to be_empty
+ end
+
+ it "can prune selectively" do
+ deps = described_class.expand(formula) do |_, dep|
+ described_class.prune if dep.name == "foo"
+ end
+
+ expect(deps).to eq([bar, baz, qux])
+ end
+
+ it "preserves dependency order" do
+ allow(foo).to receive(:to_formula).and_return(double(name: "f", deps: [qux, baz]))
+ expect(described_class.expand(formula)).to eq([qux, baz, foo, bar])
+ end
+ end
+
+ it "skips optionals by default" do
+ deps = [build_dep(:foo, [:optional]), bar, baz, qux]
+ f = double(deps: deps, build: double(with?: false), name: "f")
+ expect(described_class.expand(f)).to eq([bar, baz, qux])
+ end
+
+ it "keeps recommended dependencies by default" do
+ deps = [build_dep(:foo, [:recommended]), bar, baz, qux]
+ f = double(deps: deps, build: double(with?: true), name: "f")
+ expect(described_class.expand(f)).to eq(deps)
+ end
+
+ it "merges repeated dependencies with differing options" do
+ foo2 = build_dep(:foo, ["option"])
+ baz2 = build_dep(:baz, ["option"])
+ deps << foo2 << baz2
+ deps = [foo2, bar, baz2, qux]
+ deps.zip(described_class.expand(formula)) do |expected, actual|
+ expect(expected.tags).to eq(actual.tags)
+ expect(expected).to eq(actual)
+ end
+ end
+
+ it "merges dependencies and perserves env_proc" do
+ env_proc = double
+ dep = described_class.new("foo", [], env_proc)
+ allow(dep).to receive(:to_formula).and_return(double(deps: [], name: "foo"))
+ deps.replace([dep])
+ expect(described_class.expand(formula).first.env_proc).to eq(env_proc)
+ end
+
+ it "merges tags without duplicating them" do
+ foo2 = build_dep(:foo, ["option"])
+ foo3 = build_dep(:foo, ["option"])
+ deps << foo2 << foo3
+
+ expect(described_class.expand(formula).first.tags).to eq(%w[option])
+ end
+
+ it "skips parent but yields children with ::skip" do
+ f = double(
+ name: "f",
+ deps: [
+ build_dep(:foo, [], [bar, baz]),
+ build_dep(:foo, [], [baz]),
+ ],
+ )
+
+ deps = described_class.expand(f) do |_dependent, dep|
+ described_class.skip if %w[foo qux].include? dep.name
+ end
+
+ expect(deps).to eq([bar, baz])
+ end
+
+ it "keeps dependency but prunes recursive dependencies with ::keep_but_prune_recursive_deps" do
+ foo = build_dep(:foo, [:build], bar)
+ baz = build_dep(:baz, [:build])
+ f = double(name: "f", deps: [foo, baz])
+
+ deps = described_class.expand(f) do |_dependent, dep|
+ described_class.keep_but_prune_recursive_deps if dep.build?
+ end
+
+ expect(deps).to eq([foo, baz])
+ end
+
+ it "returns only the dependencies given as a collection as second argument" do
+ expect(formula.deps).to eq([foo, bar, baz, qux])
+ expect(described_class.expand(formula, [bar, baz])).to eq([bar, baz])
+ end
+
+ it "doesn't raise an error when a dependency is cyclic" do
+ foo = build_dep(:foo)
+ bar = build_dep(:bar, [], [foo])
+ allow(foo).to receive(:to_formula).and_return(double(deps: [bar], name: foo.name))
+ f = double(name: "f", deps: [foo, bar])
+ expect { described_class.expand(f) }.not_to raise_error
+ end
+
+ it "cleans the expand stack" do
+ foo = build_dep(:foo)
+ allow(foo).to receive(:to_formula).and_raise(FormulaUnavailableError, foo.name)
+ f = double(name: "f", deps: [foo])
+ expect { described_class.expand(f) }.to raise_error(FormulaUnavailableError)
+ expect(described_class.instance_variable_get(:@expand_stack)).to be_empty
+ end
+end
diff --git a/Library/Homebrew/test/dependency_expansion_test.rb b/Library/Homebrew/test/dependency_expansion_test.rb
deleted file mode 100644
index 58a731121..000000000
--- a/Library/Homebrew/test/dependency_expansion_test.rb
+++ /dev/null
@@ -1,138 +0,0 @@
-require "testing_env"
-require "dependency"
-
-class DependencyExpansionTests < Homebrew::TestCase
- def build_dep(name, tags = [], deps = [])
- dep = Dependency.new(name.to_s, tags)
- dep.stubs(:to_formula).returns(stub(deps: deps, name: name))
- dep
- end
-
- def setup
- super
- @foo = build_dep(:foo)
- @bar = build_dep(:bar)
- @baz = build_dep(:baz)
- @qux = build_dep(:qux)
- @deps = [@foo, @bar, @baz, @qux]
- @f = stub(deps: @deps, name: "f")
- end
-
- def test_expand_yields_dependent_and_dep_pairs
- i = 0
- Dependency.expand(@f) do |dependent, dep|
- assert_equal @f, dependent
- assert_equal dep, @deps[i]
- i += 1
- end
- end
-
- def test_expand_no_block
- assert_equal @deps, Dependency.expand(@f)
- end
-
- def test_expand_prune_all
- assert_empty Dependency.expand(@f) { Dependency.prune }
- end
-
- def test_expand_selective_pruning
- deps = Dependency.expand(@f) do |_, dep|
- Dependency.prune if dep.name == "foo"
- end
-
- assert_equal [@bar, @baz, @qux], deps
- end
-
- def test_expand_preserves_dependency_order
- @foo.stubs(:to_formula).returns(stub(name: "f", deps: [@qux, @baz]))
- assert_equal [@qux, @baz, @foo, @bar], Dependency.expand(@f)
- end
-
- def test_expand_skips_optionals_by_default
- deps = [build_dep(:foo, [:optional]), @bar, @baz, @qux]
- f = stub(deps: deps, build: stub(with?: false), name: "f")
- assert_equal [@bar, @baz, @qux], Dependency.expand(f)
- end
-
- def test_expand_keeps_recommendeds_by_default
- deps = [build_dep(:foo, [:recommended]), @bar, @baz, @qux]
- f = stub(deps: deps, build: stub(with?: true), name: "f")
- assert_equal deps, Dependency.expand(f)
- end
-
- def test_merges_repeated_deps_with_differing_options
- @foo2 = build_dep(:foo, ["option"])
- @baz2 = build_dep(:baz, ["option"])
- @deps << @foo2 << @baz2
- deps = [@foo2, @bar, @baz2, @qux]
- deps.zip(Dependency.expand(@f)) do |expected, actual|
- assert_equal expected.tags, actual.tags
- assert_equal expected, actual
- end
- end
-
- def test_merger_preserves_env_proc
- env_proc = stub
- dep = Dependency.new("foo", [], env_proc)
- dep.stubs(:to_formula).returns(stub(deps: [], name: "foo"))
- @deps.replace [dep]
- assert_equal env_proc, Dependency.expand(@f).first.env_proc
- end
-
- def test_merged_tags_no_dupes
- @foo2 = build_dep(:foo, ["option"])
- @foo3 = build_dep(:foo, ["option"])
- @deps << @foo2 << @foo3
-
- assert_equal %w[option], Dependency.expand(@f).first.tags
- end
-
- def test_skip_skips_parent_but_yields_children
- f = stub(
- name: "f",
- deps: [
- build_dep(:foo, [], [@bar, @baz]),
- build_dep(:foo, [], [@baz]),
- ],
- )
-
- deps = Dependency.expand(f) do |_dependent, dep|
- Dependency.skip if %w[foo qux].include? dep.name
- end
-
- assert_equal [@bar, @baz], deps
- end
-
- def test_keep_dep_but_prune_recursive_deps
- foo = build_dep(:foo, [:build], @bar)
- baz = build_dep(:baz, [:build])
- f = stub(name: "f", deps: [foo, baz])
-
- deps = Dependency.expand(f) do |_dependent, dep|
- Dependency.keep_but_prune_recursive_deps if dep.build?
- end
-
- assert_equal [foo, baz], deps
- end
-
- def test_deps_with_collection_argument
- assert_equal [@foo, @bar, @baz, @qux], @f.deps
- assert_equal [@bar, @baz], Dependency.expand(@f, [@bar, @baz])
- end
-
- def test_cyclic_dependency
- foo = build_dep(:foo)
- bar = build_dep(:bar, [], [foo])
- foo.stubs(:to_formula).returns(stub(deps: [bar], name: "foo"))
- f = stub(name: "f", deps: [foo, bar])
- assert_nothing_raised { Dependency.expand(f) }
- end
-
- def test_clean_expand_stack
- foo = build_dep(:foo)
- foo.stubs(:to_formula).raises(FormulaUnavailableError, "foo")
- f = stub(name: "f", deps: [foo])
- assert_raises(FormulaUnavailableError) { Dependency.expand(f) }
- assert_empty Dependency.instance_variable_get(:@expand_stack)
- end
-end
diff --git a/Library/Homebrew/test/deps_spec.rb b/Library/Homebrew/test/deps_spec.rb
new file mode 100644
index 000000000..4c892c93d
--- /dev/null
+++ b/Library/Homebrew/test/deps_spec.rb
@@ -0,0 +1,31 @@
+describe "brew deps", :integration_test do
+ before(:each) 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
+ end
+
+ it "outputs no dependencies for a Formula that has no dependencies" do
+ expect { brew "deps", "foo" }
+ .to be_a_success
+ .and not_to_output.to_stdout
+ .and not_to_output.to_stderr
+ end
+
+ it "outputs a dependency for a Formula that has one dependency" do
+ expect { brew "deps", "bar" }
+ .to be_a_success
+ .and output("foo\n").to_stdout
+ .and not_to_output.to_stderr
+ end
+
+ it "outputs all of a Formula's dependencies and their dependencies on separate lines" do
+ expect { brew "deps", "baz" }
+ .to be_a_success
+ .and output("bar\nfoo\n").to_stdout
+ .and not_to_output.to_stderr
+ end
+end
diff --git a/Library/Homebrew/test/deps_test.rb b/Library/Homebrew/test/deps_test.rb
deleted file mode 100644
index 01639857c..000000000
--- a/Library/Homebrew/test/deps_test.rb
+++ /dev/null
@@ -1,16 +0,0 @@
-require "testing_env"
-
-class IntegrationCommandTestDeps < IntegrationCommandTestCase
- def test_deps
- 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
-
- assert_equal "", cmd("deps", "foo")
- assert_equal "foo", cmd("deps", "bar")
- assert_equal "bar\nfoo", cmd("deps", "baz")
- end
-end
diff --git a/Library/Homebrew/test/desc_test.rb b/Library/Homebrew/test/desc_test.rb
deleted file mode 100644
index 2ba498135..000000000
--- a/Library/Homebrew/test/desc_test.rb
+++ /dev/null
@@ -1,17 +0,0 @@
-require "testing_env"
-
-class IntegrationCommandTestDesc < IntegrationCommandTestCase
- def test_desc
- setup_test_formula "testball"
-
- assert_equal "testball: Some test", cmd("desc", "testball")
- assert_match "Pick one, and only one", cmd_fail("desc", "--search", "--name")
- assert_match "You must provide a search term", cmd_fail("desc", "--search")
-
- desc_cache = HOMEBREW_CACHE/"desc_cache.json"
- refute_predicate desc_cache, :exist?, "Cached file should not exist"
-
- cmd("desc", "--description", "testball")
- assert_predicate desc_cache, :exist?, "Cached file should not exist"
- end
-end
diff --git a/Library/Homebrew/test/dev-cmd/bottle_spec.rb b/Library/Homebrew/test/dev-cmd/bottle_spec.rb
new file mode 100644
index 000000000..468ef2e90
--- /dev/null
+++ b/Library/Homebrew/test/dev-cmd/bottle_spec.rb
@@ -0,0 +1,30 @@
+describe "brew bottle", :integration_test do
+ it "builds a bottle for the given Formula" do
+ begin
+ shutup do
+ expect { brew "install", "--build-bottle", testball }
+ .to be_a_success
+ end
+
+ expect { brew "bottle", "--no-rebuild", testball }
+ .to output(/Formula not from core or any taps/).to_stderr
+ .and not_to_output.to_stdout
+ .and be_a_failure
+
+ 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
+
+ expect { brew "bottle", "--no-rebuild", "testball" }
+ .to output(/testball-0\.1.*\.bottle\.tar\.gz/).to_stdout
+ .and not_to_output.to_stderr
+ .and be_a_success
+ ensure
+ FileUtils.rm_f Dir.glob("testball-0.1*.bottle.tar.gz")
+ end
+ end
+end
diff --git a/Library/Homebrew/test/dev-cmd/create_spec.rb b/Library/Homebrew/test/dev-cmd/create_spec.rb
new file mode 100644
index 000000000..b7f96ec7f
--- /dev/null
+++ b/Library/Homebrew/test/dev-cmd/create_spec.rb
@@ -0,0 +1,13 @@
+describe "brew create", :integration_test do
+ let(:url) { "file://#{TEST_FIXTURE_DIR}/tarballs/testball-0.1.tbz" }
+ let(:formula_file) { CoreTap.new.formula_dir/"testball.rb" }
+
+ it "creates a new Formula file for a given URL" do
+ shutup do
+ brew "create", url, "HOMEBREW_EDITOR" => "/bin/cat"
+ end
+
+ expect(formula_file).to exist
+ expect(formula_file.read).to match(%Q(sha256 "#{TESTBALL_SHA256}"))
+ end
+end
diff --git a/Library/Homebrew/test/dev-cmd/edit_spec.rb b/Library/Homebrew/test/dev-cmd/edit_spec.rb
new file mode 100644
index 000000000..5cedb0524
--- /dev/null
+++ b/Library/Homebrew/test/dev-cmd/edit_spec.rb
@@ -0,0 +1,16 @@
+describe "brew edit", :integration_test do
+ it "opens a given Formula in an editor" do
+ HOMEBREW_REPOSITORY.cd do
+ shutup do
+ system "git", "init"
+ end
+ end
+
+ setup_test_formula "testball"
+
+ expect { brew "edit", "testball", "HOMEBREW_EDITOR" => "/bin/cat" }
+ .to output(/# something here/).to_stdout
+ .and not_to_output.to_stderr
+ .and be_a_success
+ end
+end
diff --git a/Library/Homebrew/test/dev-cmd/formula_spec.rb b/Library/Homebrew/test/dev-cmd/formula_spec.rb
new file mode 100644
index 000000000..cc5b3e9e8
--- /dev/null
+++ b/Library/Homebrew/test/dev-cmd/formula_spec.rb
@@ -0,0 +1,10 @@
+describe "brew formula", :integration_test do
+ it "prints a given Formula's path" do
+ formula_file = setup_test_formula "testball"
+
+ expect { brew "formula", "testball" }
+ .to output("#{formula_file}\n").to_stdout
+ .and not_to_output.to_stderr
+ .and be_a_success
+ end
+end
diff --git a/Library/Homebrew/test/dev-cmd/pull_spec.rb b/Library/Homebrew/test/dev-cmd/pull_spec.rb
new file mode 100644
index 000000000..3c0108df2
--- /dev/null
+++ b/Library/Homebrew/test/dev-cmd/pull_spec.rb
@@ -0,0 +1,60 @@
+describe "brew pull", :integration_test do
+ it "fails when no argument is given" do
+ expect { brew "pull" }
+ .to output(/This command requires at least one argument/).to_stderr
+ .and not_to_output.to_stdout
+ .and be_a_failure
+ end
+
+ it "fetches a patch from a GitHub commit or pull request and applies it" do
+ skip "Requires network connection." if ENV["HOMEBREW_NO_GITHUB_API"]
+
+ CoreTap.instance.path.cd do
+ shutup do
+ system "git", "init"
+ system "git", "checkout", "-b", "new-branch"
+ end
+ end
+
+ expect { brew "pull", "https://bot.brew.sh/job/Homebrew\%20Testing/1028/" }
+ .to output(/Testing URLs require `\-\-bottle`!/).to_stderr
+ .and not_to_output.to_stdout
+ .and be_a_failure
+
+ expect { brew "pull", "1" }
+ .to output(/Fetching patch/).to_stdout
+ .and output(/Current branch is new\-branch/).to_stderr
+ .and be_a_failure
+
+ expect { brew "pull", "--bump", "8" }
+ .to output(/Fetching patch/).to_stdout
+ .and output(/No changed formulae found to bump/).to_stderr
+ .and be_a_failure
+
+ expect { brew "pull", "--bump", "https://api.github.com/repos/Homebrew/homebrew-core/pulls/122" }
+ .to output(/Fetching patch/).to_stdout
+ .and output(/Can only bump one changed formula/).to_stderr
+ .and be_a_failure
+
+ expect { brew "pull", "https://github.com/Homebrew/homebrew-core/pull/1" }
+ .to output(/Fetching patch/).to_stdout
+ .and output(/Patch failed to apply/).to_stderr
+ .and be_a_failure
+ end
+
+ describe "--rebase" do
+ it "fails" do
+ expect { brew "pull", "--rebase" }
+ .to output(/You meant `git pull --rebase`./).to_stderr
+ .and not_to_output.to_stdout
+ .and be_a_failure
+ end
+ end
+
+ it "fails when given 0" do
+ expect { brew "pull", "0" }
+ .to output(/Not a GitHub pull request or commit/).to_stderr
+ .and not_to_output.to_stdout
+ .and be_a_failure
+ end
+end
diff --git a/Library/Homebrew/test/dev-cmd/tap_spec.rb b/Library/Homebrew/test/dev-cmd/tap_spec.rb
new file mode 100644
index 000000000..a24c67aae
--- /dev/null
+++ b/Library/Homebrew/test/dev-cmd/tap_spec.rb
@@ -0,0 +1,75 @@
+describe "brew tap", :integration_test do
+ it "taps a given Tap" do
+ path = Tap::TAP_DIRECTORY/"homebrew/homebrew-foo"
+ path.mkpath
+ path.cd do
+ shutup do
+ system "git", "init"
+ system "git", "remote", "add", "origin", "https://github.com/Homebrew/homebrew-foo"
+ FileUtils.touch "readme"
+ system "git", "add", "--all"
+ system "git", "commit", "-m", "init"
+ end
+ end
+
+ expect { brew "tap" }
+ .to output(%r{homebrew/foo}).to_stdout
+ .and not_to_output.to_stderr
+ .and be_a_success
+
+ expect { brew "tap", "--list-official" }
+ .to output(%r{homebrew/science}).to_stdout
+ .and not_to_output.to_stderr
+ .and be_a_success
+
+ expect { brew "tap-info" }
+ .to output(/2 taps/).to_stdout
+ .and not_to_output.to_stderr
+ .and be_a_success
+
+ expect { brew "tap-info", "homebrew/foo" }
+ .to output(%r{https://github\.com/Homebrew/homebrew-foo}).to_stdout
+ .and not_to_output.to_stderr
+ .and be_a_success
+
+ expect { brew "tap-info", "--json=v1", "--installed" }
+ .to output(%r{https://github\.com/Homebrew/homebrew-foo}).to_stdout
+ .and not_to_output.to_stderr
+ .and be_a_success
+
+ expect { brew "tap-pin", "homebrew/foo" }
+ .to output(%r{Pinned homebrew/foo}).to_stdout
+ .and not_to_output.to_stderr
+ .and be_a_success
+
+ expect { brew "tap", "--list-pinned" }
+ .to output(%r{homebrew/foo}).to_stdout
+ .and not_to_output.to_stderr
+ .and be_a_success
+
+ expect { brew "tap-unpin", "homebrew/foo" }
+ .to output(%r{Unpinned homebrew/foo}).to_stdout
+ .and not_to_output.to_stderr
+ .and be_a_success
+
+ expect { brew "tap", "homebrew/bar", path/".git" }
+ .to output(/Tapped/).to_stdout
+ .and output(/Cloning/).to_stderr
+ .and be_a_success
+
+ expect { brew "untap", "homebrew/bar" }
+ .to output(/Untapped/).to_stdout
+ .and not_to_output.to_stderr
+ .and be_a_success
+
+ expect { brew "tap", "homebrew/bar", path/".git", "-q", "--full" }
+ .to be_a_success
+ .and not_to_output.to_stdout
+ .and not_to_output.to_stderr
+
+ expect { brew "untap", "homebrew/bar" }
+ .to output(/Untapped/).to_stdout
+ .and not_to_output.to_stderr
+ .and be_a_success
+ end
+end
diff --git a/Library/Homebrew/test/dev-cmd/test_spec.rb b/Library/Homebrew/test/dev-cmd/test_spec.rb
new file mode 100644
index 000000000..b73d042e4
--- /dev/null
+++ b/Library/Homebrew/test/dev-cmd/test_spec.rb
@@ -0,0 +1,56 @@
+describe "brew test", :integration_test do
+ it "fails when no argument is given" do
+ expect { brew "test" }
+ .to output(/This command requires a formula argument/).to_stderr
+ .and not_to_output.to_stdout
+ .and be_a_failure
+ end
+
+ it "fails when a Formula is not installed" do
+ expect { brew "test", testball }
+ .to output(/Testing requires the latest version of testball/).to_stderr
+ .and not_to_output.to_stdout
+ .and be_a_failure
+ end
+
+ it "fails when a Formula has no test" do
+ shutup do
+ expect { brew "install", testball }.to be_a_success
+ end
+
+ expect { brew "test", testball }
+ .to output(/testball defines no test/).to_stderr
+ .and not_to_output.to_stdout
+ .and be_a_failure
+ end
+
+ it "tests a given Formula" do
+ setup_test_formula "testball", <<-EOS.undent
+ head "https://github.com/example/testball2.git"
+
+ devel do
+ url "file://#{TEST_FIXTURE_DIR}/tarballs/testball-0.1.tbz"
+ sha256 "#{TESTBALL_SHA256}"
+ end
+
+ keg_only "just because"
+
+ test do
+ end
+ EOS
+
+ shutup do
+ expect { brew "install", "testball" }.to be_a_success
+ end
+
+ expect { brew "test", "--HEAD", "testball" }
+ .to output(/Testing testball/).to_stdout
+ .and not_to_output.to_stderr
+ .and be_a_success
+
+ expect { brew "test", "--devel", "testball" }
+ .to output(/Testing testball/).to_stdout
+ .and not_to_output.to_stderr
+ .and be_a_success
+ end
+end
diff --git a/Library/Homebrew/test/doctor_test.rb b/Library/Homebrew/test/doctor_test.rb
deleted file mode 100644
index d2dc871f4..000000000
--- a/Library/Homebrew/test/doctor_test.rb
+++ /dev/null
@@ -1,8 +0,0 @@
-require "testing_env"
-
-class IntegrationCommandTestDoctor < IntegrationCommandTestCase
- def test_doctor
- assert_match "This is an integration test",
- cmd_fail("doctor", "check_integration_test")
- end
-end
diff --git a/Library/Homebrew/test/edit_test.rb b/Library/Homebrew/test/edit_test.rb
deleted file mode 100644
index 9b6ded651..000000000
--- a/Library/Homebrew/test/edit_test.rb
+++ /dev/null
@@ -1,11 +0,0 @@
-require "testing_env"
-
-class IntegrationCommandTestEdit < IntegrationCommandTestCase
- def test_edit
- (HOMEBREW_REPOSITORY/".git").mkpath
- setup_test_formula "testball"
-
- assert_match "# something here",
- cmd("edit", "testball", "HOMEBREW_EDITOR" => "/bin/cat")
- end
-end
diff --git a/Library/Homebrew/test/fetch_test.rb b/Library/Homebrew/test/fetch_test.rb
deleted file mode 100644
index e08e545e3..000000000
--- a/Library/Homebrew/test/fetch_test.rb
+++ /dev/null
@@ -1,11 +0,0 @@
-require "testing_env"
-
-class IntegrationCommandTestFetch < IntegrationCommandTestCase
- def test_fetch
- setup_test_formula "testball"
-
- cmd("fetch", "testball")
- assert((HOMEBREW_CACHE/"testball-0.1.tbz").exist?,
- "The tarball should have been cached")
- end
-end
diff --git a/Library/Homebrew/test/formula_cmd_test.rb b/Library/Homebrew/test/formula_cmd_test.rb
deleted file mode 100644
index abbe42d98..000000000
--- a/Library/Homebrew/test/formula_cmd_test.rb
+++ /dev/null
@@ -1,8 +0,0 @@
-require "testing_env"
-
-class IntegrationCommandTestFormula < IntegrationCommandTestCase
- def test_formula
- formula_file = setup_test_formula "testball"
- assert_equal formula_file.to_s, cmd("formula", "testball")
- end
-end
diff --git a/Library/Homebrew/test/formula_spec.rb b/Library/Homebrew/test/formula_spec.rb
new file mode 100644
index 000000000..1e064912f
--- /dev/null
+++ b/Library/Homebrew/test/formula_spec.rb
@@ -0,0 +1,1295 @@
+require "test/support/fixtures/testball"
+require "formula"
+
+RSpec::Matchers.alias_matcher :follow_installed_alias, :be_follow_installed_alias
+RSpec::Matchers.alias_matcher :have_any_version_installed, :be_any_version_installed
+RSpec::Matchers.alias_matcher :need_migration, :be_migration_needed
+
+RSpec::Matchers.alias_matcher :have_changed_installed_alias_target, :be_installed_alias_target_changed
+RSpec::Matchers.alias_matcher :supersede_an_installed_formula, :be_supersedes_an_installed_formula
+RSpec::Matchers.alias_matcher :have_changed_alias, :be_alias_changed
+
+RSpec::Matchers.alias_matcher :have_option_defined, :be_option_defined
+RSpec::Matchers.alias_matcher :have_post_install_defined, :be_post_install_defined
+RSpec::Matchers.alias_matcher :have_test_defined, :be_test_defined
+RSpec::Matchers.alias_matcher :pour_bottle, :be_pour_bottle
+
+describe Formula do
+ describe "::new" do
+ let(:klass) do
+ Class.new(described_class) do
+ url "http://example.com/foo-1.0.tar.gz"
+ end
+ end
+
+ let(:name) { "formula_name" }
+ let(:path) { Formulary.core_path(name) }
+ let(:spec) { :stable }
+ let(:alias_name) { "baz@1" }
+ let(:alias_path) { CoreTap.instance.alias_dir/alias_name }
+ let(:f) { klass.new(name, path, spec) }
+ let(:f_alias) { klass.new(name, path, spec, alias_path: alias_path) }
+
+ specify "formula instantiation" do
+ expect(f.name).to eq(name)
+ expect(f.specified_name).to eq(name)
+ expect(f.full_name).to eq(name)
+ expect(f.full_specified_name).to eq(name)
+ expect(f.path).to eq(path)
+ expect(f.alias_path).to be nil
+ expect(f.alias_name).to be nil
+ expect(f.full_alias_name).to be nil
+ expect { klass.new }.to raise_error(ArgumentError)
+ end
+
+ specify "formula instantiation with alias" do
+ expect(f_alias.name).to eq(name)
+ expect(f_alias.full_name).to eq(name)
+ expect(f_alias.path).to eq(path)
+ expect(f_alias.alias_path).to eq(alias_path)
+ expect(f_alias.alias_name).to eq(alias_name)
+ expect(f_alias.specified_name).to eq(alias_name)
+ expect(f_alias.full_alias_name).to eq(alias_name)
+ expect(f_alias.full_specified_name).to eq(alias_name)
+ expect { klass.new }.to raise_error(ArgumentError)
+ end
+
+ context "in a Tap" do
+ let(:tap) { Tap.new("foo", "bar") }
+ let(:path) { (tap.path/"Formula/#{name}.rb") }
+ let(:full_name) { "#{tap.user}/#{tap.repo}/#{name}" }
+ let(:full_alias_name) { "#{tap.user}/#{tap.repo}/#{alias_name}" }
+
+ specify "formula instantiation" do
+ expect(f.name).to eq(name)
+ expect(f.specified_name).to eq(name)
+ expect(f.full_name).to eq(full_name)
+ expect(f.full_specified_name).to eq(full_name)
+ expect(f.path).to eq(path)
+ expect(f.alias_path).to be nil
+ expect(f.alias_name).to be nil
+ expect(f.full_alias_name).to be nil
+ expect { klass.new }.to raise_error(ArgumentError)
+ end
+
+ specify "formula instantiation with alias" do
+ expect(f_alias.name).to eq(name)
+ expect(f_alias.full_name).to eq(full_name)
+ expect(f_alias.path).to eq(path)
+ expect(f_alias.alias_path).to eq(alias_path)
+ expect(f_alias.alias_name).to eq(alias_name)
+ expect(f_alias.specified_name).to eq(alias_name)
+ expect(f_alias.full_alias_name).to eq(full_alias_name)
+ expect(f_alias.full_specified_name).to eq(full_alias_name)
+ expect { klass.new }.to raise_error(ArgumentError)
+ end
+ end
+ end
+
+ describe "#follow_installed_alias?" do
+ let(:f) do
+ formula do
+ url "foo-1.0"
+ end
+ end
+
+ it "returns true by default" do
+ expect(f).to follow_installed_alias
+ end
+
+ it "can be set to true" do
+ f.follow_installed_alias = true
+ expect(f).to follow_installed_alias
+ end
+
+ it "can be set to false" do
+ f.follow_installed_alias = false
+ expect(f).not_to follow_installed_alias
+ end
+ end
+
+ example "installed alias with core" do
+ f = formula do
+ url "foo-1.0"
+ end
+
+ build_values_with_no_installed_alias = [
+ nil,
+ BuildOptions.new({}, {}),
+ Tab.new(source: { "path" => f.path.to_s }),
+ ]
+ build_values_with_no_installed_alias.each do |build|
+ f.build = build
+ expect(f.installed_alias_path).to be nil
+ expect(f.installed_alias_name).to be nil
+ expect(f.full_installed_alias_name).to be nil
+ expect(f.installed_specified_name).to eq(f.name)
+ expect(f.full_installed_specified_name).to eq(f.name)
+ end
+
+ alias_name = "bar"
+ alias_path = "#{CoreTap.instance.alias_dir}/#{alias_name}"
+
+ f.build = Tab.new(source: { "path" => alias_path })
+
+ expect(f.installed_alias_path).to eq(alias_path)
+ expect(f.installed_alias_name).to eq(alias_name)
+ expect(f.full_installed_alias_name).to eq(alias_name)
+ expect(f.installed_specified_name).to eq(alias_name)
+ expect(f.full_installed_specified_name).to eq(alias_name)
+ end
+
+ example "installed alias with tap" do
+ tap = Tap.new("user", "repo")
+ name = "foo"
+ path = "#{tap.path}/Formula/#{name}.rb"
+ f = formula name, path: path do
+ url "foo-1.0"
+ end
+
+ build_values_with_no_installed_alias = [nil, BuildOptions.new({}, {}), Tab.new(source: { "path" => f.path })]
+ build_values_with_no_installed_alias.each do |build|
+ f.build = build
+ expect(f.installed_alias_path).to be nil
+ expect(f.installed_alias_name).to be nil
+ expect(f.full_installed_alias_name).to be nil
+ expect(f.installed_specified_name).to eq(f.name)
+ expect(f.full_installed_specified_name).to eq(f.full_name)
+ end
+
+ alias_name = "bar"
+ full_alias_name = "#{tap.user}/#{tap.repo}/#{alias_name}"
+ alias_path = "#{tap.alias_dir}/#{alias_name}"
+
+ f.build = Tab.new(source: { "path" => alias_path })
+
+ expect(f.installed_alias_path).to eq(alias_path)
+ expect(f.installed_alias_name).to eq(alias_name)
+ expect(f.full_installed_alias_name).to eq(full_alias_name)
+ expect(f.installed_specified_name).to eq(alias_name)
+ expect(f.full_installed_specified_name).to eq(full_alias_name)
+ end
+
+ specify "#prefix" do
+ f = Testball.new
+ expect(f.prefix).to eq(HOMEBREW_CELLAR/f.name/"0.1")
+ expect(f.prefix).to be_kind_of(Pathname)
+ end
+
+ example "revised prefix" do
+ f = Class.new(Testball) { revision(1) }.new
+ expect(f.prefix).to eq(HOMEBREW_CELLAR/f.name/"0.1_1")
+ end
+
+ specify "#any_version_installed?" do
+ f = formula do
+ url "foo"
+ version "1.0"
+ end
+
+ expect(f).not_to have_any_version_installed
+
+ prefix = HOMEBREW_CELLAR/f.name/"0.1"
+ prefix.mkpath
+ FileUtils.touch prefix/Tab::FILENAME
+
+ expect(f).to have_any_version_installed
+ end
+
+ specify "#migration_needed" do
+ f = Testball.new("newname")
+ f.instance_variable_set(:@oldname, "oldname")
+ f.instance_variable_set(:@tap, CoreTap.instance)
+
+ oldname_prefix = (HOMEBREW_CELLAR/"oldname/2.20")
+ newname_prefix = (HOMEBREW_CELLAR/"newname/2.10")
+
+ oldname_prefix.mkpath
+ oldname_tab = Tab.empty
+ oldname_tab.tabfile = oldname_prefix/Tab::FILENAME
+ oldname_tab.write
+
+ expect(f).not_to need_migration
+
+ oldname_tab.tabfile.unlink
+ oldname_tab.source["tap"] = "homebrew/core"
+ oldname_tab.write
+
+ expect(f).to need_migration
+
+ newname_prefix.mkpath
+
+ expect(f).not_to need_migration
+ end
+
+ describe "#installed?" do
+ let(:f) { Testball.new }
+
+ it "returns false if the #installed_prefix is not a directory" do
+ allow(f).to receive(:installed_prefix).and_return(double(directory?: false))
+ expect(f).not_to be_installed
+ end
+
+ it "returns false if the #installed_prefix does not have children" do
+ allow(f).to receive(:installed_prefix).and_return(double(directory?: true, children: []))
+ expect(f).not_to be_installed
+ end
+
+ it "returns true if the #installed_prefix has children" do
+ allow(f).to receive(:installed_prefix).and_return(double(directory?: true, children: [double]))
+ expect(f).to be_installed
+ end
+ end
+
+ describe "#installed prefix" do
+ let(:f) do
+ formula do
+ url "foo"
+ version "1.9"
+
+ head "foo"
+
+ devel do
+ url "foo"
+ version "2.1-devel"
+ end
+ end
+ end
+
+ let(:stable_prefix) { HOMEBREW_CELLAR/f.name/f.version }
+ let(:devel_prefix) { HOMEBREW_CELLAR/f.name/f.devel.version }
+ let(:head_prefix) { HOMEBREW_CELLAR/f.name/f.head.version }
+
+ it "is the same as #prefix by default" do
+ expect(f.installed_prefix).to eq(f.prefix)
+ end
+
+ it "returns the stable prefix if it is installed" do
+ stable_prefix.mkpath
+ expect(f.installed_prefix).to eq(stable_prefix)
+ end
+
+ it "returns the devel prefix if it is installed" do
+ devel_prefix.mkpath
+ expect(f.installed_prefix).to eq(devel_prefix)
+ end
+
+ it "returns the head prefix if it is installed" do
+ head_prefix.mkpath
+ expect(f.installed_prefix).to eq(head_prefix)
+ end
+
+ it "returns the stable prefix if head is outdated" do
+ head_prefix.mkpath
+
+ tab = Tab.empty
+ tab.tabfile = head_prefix/Tab::FILENAME
+ tab.source["versions"] = { "stable" => "1.0" }
+ tab.write
+
+ expect(f.installed_prefix).to eq(stable_prefix)
+ end
+
+ it "returns the stable prefix if head and devel are outdated" do
+ head_prefix.mkpath
+
+ tab = Tab.empty
+ tab.tabfile = head_prefix/Tab::FILENAME
+ tab.source["versions"] = { "stable" => "1.9", "devel" => "2.0" }
+ tab.write
+
+ expect(f.installed_prefix).to eq(stable_prefix)
+ end
+
+ it "returns the devel prefix if the active specification is :devel" do
+ f.active_spec = :devel
+ expect(f.installed_prefix).to eq(devel_prefix)
+ end
+
+ it "returns the head prefix if the active specification is :head" do
+ f.active_spec = :head
+ expect(f.installed_prefix).to eq(head_prefix)
+ end
+ end
+
+ describe "#latest_head_prefix" do
+ let(:f) { Testball.new }
+
+ it "returns the latest head prefix" do
+ stamps_with_revisions = [
+ [111111, 1],
+ [222222, 0],
+ [222222, 1],
+ [222222, 2],
+ ]
+
+ stamps_with_revisions.each do |stamp, revision|
+ version = "HEAD-#{stamp}"
+ version << "_#{revision}" unless revision.zero?
+
+ prefix = f.rack/version
+ prefix.mkpath
+
+ tab = Tab.empty
+ tab.tabfile = prefix/Tab::FILENAME
+ tab.source_modified_time = stamp
+ tab.write
+ end
+
+ prefix = HOMEBREW_CELLAR/f.name/"HEAD-222222_2"
+
+ expect(f.latest_head_prefix).to eq(prefix)
+ end
+ end
+
+ specify "equality" do
+ x = Testball.new
+ y = Testball.new
+
+ expect(x).to eq(y)
+ expect(x).to eql(y)
+ expect(x.hash).to eq(y.hash)
+ end
+
+ specify "inequality" do
+ x = Testball.new("foo")
+ y = Testball.new("bar")
+
+ expect(x).not_to eq(y)
+ expect(x).not_to eql(y)
+ expect(x.hash).not_to eq(y.hash)
+ end
+
+ specify "comparison with non formula objects does not raise" do
+ expect(Object.new).not_to eq(Testball.new)
+ end
+
+ specify "#<=>" do
+ expect(Testball.new <=> Object.new).to be nil
+ end
+
+ describe "#installed_alias_path" do
+ example "alias paths with build options" do
+ alias_path = (CoreTap.instance.alias_dir/"another_name")
+
+ f = formula alias_path: alias_path do
+ url "foo-1.0"
+ end
+ f.build = BuildOptions.new({}, {})
+
+ expect(f.alias_path).to eq(alias_path)
+ expect(f.installed_alias_path).to be nil
+ end
+
+ example "alias paths with tab with non alias source path" do
+ alias_path = (CoreTap.instance.alias_dir/"another_name")
+ source_path = (CoreTap.instance.formula_dir/"another_other_name")
+
+ f = formula alias_path: alias_path do
+ url "foo-1.0"
+ end
+ f.build = Tab.new(source: { "path" => source_path.to_s })
+
+ expect(f.alias_path).to eq(alias_path)
+ expect(f.installed_alias_path).to be nil
+ end
+
+ example "alias paths with tab with alias source path" do
+ alias_path = (CoreTap.instance.alias_dir/"another_name")
+ source_path = (CoreTap.instance.alias_dir/"another_other_name")
+
+ f = formula alias_path: alias_path do
+ url "foo-1.0"
+ end
+ f.build = Tab.new(source: { "path" => source_path.to_s })
+
+ expect(f.alias_path).to eq(alias_path)
+ expect(f.installed_alias_path).to eq(source_path.to_s)
+ end
+ end
+
+ describe "::installed_with_alias_path" do
+ specify "with alias path with nil" do
+ expect(described_class.installed_with_alias_path(nil)).to be_empty
+ end
+
+ specify "with alias path with a path" do
+ alias_path = "#{CoreTap.instance.alias_dir}/alias"
+ different_alias_path = "#{CoreTap.instance.alias_dir}/another_alias"
+
+ formula_with_alias = formula "foo" do
+ url "foo-1.0"
+ end
+ formula_with_alias.build = Tab.empty
+ formula_with_alias.build.source["path"] = alias_path
+
+ formula_without_alias = formula "bar" do
+ url "bar-1.0"
+ end
+ formula_without_alias.build = Tab.empty
+ formula_without_alias.build.source["path"] = formula_without_alias.path.to_s
+
+ formula_with_different_alias = formula "baz" do
+ url "baz-1.0"
+ end
+ formula_with_different_alias.build = Tab.empty
+ formula_with_different_alias.build.source["path"] = different_alias_path
+
+ formulae = [
+ formula_with_alias,
+ formula_without_alias,
+ formula_with_different_alias,
+ ]
+
+ allow(described_class).to receive(:installed).and_return(formulae)
+
+ expect(described_class.installed_with_alias_path(alias_path))
+ .to eq([formula_with_alias])
+ end
+ end
+
+ specify "spec integration" do
+ f = formula do
+ homepage "http://example.com"
+
+ url "http://example.com/test-0.1.tbz"
+ mirror "http://example.org/test-0.1.tbz"
+ sha256 TEST_SHA256
+
+ head "http://example.com/test.git", tag: "foo"
+
+ devel do
+ url "http://example.com/test-0.2.tbz"
+ mirror "http://example.org/test-0.2.tbz"
+ sha256 TEST_SHA256
+ end
+ end
+
+ expect(f.homepage).to eq("http://example.com")
+ expect(f.version).to eq(Version.create("0.1"))
+ expect(f).to be_stable
+ expect(f.stable.version).to eq(Version.create("0.1"))
+ expect(f.devel.version).to eq(Version.create("0.2"))
+ expect(f.head.version).to eq(Version.create("HEAD"))
+ end
+
+ specify "#active_spec=" do
+ f = formula do
+ url "foo"
+ version "1.0"
+ revision 1
+
+ devel do
+ url "foo"
+ version "1.0beta"
+ end
+ end
+
+ expect(f.active_spec_sym).to eq(:stable)
+ expect(f.send(:active_spec)).to eq(f.stable)
+ expect(f.pkg_version.to_s).to eq("1.0_1")
+
+ f.active_spec = :devel
+
+ expect(f.active_spec_sym).to eq(:devel)
+ expect(f.send(:active_spec)).to eq(f.devel)
+ expect(f.pkg_version.to_s).to eq("1.0beta_1")
+ expect { f.active_spec = :head }.to raise_error(FormulaSpecificationError)
+ end
+
+ specify "class specs are always initialized" do
+ f = formula do
+ url "foo-1.0"
+ end
+
+ expect(f.class.stable).to be_kind_of(SoftwareSpec)
+ expect(f.class.devel).to be_kind_of(SoftwareSpec)
+ expect(f.class.head).to be_kind_of(SoftwareSpec)
+ end
+
+ specify "incomplete instance specs are not accessible" do
+ f = formula do
+ url "foo-1.0"
+ end
+
+ expect(f.devel).to be nil
+ expect(f.head).to be nil
+ end
+
+ it "honors attributes declared before specs" do
+ f = formula do
+ url "foo-1.0"
+
+ depends_on "foo"
+
+ devel do
+ url "foo-1.1"
+ end
+ end
+
+ expect(f.class.stable.deps.first.name).to eq("foo")
+ expect(f.class.devel.deps.first.name).to eq("foo")
+ expect(f.class.head.deps.first.name).to eq("foo")
+ end
+
+ describe "#pkg_version" do
+ specify "simple version" do
+ f = formula do
+ url "foo-1.0.bar"
+ end
+
+ expect(f.pkg_version).to eq(PkgVersion.parse("1.0"))
+ end
+
+ specify "version with revision" do
+ f = formula do
+ url "foo-1.0.bar"
+ revision 1
+ end
+
+ expect(f.pkg_version).to eq(PkgVersion.parse("1.0_1"))
+ end
+
+ specify "head uses revisions" do
+ f = formula "test", spec: :head do
+ url "foo-1.0.bar"
+ revision 1
+
+ head "foo"
+ end
+
+ expect(f.pkg_version).to eq(PkgVersion.parse("HEAD_1"))
+ end
+ end
+
+ specify "#update_head_version" do
+ f = formula do
+ head "foo", using: :git
+ end
+
+ cached_location = f.head.downloader.cached_location
+ cached_location.mkpath
+ cached_location.cd do
+ FileUtils.touch "LICENSE"
+
+ shutup do
+ system("git", "init")
+ system("git", "add", "--all")
+ system("git", "commit", "-m", "Initial commit")
+ end
+ end
+
+ f.update_head_version
+
+ expect(f.head.version).to eq(Version.create("HEAD-5658946"))
+ end
+
+ specify "legacy options" do
+ f = formula do
+ url "foo-1.0"
+
+ def options
+ [
+ ["--foo", "desc"],
+ ["--bar", "desc"],
+ ]
+ end
+
+ option("baz")
+ end
+
+ expect(f).to have_option_defined("foo")
+ expect(f).to have_option_defined("bar")
+ expect(f).to have_option_defined("baz")
+ end
+
+ specify "#desc" do
+ f = formula do
+ desc "a formula"
+
+ url "foo-1.0"
+ end
+
+ expect(f.desc).to eq("a formula")
+ end
+
+ specify "#post_install_defined?" do
+ f1 = formula do
+ url "foo-1.0"
+
+ def post_install
+ # do nothing
+ end
+ end
+
+ f2 = formula do
+ url "foo-1.0"
+ end
+
+ expect(f1).to have_post_install_defined
+ expect(f2).not_to have_post_install_defined
+ end
+
+ specify "#test_defined?" do
+ f1 = formula do
+ url "foo-1.0"
+
+ def test
+ # do nothing
+ end
+ end
+
+ f2 = formula do
+ url "foo-1.0"
+ end
+
+ expect(f1).to have_test_defined
+ expect(f2).not_to have_test_defined
+ end
+
+ specify "test fixtures" do
+ f1 = formula do
+ url "foo-1.0"
+ end
+
+ expect(f1.test_fixtures("foo")).to eq(Pathname.new("#{HOMEBREW_LIBRARY_PATH}/test/support/fixtures/foo"))
+ end
+
+ specify "dependencies" do
+ f1 = formula "f1" do
+ url "f1-1.0"
+ end
+
+ f2 = formula "f2" do
+ url "f2-1.0"
+ end
+
+ f3 = formula "f3" do
+ url "f3-1.0"
+
+ depends_on "f1" => :build
+ depends_on "f2"
+ end
+
+ f4 = formula "f4" do
+ url "f4-1.0"
+
+ depends_on "f1"
+ end
+
+ stub_formula_loader(f1)
+ stub_formula_loader(f2)
+ stub_formula_loader(f3)
+ stub_formula_loader(f4)
+
+ f5 = formula "f5" do
+ url "f5-1.0"
+
+ depends_on "f3" => :build
+ depends_on "f4"
+ end
+
+ expect(f5.deps.map(&:name)).to eq(["f3", "f4"])
+ expect(f5.recursive_dependencies.map(&:name)).to eq(["f1", "f2", "f3", "f4"])
+ expect(f5.runtime_dependencies.map(&:name)).to eq(["f1", "f4"])
+ end
+
+ specify "runtime dependencies with optional deps from tap" do
+ tap_loader = double
+
+ allow(tap_loader).to receive(:get_formula).and_raise(RuntimeError, "tried resolving tap formula")
+ allow(Formulary).to receive(:loader_for).with("foo/bar/f1", from: nil).and_return(tap_loader)
+ stub_formula_loader(formula("f2") { url("f2-1.0") }, "baz/qux/f2")
+
+ f3 = formula "f3" do
+ url "f3-1.0"
+
+ depends_on "foo/bar/f1" => :optional
+ depends_on "baz/qux/f2"
+ end
+
+ expect(f3.runtime_dependencies.map(&:name)).to eq(["baz/qux/f2"])
+
+ stub_formula_loader(formula("f1") { url("f1-1.0") }, "foo/bar/f1")
+ f3.build = BuildOptions.new(Options.create(["--with-f1"]), f3.options)
+
+ expect(f3.runtime_dependencies.map(&:name)).to eq(["foo/bar/f1", "baz/qux/f2"])
+ end
+
+ specify "requirements" do
+ f1 = formula "f1" do
+ url "f1-1"
+
+ depends_on :python
+ depends_on x11: :recommended
+ depends_on xcode: ["1.0", :optional]
+ end
+ stub_formula_loader(f1)
+
+ python = PythonRequirement.new
+ x11 = X11Requirement.new("x11", [:recommended])
+ xcode = XcodeRequirement.new(["1.0", :optional])
+
+ expect(Set.new(f1.recursive_requirements)).to eq(Set[python, x11])
+
+ f1.build = BuildOptions.new(["--with-xcode", "--without-x11"], f1.options)
+
+ expect(Set.new(f1.recursive_requirements)).to eq(Set[python, xcode])
+
+ f1.build = f1.stable.build
+ f2 = formula "f2" do
+ url "f2-1"
+
+ depends_on "f1"
+ end
+
+ expect(Set.new(f2.recursive_requirements)).to eq(Set[python, x11])
+ expect(Set.new(f2.recursive_requirements {})).to eq(Set[python, x11, xcode])
+
+ requirements = f2.recursive_requirements do |_dependent, requirement|
+ Requirement.prune if requirement.is_a?(PythonRequirement)
+ end
+
+ expect(Set.new(requirements)).to eq(Set[x11, xcode])
+ end
+
+ specify "#to_hash" do
+ f1 = formula "foo" do
+ url "foo-1.0"
+
+ bottle do
+ cellar(:any)
+ sha256(TEST_SHA256 => Utils::Bottles.tag)
+ end
+ end
+
+ h = f1.to_hash
+
+ expect(h).to be_a(Hash)
+ expect(h["name"]).to eq("foo")
+ expect(h["full_name"]).to eq("foo")
+ expect(h["versions"]["stable"]).to eq("1.0")
+ expect(h["versions"]["bottle"]).to be_truthy
+ end
+
+ describe "#eligible_kegs_for_cleanup" do
+ it "returns Kegs eligible for cleanup" do
+ f1 = Class.new(Testball) do
+ version("1.0")
+ end.new
+
+ f2 = Class.new(Testball) do
+ version("0.2")
+ version_scheme(1)
+ end.new
+
+ f3 = Class.new(Testball) do
+ version("0.3")
+ version_scheme(1)
+ end.new
+
+ f4 = Class.new(Testball) do
+ version("0.1")
+ version_scheme(2)
+ end.new
+
+ shutup do
+ [f1, f2, f3, f4].each do |f|
+ f.brew { f.install }
+ Tab.create(f, DevelopmentTools.default_compiler, :libcxx).write
+ end
+ end
+
+ expect(f1).to be_installed
+ expect(f2).to be_installed
+ expect(f3).to be_installed
+ expect(f4).to be_installed
+ expect(f3.eligible_kegs_for_cleanup.sort_by(&:version))
+ .to eq([f2, f1].map { |f| Keg.new(f.prefix) })
+ end
+
+ specify "with pinned Keg" do
+ f1 = Class.new(Testball) { version("0.1") }.new
+ f2 = Class.new(Testball) { version("0.2") }.new
+ f3 = Class.new(Testball) { version("0.3") }.new
+
+ shutup do
+ f1.brew { f1.install }
+ f1.pin
+ f2.brew { f2.install }
+ f3.brew { f3.install }
+ end
+
+ expect(f1.prefix).to eq((HOMEBREW_PINNED_KEGS/f1.name).resolved_path)
+ expect(f1).to be_installed
+ expect(f2).to be_installed
+ expect(f3).to be_installed
+ expect(shutup { f3.eligible_kegs_for_cleanup }).to eq([Keg.new(f2.prefix)])
+ end
+
+ specify "with HEAD installed" do
+ f = formula do
+ version("0.1")
+ head("foo")
+ end
+
+ stable_prefix = f.installed_prefix
+ stable_prefix.mkpath
+
+ [["000000_1", 1], ["111111", 2], ["111111_1", 2]].each do |pkg_version_suffix, stamp|
+ prefix = f.prefix("HEAD-#{pkg_version_suffix}")
+ prefix.mkpath
+ tab = Tab.empty
+ tab.tabfile = prefix/Tab::FILENAME
+ tab.source_modified_time = stamp
+ tab.write
+ end
+
+ eligible_kegs = f.installed_kegs - [Keg.new(f.prefix("HEAD-111111_1"))]
+ expect(f.eligible_kegs_for_cleanup).to eq(eligible_kegs)
+ end
+ end
+
+ describe "#pour_bottle?" do
+ it "returns false if set to false" do
+ f = formula "foo" do
+ url "foo-1.0"
+
+ def pour_bottle?
+ false
+ end
+ end
+
+ expect(f).not_to pour_bottle
+ end
+
+ it "returns true if set to true" do
+ f = formula "foo" do
+ url "foo-1.0"
+
+ def pour_bottle?
+ true
+ end
+ end
+
+ expect(f).to pour_bottle
+ end
+
+ it "returns false if set to false via DSL" do
+ f = formula "foo" do
+ url "foo-1.0"
+
+ pour_bottle? do
+ reason "false reason"
+ satisfy { (var == etc) }
+ end
+ end
+
+ expect(f).not_to pour_bottle
+ end
+
+ it "returns true if set to true via DSL" do
+ f = formula "foo" do
+ url "foo-1.0"
+
+ pour_bottle? do
+ reason "true reason"
+ satisfy { true }
+ end
+ end
+
+ expect(f).to pour_bottle
+ end
+ end
+
+ describe "alias changes" do
+ let(:f) do
+ formula "formula_name", alias_path: alias_path do
+ url "foo-1.0"
+ end
+ end
+
+ let(:new_formula) do
+ formula "new_formula_name", alias_path: alias_path do
+ url "foo-1.1"
+ end
+ end
+
+ let(:tab) { Tab.empty }
+ let(:alias_path) { "#{CoreTap.instance.alias_dir}/bar" }
+
+ before(:each) do
+ allow(described_class).to receive(:installed).and_return([f])
+
+ f.build = tab
+ new_formula.build = tab
+ end
+
+ specify "alias changes when not installed with alias" do
+ tab.source["path"] = Formulary.core_path(f.name).to_s
+
+ expect(f.current_installed_alias_target).to be nil
+ expect(f.latest_formula).to eq(f)
+ expect(f).not_to have_changed_installed_alias_target
+ expect(f).not_to supersede_an_installed_formula
+ expect(f).not_to have_changed_alias
+ expect(f.old_installed_formulae).to be_empty
+ end
+
+ specify "alias changes when not changed" do
+ tab.source["path"] = alias_path
+ stub_formula_loader(f, alias_path)
+
+ expect(f.current_installed_alias_target).to eq(f)
+ expect(f.latest_formula).to eq(f)
+ expect(f).not_to have_changed_installed_alias_target
+ expect(f).not_to supersede_an_installed_formula
+ expect(f).not_to have_changed_alias
+ expect(f.old_installed_formulae).to be_empty
+ end
+
+ specify "alias changes when new alias target" do
+ tab.source["path"] = alias_path
+ stub_formula_loader(new_formula, alias_path)
+
+ expect(f.current_installed_alias_target).to eq(new_formula)
+ expect(f.latest_formula).to eq(new_formula)
+ expect(f).to have_changed_installed_alias_target
+ expect(f).not_to supersede_an_installed_formula
+ expect(f).to have_changed_alias
+ expect(f.old_installed_formulae).to be_empty
+ end
+
+ specify "alias changes when old formulae installed" do
+ tab.source["path"] = alias_path
+ stub_formula_loader(new_formula, alias_path)
+
+ expect(new_formula.current_installed_alias_target).to eq(new_formula)
+ expect(new_formula.latest_formula).to eq(new_formula)
+ expect(new_formula).not_to have_changed_installed_alias_target
+ expect(new_formula).to supersede_an_installed_formula
+ expect(new_formula).to have_changed_alias
+ expect(new_formula.old_installed_formulae).to eq([f])
+ end
+ end
+
+ describe "#outdated_kegs" do
+ let(:outdated_prefix) { (HOMEBREW_CELLAR/"#{f.name}/1.11") }
+ let(:same_prefix) { (HOMEBREW_CELLAR/"#{f.name}/1.20") }
+ let(:greater_prefix) { (HOMEBREW_CELLAR/"#{f.name}/1.21") }
+ let(:head_prefix) { (HOMEBREW_CELLAR/"#{f.name}/HEAD") }
+ let(:old_alias_target_prefix) { (HOMEBREW_CELLAR/"#{old_formula.name}/1.0") }
+
+ let(:f) do
+ formula do
+ url "foo"
+ version "1.20"
+ end
+ end
+
+ let(:old_formula) do
+ formula "foo@1" do
+ url "foo-1.0"
+ end
+ end
+
+ let(:new_formula) do
+ formula "foo@2" do
+ url "foo-2.0"
+ end
+ end
+
+ let(:alias_path) { "#{f.tap.alias_dir}/bar" }
+
+ def setup_tab_for_prefix(prefix, options = {})
+ prefix.mkpath
+ tab = Tab.empty
+ tab.tabfile = prefix/Tab::FILENAME
+ tab.source["path"] = options[:path].to_s if options[:path]
+ tab.source["tap"] = options[:tap] if options[:tap]
+ tab.source["versions"] = options[:versions] if options[:versions]
+ tab.source_modified_time = options[:source_modified_time].to_i
+ tab.write unless options[:no_write]
+ tab
+ end
+
+ def reset_outdated_kegs
+ f.instance_variable_set(:@outdated_kegs, nil)
+ end
+
+ example "greater different tap installed" do
+ setup_tab_for_prefix(greater_prefix, tap: "user/repo")
+ expect(f.outdated_kegs).to be_empty
+ end
+
+ example "greater same tap installed" do
+ f.instance_variable_set(:@tap, CoreTap.instance)
+ setup_tab_for_prefix(greater_prefix, tap: "homebrew/core")
+ expect(f.outdated_kegs).to be_empty
+ end
+
+ example "outdated different tap installed" do
+ setup_tab_for_prefix(outdated_prefix, tap: "user/repo")
+ expect(f.outdated_kegs).not_to be_empty
+ end
+
+ example "outdated same tap installed" do
+ f.instance_variable_set(:@tap, CoreTap.instance)
+ setup_tab_for_prefix(outdated_prefix, tap: "homebrew/core")
+ expect(f.outdated_kegs).not_to be_empty
+ end
+
+ example "outdated follow alias and alias unchanged" do
+ f.follow_installed_alias = true
+ f.build = setup_tab_for_prefix(same_prefix, path: alias_path)
+ stub_formula_loader(f, alias_path)
+ expect(f.outdated_kegs).to be_empty
+ end
+
+ example "outdated follow alias and alias changed and new target not installed" do
+ f.follow_installed_alias = true
+ f.build = setup_tab_for_prefix(same_prefix, path: alias_path)
+ stub_formula_loader(new_formula, alias_path)
+ expect(f.outdated_kegs).not_to be_empty
+ end
+
+ example "outdated follow alias and alias changed and new target installed" do
+ f.follow_installed_alias = true
+ f.build = setup_tab_for_prefix(same_prefix, path: alias_path)
+ stub_formula_loader(new_formula, alias_path)
+ setup_tab_for_prefix(new_formula.prefix)
+ expect(f.outdated_kegs).to be_empty
+ end
+
+ example "outdated no follow alias and alias unchanged" do
+ f.follow_installed_alias = false
+ f.build = setup_tab_for_prefix(same_prefix, path: alias_path)
+ stub_formula_loader(f, alias_path)
+ expect(f.outdated_kegs).to be_empty
+ end
+
+ example "outdated no follow alias and alias changed" do
+ f.follow_installed_alias = false
+ f.build = setup_tab_for_prefix(same_prefix, path: alias_path)
+
+ f2 = formula "foo@2" do
+ url "foo-2.0"
+ end
+
+ stub_formula_loader(f2, alias_path)
+ expect(f.outdated_kegs).to be_empty
+ end
+
+ example "outdated old alias targets installed" do
+ f = formula alias_path: alias_path do
+ url "foo-1.0"
+ end
+
+ tab = setup_tab_for_prefix(old_alias_target_prefix, path: alias_path)
+ old_formula.build = tab
+ allow(described_class).to receive(:installed).and_return([old_formula])
+ expect(f.outdated_kegs).not_to be_empty
+ end
+
+ example "outdated old alias targets not installed" do
+ f = formula alias_path: alias_path do
+ url "foo-1.0"
+ end
+
+ tab = setup_tab_for_prefix(old_alias_target_prefix, path: old_formula.path)
+ old_formula.build = tab
+ allow(described_class).to receive(:installed).and_return([old_formula])
+ expect(f.outdated_kegs).to be_empty
+ end
+
+ example "outdated same head installed" do
+ f.instance_variable_set(:@tap, CoreTap.instance)
+ setup_tab_for_prefix(head_prefix, tap: "homebrew/core")
+ expect(f.outdated_kegs).to be_empty
+ end
+
+ example "outdated different head installed" do
+ f.instance_variable_set(:@tap, CoreTap.instance)
+ setup_tab_for_prefix(head_prefix, tap: "user/repo")
+ expect(f.outdated_kegs).to be_empty
+ end
+
+ example "outdated mixed taps greater version installed" do
+ f.instance_variable_set(:@tap, CoreTap.instance)
+ setup_tab_for_prefix(outdated_prefix, tap: "homebrew/core")
+ setup_tab_for_prefix(greater_prefix, tap: "user/repo")
+
+ expect(f.outdated_kegs).to be_empty
+
+ setup_tab_for_prefix(greater_prefix, tap: "homebrew/core")
+ reset_outdated_kegs
+
+ expect(f.outdated_kegs).to be_empty
+ end
+
+ example "outdated mixed taps outdated version installed" do
+ f.instance_variable_set(:@tap, CoreTap.instance)
+
+ extra_outdated_prefix = HOMEBREW_CELLAR/f.name/"1.0"
+
+ setup_tab_for_prefix(outdated_prefix)
+ setup_tab_for_prefix(extra_outdated_prefix, tap: "homebrew/core")
+ reset_outdated_kegs
+
+ expect(f.outdated_kegs).not_to be_empty
+
+ setup_tab_for_prefix(outdated_prefix, tap: "user/repo")
+ reset_outdated_kegs
+
+ expect(f.outdated_kegs).not_to be_empty
+ end
+
+ example "outdated same version tap installed" do
+ f.instance_variable_set(:@tap, CoreTap.instance)
+ setup_tab_for_prefix(same_prefix, tap: "homebrew/core")
+
+ expect(f.outdated_kegs).to be_empty
+
+ setup_tab_for_prefix(same_prefix, tap: "user/repo")
+ reset_outdated_kegs
+
+ expect(f.outdated_kegs).to be_empty
+ end
+
+ example "outdated installed head less than stable" do
+ tab = setup_tab_for_prefix(head_prefix, versions: { "stable" => "1.0" })
+
+ expect(f.outdated_kegs).not_to be_empty
+
+ tab.source["versions"] = { "stable" => f.version.to_s }
+ tab.write
+ reset_outdated_kegs
+
+ expect(f.outdated_kegs).to be_empty
+ end
+
+ describe ":fetch_head" do
+ let(:f) do
+ repo = testball_repo
+ formula "testball" do
+ url "foo"
+ version "2.10"
+ head "file://#{repo}", using: :git
+ end
+ end
+ let(:testball_repo) { HOMEBREW_PREFIX/"testball_repo" }
+
+ example do
+ begin
+ outdated_stable_prefix = HOMEBREW_CELLAR/"testball/1.0"
+ head_prefix_a = HOMEBREW_CELLAR/"testball/HEAD"
+ head_prefix_b = HOMEBREW_CELLAR/"testball/HEAD-aaaaaaa_1"
+ head_prefix_c = HOMEBREW_CELLAR/"testball/HEAD-18a7103"
+
+ setup_tab_for_prefix(outdated_stable_prefix)
+ tab_a = setup_tab_for_prefix(head_prefix_a, versions: { "stable" => "1.0" })
+ setup_tab_for_prefix(head_prefix_b)
+
+ testball_repo.mkdir
+ testball_repo.cd do
+ FileUtils.touch "LICENSE"
+
+ shutup do
+ system("git", "init")
+ system("git", "add", "--all")
+ system("git", "commit", "-m", "Initial commit")
+ end
+ end
+
+ expect(f.outdated_kegs(fetch_head: true)).not_to be_empty
+
+ tab_a.source["versions"] = { "stable" => f.version.to_s }
+ tab_a.write
+ reset_outdated_kegs
+ expect(f.outdated_kegs(fetch_head: true)).not_to be_empty
+
+ head_prefix_a.rmtree
+ reset_outdated_kegs
+ expect(f.outdated_kegs(fetch_head: true)).not_to be_empty
+
+ setup_tab_for_prefix(head_prefix_c, source_modified_time: 1)
+ reset_outdated_kegs
+ expect(f.outdated_kegs(fetch_head: true)).to be_empty
+ ensure
+ testball_repo.rmtree if testball_repo.exist?
+ end
+ end
+ end
+
+ describe "with changed version scheme" do
+ let(:f) do
+ formula "testball" do
+ url "foo"
+ version "20141010"
+ version_scheme 1
+ end
+ end
+
+ example do
+ prefix = HOMEBREW_CELLAR/"testball/0.1"
+ setup_tab_for_prefix(prefix, versions: { "stable" => "0.1" })
+
+ expect(f.outdated_kegs).not_to be_empty
+ end
+ end
+
+ describe "with mixed version schemes" do
+ let(:f) do
+ formula "testball" do
+ url "foo"
+ version "20141010"
+ version_scheme 3
+ end
+ end
+
+ example do
+ prefix_a = HOMEBREW_CELLAR/"testball/20141009"
+ setup_tab_for_prefix(prefix_a, versions: { "stable" => "20141009", "version_scheme" => 1 })
+
+ prefix_b = HOMEBREW_CELLAR/"testball/2.14"
+ setup_tab_for_prefix(prefix_b, versions: { "stable" => "2.14", "version_scheme" => 2 })
+
+ expect(f.outdated_kegs).not_to be_empty
+ reset_outdated_kegs
+
+ prefix_c = HOMEBREW_CELLAR/"testball/20141009"
+ setup_tab_for_prefix(prefix_c, versions: { "stable" => "20141009", "version_scheme" => 3 })
+
+ expect(f.outdated_kegs).not_to be_empty
+ reset_outdated_kegs
+
+ prefix_d = HOMEBREW_CELLAR/"testball/20141011"
+ setup_tab_for_prefix(prefix_d, versions: { "stable" => "20141009", "version_scheme" => 3 })
+ expect(f.outdated_kegs).to be_empty
+ end
+ end
+
+ describe "with version scheme" do
+ let(:f) do
+ formula "testball" do
+ url "foo"
+ version "1.0"
+ version_scheme 2
+ end
+ end
+
+ example do
+ head_prefix = HOMEBREW_CELLAR/"testball/HEAD"
+
+ setup_tab_for_prefix(head_prefix, versions: { "stable" => "1.0", "version_scheme" => 1 })
+ expect(f.outdated_kegs).not_to be_empty
+
+ reset_outdated_kegs
+ head_prefix.rmtree
+
+ setup_tab_for_prefix(head_prefix, versions: { "stable" => "1.0", "version_scheme" => 2 })
+ expect(f.outdated_kegs).to be_empty
+ end
+ end
+ end
+end
diff --git a/Library/Homebrew/test/formula_test.rb b/Library/Homebrew/test/formula_test.rb
deleted file mode 100644
index 318175d49..000000000
--- a/Library/Homebrew/test/formula_test.rb
+++ /dev/null
@@ -1,1205 +0,0 @@
-require "testing_env"
-require "test/support/fixtures/testball"
-require "formula"
-
-class FormulaTests < Homebrew::TestCase
- def test_formula_instantiation
- klass = Class.new(Formula) { url "http://example.com/foo-1.0.tar.gz" }
- name = "formula_name"
- path = Formulary.core_path(name)
- spec = :stable
-
- f = klass.new(name, path, spec)
- assert_equal name, f.name
- assert_equal name, f.specified_name
- assert_equal name, f.full_name
- assert_equal name, f.full_specified_name
- assert_equal path, f.path
- assert_nil f.alias_path
- assert_nil f.alias_name
- assert_nil f.full_alias_name
- assert_raises(ArgumentError) { klass.new }
- end
-
- def test_formula_instantiation_with_alias
- klass = Class.new(Formula) { url "http://example.com/foo-1.0.tar.gz" }
- name = "formula_name"
- path = Formulary.core_path(name)
- spec = :stable
- alias_name = "baz@1"
- alias_path = CoreTap.instance.alias_dir/alias_name
-
- f = klass.new(name, path, spec, alias_path: alias_path)
- assert_equal name, f.name
- assert_equal name, f.full_name
- assert_equal path, f.path
- assert_equal alias_path, f.alias_path
- assert_equal alias_name, f.alias_name
- assert_equal alias_name, f.specified_name
- assert_equal alias_name, f.full_alias_name
- assert_equal alias_name, f.full_specified_name
- assert_raises(ArgumentError) { klass.new }
- end
-
- def test_tap_formula_instantiation
- tap = Tap.new("foo", "bar")
- klass = Class.new(Formula) { url "baz-1.0" }
- name = "baz"
- full_name = "#{tap.user}/#{tap.repo}/#{name}"
- path = tap.path/"Formula/#{name}.rb"
- spec = :stable
-
- f = klass.new(name, path, spec)
- assert_equal name, f.name
- assert_equal name, f.specified_name
- assert_equal full_name, f.full_name
- assert_equal full_name, f.full_specified_name
- assert_equal path, f.path
- assert_nil f.alias_path
- assert_nil f.alias_name
- assert_nil f.full_alias_name
- assert_raises(ArgumentError) { klass.new }
- end
-
- def test_tap_formula_instantiation_with_alias
- tap = Tap.new("foo", "bar")
- klass = Class.new(Formula) { url "baz-1.0" }
- name = "baz"
- full_name = "#{tap.user}/#{tap.repo}/#{name}"
- path = tap.path/"Formula/#{name}.rb"
- spec = :stable
- alias_name = "baz@1"
- full_alias_name = "#{tap.user}/#{tap.repo}/#{alias_name}"
- alias_path = CoreTap.instance.alias_dir/alias_name
-
- f = klass.new(name, path, spec, alias_path: alias_path)
- assert_equal name, f.name
- assert_equal full_name, f.full_name
- assert_equal path, f.path
- assert_equal alias_path, f.alias_path
- assert_equal alias_name, f.alias_name
- assert_equal alias_name, f.specified_name
- assert_equal full_alias_name, f.full_alias_name
- assert_equal full_alias_name, f.full_specified_name
- assert_raises(ArgumentError) { klass.new }
- end
-
- def test_follow_installed_alias
- f = formula { url "foo-1.0" }
- assert_predicate f, :follow_installed_alias?
-
- f.follow_installed_alias = true
- assert_predicate f, :follow_installed_alias?
-
- f.follow_installed_alias = false
- refute_predicate f, :follow_installed_alias?
- end
-
- def test_installed_alias_with_core
- f = formula { url "foo-1.0" }
-
- build_values_with_no_installed_alias = [
- nil,
- BuildOptions.new({}, {}),
- Tab.new(source: { "path" => f.path.to_s }),
- ]
-
- build_values_with_no_installed_alias.each do |build|
- f.build = build
- assert_nil f.installed_alias_path
- assert_nil f.installed_alias_name
- assert_nil f.full_installed_alias_name
- assert_equal f.name, f.installed_specified_name
- assert_equal f.name, f.full_installed_specified_name
- end
-
- alias_name = "bar"
- alias_path = "#{CoreTap.instance.alias_dir}/#{alias_name}"
- f.build = Tab.new(source: { "path" => alias_path })
- assert_equal alias_path, f.installed_alias_path
- assert_equal alias_name, f.installed_alias_name
- assert_equal alias_name, f.full_installed_alias_name
- assert_equal alias_name, f.installed_specified_name
- assert_equal alias_name, f.full_installed_specified_name
- end
-
- def test_installed_alias_with_tap
- tap = Tap.new("user", "repo")
- name = "foo"
- path = "#{tap.path}/Formula/#{name}.rb"
- f = formula(name, path) { url "foo-1.0" }
-
- build_values_with_no_installed_alias = [
- nil,
- BuildOptions.new({}, {}),
- Tab.new(source: { "path" => f.path }),
- ]
-
- build_values_with_no_installed_alias.each do |build|
- f.build = build
- assert_nil f.installed_alias_path
- assert_nil f.installed_alias_name
- assert_nil f.full_installed_alias_name
- assert_equal f.name, f.installed_specified_name
- assert_equal f.full_name, f.full_installed_specified_name
- end
-
- alias_name = "bar"
- full_alias_name = "#{tap.user}/#{tap.repo}/#{alias_name}"
- alias_path = "#{tap.alias_dir}/#{alias_name}"
- f.build = Tab.new(source: { "path" => alias_path })
- assert_equal alias_path, f.installed_alias_path
- assert_equal alias_name, f.installed_alias_name
- assert_equal full_alias_name, f.full_installed_alias_name
- assert_equal alias_name, f.installed_specified_name
- assert_equal full_alias_name, f.full_installed_specified_name
- end
-
- def test_prefix
- f = Testball.new
- assert_equal HOMEBREW_CELLAR/f.name/"0.1", f.prefix
- assert_kind_of Pathname, f.prefix
- end
-
- def test_revised_prefix
- f = Class.new(Testball) { revision 1 }.new
- assert_equal HOMEBREW_CELLAR/f.name/"0.1_1", f.prefix
- end
-
- def test_any_version_installed?
- f = formula do
- url "foo"
- version "1.0"
- end
- refute_predicate f, :any_version_installed?
- prefix = HOMEBREW_CELLAR+f.name+"0.1"
- prefix.mkpath
- FileUtils.touch prefix+Tab::FILENAME
- assert_predicate f, :any_version_installed?
- end
-
- def test_migration_needed
- f = Testball.new("newname")
- f.instance_variable_set(:@oldname, "oldname")
- f.instance_variable_set(:@tap, CoreTap.instance)
-
- oldname_prefix = HOMEBREW_CELLAR/"oldname/2.20"
- newname_prefix = HOMEBREW_CELLAR/"newname/2.10"
- oldname_prefix.mkpath
- oldname_tab = Tab.empty
- oldname_tab.tabfile = oldname_prefix.join("INSTALL_RECEIPT.json")
- oldname_tab.write
-
- refute_predicate f, :migration_needed?
-
- oldname_tab.tabfile.unlink
- oldname_tab.source["tap"] = "homebrew/core"
- oldname_tab.write
-
- assert_predicate f, :migration_needed?
-
- newname_prefix.mkpath
-
- refute_predicate f, :migration_needed?
- end
-
- def test_installed?
- f = Testball.new
- f.stubs(:installed_prefix).returns(stub(directory?: false))
- refute_predicate f, :installed?
-
- f.stubs(:installed_prefix).returns(
- stub(directory?: true, children: []),
- )
- refute_predicate f, :installed?
-
- f.stubs(:installed_prefix).returns(
- stub(directory?: true, children: [stub]),
- )
- assert_predicate f, :installed?
- end
-
- def test_installed_prefix
- f = Testball.new
- assert_equal f.prefix, f.installed_prefix
- end
-
- def test_installed_prefix_head_installed
- f = formula do
- head "foo"
- devel do
- url "foo"
- version "1.0"
- end
- end
- prefix = HOMEBREW_CELLAR+f.name+f.head.version
- prefix.mkpath
- assert_equal prefix, f.installed_prefix
- end
-
- def test_installed_prefix_devel_installed
- f = formula do
- head "foo"
- devel do
- url "foo"
- version "1.0"
- end
- end
- prefix = HOMEBREW_CELLAR+f.name+f.devel.version
- prefix.mkpath
- assert_equal prefix, f.installed_prefix
- end
-
- def test_installed_prefix_stable_installed
- f = formula do
- head "foo"
- devel do
- url "foo"
- version "1.0-devel"
- end
- end
- prefix = HOMEBREW_CELLAR+f.name+f.version
- prefix.mkpath
- assert_equal prefix, f.installed_prefix
- end
-
- def test_installed_prefix_outdated_stable_head_installed
- f = formula do
- url "foo"
- version "1.9"
- head "foo"
- end
-
- head_prefix = HOMEBREW_CELLAR/"#{f.name}/HEAD"
- head_prefix.mkpath
- tab = Tab.empty
- tab.tabfile = head_prefix.join("INSTALL_RECEIPT.json")
- tab.source["versions"] = { "stable" => "1.0" }
- tab.write
-
- assert_equal HOMEBREW_CELLAR/"#{f.name}/#{f.version}", f.installed_prefix
- end
-
- def test_installed_prefix_outdated_devel_head_installed
- f = formula do
- url "foo"
- version "1.9"
- devel do
- url "foo"
- version "2.1"
- end
- end
-
- head_prefix = HOMEBREW_CELLAR/"#{f.name}/HEAD"
- head_prefix.mkpath
- tab = Tab.empty
- tab.tabfile = head_prefix.join("INSTALL_RECEIPT.json")
- tab.source["versions"] = { "stable" => "1.9", "devel" => "2.0" }
- tab.write
-
- assert_equal HOMEBREW_CELLAR/"#{f.name}/#{f.version}", f.installed_prefix
- end
-
- def test_installed_prefix_head
- f = formula("test", Pathname.new(__FILE__).expand_path, :head) do
- head "foo"
- devel do
- url "foo"
- version "1.0-devel"
- end
- end
- prefix = HOMEBREW_CELLAR+f.name+f.head.version
- assert_equal prefix, f.installed_prefix
- end
-
- def test_installed_prefix_devel
- f = formula("test", Pathname.new(__FILE__).expand_path, :devel) do
- head "foo"
- devel do
- url "foo"
- version "1.0-devel"
- end
- end
- prefix = HOMEBREW_CELLAR+f.name+f.devel.version
- assert_equal prefix, f.installed_prefix
- end
-
- def test_latest_head_prefix
- f = Testball.new
-
- stamps_with_revisions = [[111111, 1], [222222, 1], [222222, 2], [222222, 0]]
-
- stamps_with_revisions.each do |stamp, revision|
- version = "HEAD-#{stamp}"
- version += "_#{revision}" if revision > 0
- prefix = f.rack.join(version)
- prefix.mkpath
-
- tab = Tab.empty
- tab.tabfile = prefix.join("INSTALL_RECEIPT.json")
- tab.source_modified_time = stamp
- tab.write
- end
-
- prefix = HOMEBREW_CELLAR/"#{f.name}/HEAD-222222_2"
- assert_equal prefix, f.latest_head_prefix
- end
-
- def test_equality
- x = Testball.new
- y = Testball.new
- assert_equal x, y
- assert_eql x, y
- assert_equal x.hash, y.hash
- end
-
- def test_inequality
- x = Testball.new("foo")
- y = Testball.new("bar")
- refute_equal x, y
- refute_eql x, y
- refute_equal x.hash, y.hash
- end
-
- def test_comparison_with_non_formula_objects_does_not_raise
- refute_equal Testball.new, Object.new
- end
-
- def test_sort_operator
- assert_nil Testball.new <=> Object.new
- end
-
- def test_alias_paths_with_build_options
- alias_path = CoreTap.instance.alias_dir/"another_name"
- f = formula(alias_path: alias_path) { url "foo-1.0" }
- f.build = BuildOptions.new({}, {})
- assert_equal alias_path, f.alias_path
- assert_nil f.installed_alias_path
- end
-
- def test_alias_paths_with_tab_with_non_alias_source_path
- alias_path = CoreTap.instance.alias_dir/"another_name"
- source_path = CoreTap.instance.formula_dir/"another_other_name"
- f = formula(alias_path: alias_path) { url "foo-1.0" }
- f.build = Tab.new(source: { "path" => source_path.to_s })
- assert_equal alias_path, f.alias_path
- assert_nil f.installed_alias_path
- end
-
- def test_alias_paths_with_tab_with_alias_source_path
- alias_path = CoreTap.instance.alias_dir/"another_name"
- source_path = CoreTap.instance.alias_dir/"another_other_name"
- f = formula(alias_path: alias_path) { url "foo-1.0" }
- f.build = Tab.new(source: { "path" => source_path.to_s })
- assert_equal alias_path, f.alias_path
- assert_equal source_path.to_s, f.installed_alias_path
- end
-
- def test_installed_with_alias_path_with_nil
- assert_predicate Formula.installed_with_alias_path(nil), :empty?
- end
-
- def test_installed_with_alias_path_with_a_path
- alias_path = "#{CoreTap.instance.alias_dir}/alias"
- different_alias_path = "#{CoreTap.instance.alias_dir}/another_alias"
-
- formula_with_alias = formula("foo") { url "foo-1.0" }
- formula_with_alias.build = Tab.empty
- formula_with_alias.build.source["path"] = alias_path
-
- formula_without_alias = formula("bar") { url "bar-1.0" }
- formula_without_alias.build = Tab.empty
- formula_without_alias.build.source["path"] = formula_without_alias.path.to_s
-
- formula_with_different_alias = formula("baz") { url "baz-1.0" }
- formula_with_different_alias.build = Tab.empty
- formula_with_different_alias.build.source["path"] = different_alias_path
-
- formulae = [
- formula_with_alias,
- formula_without_alias,
- formula_with_different_alias,
- ]
-
- Formula.stubs(:installed).returns(formulae)
- assert_equal [formula_with_alias], Formula.installed_with_alias_path(alias_path)
- end
-
- def test_formula_spec_integration
- f = formula do
- homepage "http://example.com"
- url "http://example.com/test-0.1.tbz"
- mirror "http://example.org/test-0.1.tbz"
- sha256 TEST_SHA256
-
- head "http://example.com/test.git", tag: "foo"
-
- devel do
- url "http://example.com/test-0.2.tbz"
- mirror "http://example.org/test-0.2.tbz"
- sha256 TEST_SHA256
- end
- end
-
- assert_equal "http://example.com", f.homepage
- assert_version_equal "0.1", f.version
- assert_predicate f, :stable?
-
- assert_version_equal "0.1", f.stable.version
- assert_version_equal "0.2", f.devel.version
- assert_version_equal "HEAD", f.head.version
- end
-
- def test_formula_active_spec=
- f = formula do
- url "foo"
- version "1.0"
- revision 1
-
- devel do
- url "foo"
- version "1.0beta"
- end
- end
- assert_equal :stable, f.active_spec_sym
- assert_equal f.stable, f.send(:active_spec)
- assert_equal "1.0_1", f.pkg_version.to_s
- f.active_spec = :devel
- assert_equal :devel, f.active_spec_sym
- assert_equal f.devel, f.send(:active_spec)
- assert_equal "1.0beta_1", f.pkg_version.to_s
- assert_raises(FormulaSpecificationError) { f.active_spec = :head }
- end
-
- def test_path
- name = "foo-bar"
- assert_equal Pathname.new("#{HOMEBREW_LIBRARY}/Taps/homebrew/homebrew-core/Formula/#{name}.rb"), Formulary.core_path(name)
- end
-
- def test_class_specs_are_always_initialized
- f = formula { url "foo-1.0" }
-
- %w[stable devel head].each do |spec|
- assert_kind_of SoftwareSpec, f.class.send(spec)
- end
- end
-
- def test_incomplete_instance_specs_are_not_accessible
- f = formula { url "foo-1.0" }
-
- %w[devel head].each { |spec| assert_nil f.send(spec) }
- end
-
- def test_honors_attributes_declared_before_specs
- f = formula do
- url "foo-1.0"
- depends_on "foo"
- devel { url "foo-1.1" }
- end
-
- %w[stable devel head].each do |spec|
- assert_equal "foo", f.class.send(spec).deps.first.name
- end
- end
-
- def test_simple_version
- assert_equal PkgVersion.parse("1.0"), formula { url "foo-1.0.bar" }.pkg_version
- end
-
- def test_version_with_revision
- f = formula do
- url "foo-1.0.bar"
- revision 1
- end
-
- assert_equal PkgVersion.parse("1.0_1"), f.pkg_version
- end
-
- def test_head_uses_revisions
- f = formula("test", Pathname.new(__FILE__).expand_path, :head) do
- url "foo-1.0.bar"
- revision 1
- head "foo"
- end
-
- assert_equal PkgVersion.parse("HEAD_1"), f.pkg_version
- end
-
- def test_update_head_version
- f = formula do
- head "foo", using: :git
- end
-
- cached_location = f.head.downloader.cached_location
- cached_location.mkpath
-
- cached_location.cd do
- FileUtils.touch "LICENSE"
- shutup do
- system "git", "init"
- system "git", "add", "--all"
- system "git", "commit", "-m", "Initial commit"
- end
- end
-
- f.update_head_version
- assert_equal Version.create("HEAD-5658946"), f.head.version
- end
-
- def test_legacy_options
- f = formula do
- url "foo-1.0"
-
- def options
- [["--foo", "desc"], ["--bar", "desc"]]
- end
-
- option "baz"
- end
-
- assert f.option_defined?("foo")
- assert f.option_defined?("bar")
- assert f.option_defined?("baz")
- end
-
- def test_desc
- f = formula do
- desc "a formula"
- url "foo-1.0"
- end
-
- assert_equal "a formula", f.desc
- end
-
- def test_post_install_defined
- f1 = formula do
- url "foo-1.0"
-
- def post_install; end
- end
-
- f2 = formula do
- url "foo-1.0"
- end
-
- assert f1.post_install_defined?
- refute f2.post_install_defined?
- end
-
- def test_test_defined
- f1 = formula do
- url "foo-1.0"
-
- def test; end
- end
-
- f2 = formula do
- url "foo-1.0"
- end
-
- assert f1.test_defined?
- refute f2.test_defined?
- end
-
- def test_test_fixtures
- f1 = formula do
- url "foo-1.0"
- end
-
- assert_equal Pathname.new("#{HOMEBREW_LIBRARY_PATH}/test/support/fixtures/foo"),
- f1.test_fixtures("foo")
- end
-
- def test_dependencies
- stub_formula_loader formula("f1") { url "f1-1.0" }
- stub_formula_loader formula("f2") { url "f2-1.0" }
-
- f3 = formula("f3") do
- url "f3-1.0"
- depends_on "f1" => :build
- depends_on "f2"
- end
- stub_formula_loader f3
-
- f4 = formula("f4") do
- url "f4-1.0"
- depends_on "f1"
- end
- stub_formula_loader f4
-
- f5 = formula("f5") do
- url "f5-1.0"
- depends_on "f3" => :build
- depends_on "f4"
- end
-
- assert_equal %w[f3 f4], f5.deps.map(&:name)
- assert_equal %w[f1 f2 f3 f4], f5.recursive_dependencies.map(&:name)
- assert_equal %w[f1 f4], f5.runtime_dependencies.map(&:name)
- end
-
- def test_runtime_dependencies_with_optional_deps_from_tap
- tap_loader = mock
- tap_loader.stubs(:get_formula).raises(RuntimeError, "tried resolving tap formula")
- Formulary.stubs(:loader_for).with("foo/bar/f1", from: nil).returns(tap_loader)
-
- stub_formula_loader formula("f2") { url "f2-1.0" }, "baz/qux/f2"
-
- f3 = formula("f3") do
- url "f3-1.0"
- depends_on "foo/bar/f1" => :optional
- depends_on "baz/qux/f2"
- end
-
- # f1 shouldn't be loaded by default.
- # If it is, an exception will be raised.
- assert_equal %w[baz/qux/f2], f3.runtime_dependencies.map(&:name)
-
- # If --with-f1, f1 should be loaded.
- stub_formula_loader formula("f1") { url "f1-1.0" }, "foo/bar/f1"
- f3.build = BuildOptions.new(Options.create(%w[--with-f1]), f3.options)
- assert_equal %w[foo/bar/f1 baz/qux/f2], f3.runtime_dependencies.map(&:name)
- end
-
- def test_requirements
- f1 = formula("f1") do
- url "f1-1"
-
- depends_on :python
- depends_on x11: :recommended
- depends_on xcode: ["1.0", :optional]
- end
- stub_formula_loader f1
-
- python = PythonRequirement.new
- x11 = X11Requirement.new("x11", [:recommended])
- xcode = XcodeRequirement.new(["1.0", :optional])
-
- # Default block should filter out deps that aren't being used
- assert_equal Set[python, x11], Set.new(f1.recursive_requirements)
-
- f1.build = BuildOptions.new(["--with-xcode", "--without-x11"], f1.options)
- assert_equal Set[python, xcode], Set.new(f1.recursive_requirements)
- f1.build = f1.stable.build
-
- f2 = formula("f2") do
- url "f2-1"
- depends_on "f1"
- end
-
- assert_equal Set[python, x11], Set.new(f2.recursive_requirements)
-
- # Empty block should allow all requirements
- assert_equal Set[python, x11, xcode], Set.new(f2.recursive_requirements {})
-
- # Requirements can be pruned
- requirements = f2.recursive_requirements do |_dependent, requirement|
- Requirement.prune if requirement.is_a?(PythonRequirement)
- end
- assert_equal Set[x11, xcode], Set.new(requirements)
- end
-
- def test_to_hash
- f1 = formula("foo") do
- url "foo-1.0"
- end
-
- h = f1.to_hash
- assert h.is_a?(Hash), "Formula#to_hash should return a Hash"
- assert_equal "foo", h["name"]
- assert_equal "foo", h["full_name"]
- assert_equal "1.0", h["versions"]["stable"]
- end
-
- def test_to_hash_bottle
- f1 = formula("foo") do
- url "foo-1.0"
-
- bottle do
- cellar :any
- sha256 TEST_SHA256 => Utils::Bottles.tag
- end
- end
-
- h = f1.to_hash
- assert h.is_a?(Hash), "Formula#to_hash should return a Hash"
- assert h["versions"]["bottle"], "The hash should say the formula is bottled"
- end
-
- def test_eligible_kegs_for_cleanup
- f1 = Class.new(Testball) do
- version "1.0"
- end.new
- f2 = Class.new(Testball) do
- version "0.2"
- version_scheme 1
- end.new
- f3 = Class.new(Testball) do
- version "0.3"
- version_scheme 1
- end.new
- f4 = Class.new(Testball) do
- version "0.1"
- version_scheme 2
- end.new
-
- shutup do
- [f1, f2, f3, f4].each do |f|
- f.brew { f.install }
- Tab.create(f, DevelopmentTools.default_compiler, :libcxx).write
- end
- end
-
- assert_predicate f1, :installed?
- assert_predicate f2, :installed?
- assert_predicate f3, :installed?
- assert_predicate f4, :installed?
-
- assert_equal [f2, f1].map { |f| Keg.new(f.prefix) },
- f3.eligible_kegs_for_cleanup.sort_by(&:version)
- end
-
- def test_eligible_kegs_for_cleanup_keg_pinned
- f1 = Class.new(Testball) { version "0.1" }.new
- f2 = Class.new(Testball) { version "0.2" }.new
- f3 = Class.new(Testball) { version "0.3" }.new
-
- shutup do
- f1.brew { f1.install }
- f1.pin
- f2.brew { f2.install }
- f3.brew { f3.install }
- end
-
- assert_equal (HOMEBREW_PINNED_KEGS/f1.name).resolved_path, f1.prefix
-
- assert_predicate f1, :installed?
- assert_predicate f2, :installed?
- assert_predicate f3, :installed?
-
- assert_equal [Keg.new(f2.prefix)], shutup { f3.eligible_kegs_for_cleanup }
- end
-
- def test_eligible_kegs_for_cleanup_head_installed
- f = formula do
- version "0.1"
- head "foo"
- end
-
- stable_prefix = f.installed_prefix
- stable_prefix.mkpath
-
- [["000000_1", 1], ["111111", 2], ["111111_1", 2]].each do |pkg_version_suffix, stamp|
- prefix = f.prefix("HEAD-#{pkg_version_suffix}")
- prefix.mkpath
- tab = Tab.empty
- tab.tabfile = prefix.join("INSTALL_RECEIPT.json")
- tab.source_modified_time = stamp
- tab.write
- end
-
- eligible_kegs = f.installed_kegs - [Keg.new(f.prefix("HEAD-111111_1"))]
- assert_equal eligible_kegs, f.eligible_kegs_for_cleanup
- end
-
- def test_pour_bottle
- f_false = formula("foo") do
- url "foo-1.0"
- def pour_bottle?
- false
- end
- end
- refute f_false.pour_bottle?
-
- f_true = formula("foo") do
- url "foo-1.0"
- def pour_bottle?
- true
- end
- end
- assert f_true.pour_bottle?
- end
-
- def test_pour_bottle_dsl
- f_false = formula("foo") do
- url "foo-1.0"
- pour_bottle? do
- reason "false reason"
- satisfy { var == etc }
- end
- end
- refute f_false.pour_bottle?
-
- f_true = formula("foo") do
- url "foo-1.0"
- pour_bottle? do
- reason "true reason"
- satisfy { true }
- end
- end
- assert f_true.pour_bottle?
- end
-end
-
-class AliasChangeTests < Homebrew::TestCase
- attr_reader :f, :new_formula, :tab, :alias_path
-
- def make_formula(name, version)
- f = formula(name, alias_path: alias_path) { url "foo-#{version}" }
- f.build = tab
- f
- end
-
- def setup
- super
-
- alias_name = "bar"
- @alias_path = "#{CoreTap.instance.alias_dir}/#{alias_name}"
-
- @tab = Tab.empty
-
- @f = make_formula("formula_name", "1.0")
- @new_formula = make_formula("new_formula_name", "1.1")
-
- Formula.stubs(:installed).returns([f])
- end
-
- def test_alias_changes_when_not_installed_with_alias
- tab.source["path"] = Formulary.core_path(f.name).to_s
-
- assert_nil f.current_installed_alias_target
- assert_equal f, f.latest_formula
- refute_predicate f, :installed_alias_target_changed?
- refute_predicate f, :supersedes_an_installed_formula?
- refute_predicate f, :alias_changed?
- assert_predicate f.old_installed_formulae, :empty?
- end
-
- def test_alias_changes_when_not_changed
- tab.source["path"] = alias_path
- stub_formula_loader(f, alias_path)
-
- assert_equal f, f.current_installed_alias_target
- assert_equal f, f.latest_formula
- refute_predicate f, :installed_alias_target_changed?
- refute_predicate f, :supersedes_an_installed_formula?
- refute_predicate f, :alias_changed?
- assert_predicate f.old_installed_formulae, :empty?
- end
-
- def test_alias_changes_when_new_alias_target
- tab.source["path"] = alias_path
- stub_formula_loader(new_formula, alias_path)
-
- assert_equal new_formula, f.current_installed_alias_target
- assert_equal new_formula, f.latest_formula
- assert_predicate f, :installed_alias_target_changed?
- refute_predicate f, :supersedes_an_installed_formula?
- assert_predicate f, :alias_changed?
- assert_predicate f.old_installed_formulae, :empty?
- end
-
- def test_alias_changes_when_old_formulae_installed
- tab.source["path"] = alias_path
- stub_formula_loader(new_formula, alias_path)
-
- assert_equal new_formula, new_formula.current_installed_alias_target
- assert_equal new_formula, new_formula.latest_formula
- refute_predicate new_formula, :installed_alias_target_changed?
- assert_predicate new_formula, :supersedes_an_installed_formula?
- assert_predicate new_formula, :alias_changed?
- assert_equal [f], new_formula.old_installed_formulae
- end
-end
-
-class OutdatedVersionsTests < Homebrew::TestCase
- attr_reader :outdated_prefix,
- :same_prefix,
- :greater_prefix,
- :head_prefix,
- :old_alias_target_prefix
- attr_reader :f, :old_formula, :new_formula
-
- def setup
- super
-
- @f = formula do
- url "foo"
- version "1.20"
- end
-
- @old_formula = formula("foo@1") { url "foo-1.0" }
- @new_formula = formula("foo@2") { url "foo-2.0" }
-
- @outdated_prefix = HOMEBREW_CELLAR/"#{f.name}/1.11"
- @same_prefix = HOMEBREW_CELLAR/"#{f.name}/1.20"
- @greater_prefix = HOMEBREW_CELLAR/"#{f.name}/1.21"
- @head_prefix = HOMEBREW_CELLAR/"#{f.name}/HEAD"
- @old_alias_target_prefix = HOMEBREW_CELLAR/"#{old_formula.name}/1.0"
- end
-
- def alias_path
- "#{@f.tap.alias_dir}/bar"
- end
-
- def setup_tab_for_prefix(prefix, options = {})
- prefix.mkpath
- tab = Tab.empty
- tab.tabfile = prefix.join("INSTALL_RECEIPT.json")
- tab.source["path"] = options[:path].to_s if options[:path]
- tab.source["tap"] = options[:tap] if options[:tap]
- tab.source["versions"] = options[:versions] if options[:versions]
- tab.source_modified_time = options[:source_modified_time].to_i
- tab.write unless options[:no_write]
- tab
- end
-
- def reset_outdated_kegs
- f.instance_variable_set(:@outdated_kegs, nil)
- end
-
- def test_greater_different_tap_installed
- setup_tab_for_prefix(greater_prefix, tap: "user/repo")
- assert_predicate f.outdated_kegs, :empty?
- end
-
- def test_greater_same_tap_installed
- f.instance_variable_set(:@tap, CoreTap.instance)
- setup_tab_for_prefix(greater_prefix, tap: "homebrew/core")
- assert_predicate f.outdated_kegs, :empty?
- end
-
- def test_outdated_different_tap_installed
- setup_tab_for_prefix(outdated_prefix, tap: "user/repo")
- refute_predicate f.outdated_kegs, :empty?
- end
-
- def test_outdated_same_tap_installed
- f.instance_variable_set(:@tap, CoreTap.instance)
- setup_tab_for_prefix(outdated_prefix, tap: "homebrew/core")
- refute_predicate f.outdated_kegs, :empty?
- end
-
- def test_outdated_follow_alias_and_alias_unchanged
- f.follow_installed_alias = true
- f.build = setup_tab_for_prefix(same_prefix, path: alias_path)
- stub_formula_loader(f, alias_path)
- assert_predicate f.outdated_kegs, :empty?
- end
-
- def test_outdated_follow_alias_and_alias_changed_and_new_target_not_installed
- f.follow_installed_alias = true
- f.build = setup_tab_for_prefix(same_prefix, path: alias_path)
- stub_formula_loader(new_formula, alias_path)
- refute_predicate f.outdated_kegs, :empty?
- end
-
- def test_outdated_follow_alias_and_alias_changed_and_new_target_installed
- f.follow_installed_alias = true
- f.build = setup_tab_for_prefix(same_prefix, path: alias_path)
- stub_formula_loader(new_formula, alias_path)
- setup_tab_for_prefix(new_formula.prefix) # install new_formula
- assert_predicate f.outdated_kegs, :empty?
- end
-
- def test_outdated_no_follow_alias_and_alias_unchanged
- f.follow_installed_alias = false
- f.build = setup_tab_for_prefix(same_prefix, path: alias_path)
- stub_formula_loader(f, alias_path)
- assert_predicate f.outdated_kegs, :empty?
- end
-
- def test_outdated_no_follow_alias_and_alias_changed
- f.follow_installed_alias = false
- f.build = setup_tab_for_prefix(same_prefix, path: alias_path)
- stub_formula_loader(formula("foo@2") { url "foo-2.0" }, alias_path)
- assert_predicate f.outdated_kegs, :empty?
- end
-
- def test_outdated_old_alias_targets_installed
- @f = formula(alias_path: alias_path) { url "foo-1.0" }
- tab = setup_tab_for_prefix(old_alias_target_prefix, path: alias_path)
- old_formula.build = tab
- Formula.stubs(:installed).returns([old_formula])
- refute_predicate f.outdated_kegs, :empty?
- end
-
- def test_outdated_old_alias_targets_not_installed
- @f = formula(alias_path: alias_path) { url "foo-1.0" }
- tab = setup_tab_for_prefix(old_alias_target_prefix, path: old_formula.path)
- old_formula.build = tab
- Formula.stubs(:installed).returns([old_formula])
- assert_predicate f.outdated_kegs, :empty?
- end
-
- def test_outdated_same_head_installed
- f.instance_variable_set(:@tap, CoreTap.instance)
- setup_tab_for_prefix(head_prefix, tap: "homebrew/core")
- assert_predicate f.outdated_kegs, :empty?
- end
-
- def test_outdated_different_head_installed
- f.instance_variable_set(:@tap, CoreTap.instance)
- setup_tab_for_prefix(head_prefix, tap: "user/repo")
- assert_predicate f.outdated_kegs, :empty?
- end
-
- def test_outdated_mixed_taps_greater_version_installed
- f.instance_variable_set(:@tap, CoreTap.instance)
- setup_tab_for_prefix(outdated_prefix, tap: "homebrew/core")
- setup_tab_for_prefix(greater_prefix, tap: "user/repo")
-
- assert_predicate f.outdated_kegs, :empty?
-
- setup_tab_for_prefix(greater_prefix, tap: "homebrew/core")
- reset_outdated_kegs
-
- assert_predicate f.outdated_kegs, :empty?
- end
-
- def test_outdated_mixed_taps_outdated_version_installed
- f.instance_variable_set(:@tap, CoreTap.instance)
-
- extra_outdated_prefix = HOMEBREW_CELLAR/"#{f.name}/1.0"
-
- setup_tab_for_prefix(outdated_prefix)
- setup_tab_for_prefix(extra_outdated_prefix, tap: "homebrew/core")
- reset_outdated_kegs
-
- refute_predicate f.outdated_kegs, :empty?
-
- setup_tab_for_prefix(outdated_prefix, tap: "user/repo")
- reset_outdated_kegs
-
- refute_predicate f.outdated_kegs, :empty?
- end
-
- def test_outdated_same_version_tap_installed
- f.instance_variable_set(:@tap, CoreTap.instance)
- setup_tab_for_prefix(same_prefix, tap: "homebrew/core")
-
- assert_predicate f.outdated_kegs, :empty?
-
- setup_tab_for_prefix(same_prefix, tap: "user/repo")
- reset_outdated_kegs
-
- assert_predicate f.outdated_kegs, :empty?
- end
-
- def test_outdated_installed_head_less_than_stable
- tab = setup_tab_for_prefix(head_prefix, versions: { "stable" => "1.0" })
- refute_predicate f.outdated_kegs, :empty?
-
- # Tab.for_keg(head_prefix) will be fetched from CACHE but we write it anyway
- tab.source["versions"] = { "stable" => f.version.to_s }
- tab.write
- reset_outdated_kegs
-
- assert_predicate f.outdated_kegs, :empty?
- end
-
- def test_outdated_fetch_head
- outdated_stable_prefix = HOMEBREW_CELLAR.join("testball/1.0")
- head_prefix_a = HOMEBREW_CELLAR.join("testball/HEAD")
- head_prefix_b = HOMEBREW_CELLAR.join("testball/HEAD-aaaaaaa_1")
- head_prefix_c = HOMEBREW_CELLAR.join("testball/HEAD-18a7103")
-
- setup_tab_for_prefix(outdated_stable_prefix)
- tab_a = setup_tab_for_prefix(head_prefix_a, versions: { "stable" => "1.0" })
- setup_tab_for_prefix(head_prefix_b)
-
- testball_repo = HOMEBREW_PREFIX.join("testball_repo")
- testball_repo.mkdir
-
- @f = formula("testball") do
- url "foo"
- version "2.10"
- head "file://#{testball_repo}", using: :git
- end
-
- testball_repo.cd do
- FileUtils.touch "LICENSE"
- shutup do
- system "git", "init"
- system "git", "add", "--all"
- system "git", "commit", "-m", "Initial commit"
- end
- end
-
- refute_predicate f.outdated_kegs(fetch_head: true), :empty?
-
- tab_a.source["versions"] = { "stable" => f.version.to_s }
- tab_a.write
- reset_outdated_kegs
- refute_predicate f.outdated_kegs(fetch_head: true), :empty?
-
- head_prefix_a.rmtree
- reset_outdated_kegs
- refute_predicate f.outdated_kegs(fetch_head: true), :empty?
-
- setup_tab_for_prefix(head_prefix_c, source_modified_time: 1)
- reset_outdated_kegs
- assert_predicate f.outdated_kegs(fetch_head: true), :empty?
- ensure
- testball_repo.rmtree if testball_repo.exist?
- end
-
- def test_outdated_kegs_version_scheme_changed
- @f = formula("testball") do
- url "foo"
- version "20141010"
- version_scheme 1
- end
-
- prefix = HOMEBREW_CELLAR.join("testball/0.1")
- setup_tab_for_prefix(prefix, versions: { "stable" => "0.1" })
-
- refute_predicate f.outdated_kegs, :empty?
- end
-
- def test_outdated_kegs_mixed_version_schemes
- @f = formula("testball") do
- url "foo"
- version "20141010"
- version_scheme 3
- end
-
- prefix_a = HOMEBREW_CELLAR.join("testball/20141009")
- setup_tab_for_prefix(prefix_a, versions: { "stable" => "20141009", "version_scheme" => 1 })
-
- prefix_b = HOMEBREW_CELLAR.join("testball/2.14")
- setup_tab_for_prefix(prefix_b, versions: { "stable" => "2.14", "version_scheme" => 2 })
-
- refute_predicate f.outdated_kegs, :empty?
- reset_outdated_kegs
-
- prefix_c = HOMEBREW_CELLAR.join("testball/20141009")
- setup_tab_for_prefix(prefix_c, versions: { "stable" => "20141009", "version_scheme" => 3 })
-
- refute_predicate f.outdated_kegs, :empty?
- reset_outdated_kegs
-
- prefix_d = HOMEBREW_CELLAR.join("testball/20141011")
- setup_tab_for_prefix(prefix_d, versions: { "stable" => "20141009", "version_scheme" => 3 })
- assert_predicate f.outdated_kegs, :empty?
- end
-
- def test_outdated_kegs_head_with_version_scheme
- @f = formula("testball") do
- url "foo"
- version "1.0"
- version_scheme 2
- end
-
- head_prefix = HOMEBREW_CELLAR.join("testball/HEAD")
-
- setup_tab_for_prefix(head_prefix, versions: { "stable" => "1.0", "version_scheme" => 1 })
- refute_predicate f.outdated_kegs, :empty?
-
- reset_outdated_kegs
- head_prefix.rmtree
-
- setup_tab_for_prefix(head_prefix, versions: { "stable" => "1.0", "version_scheme" => 2 })
- assert_predicate f.outdated_kegs, :empty?
- end
-end
diff --git a/Library/Homebrew/test/formulary_spec.rb b/Library/Homebrew/test/formulary_spec.rb
index 8e9d23589..213ad511d 100644
--- a/Library/Homebrew/test/formulary_spec.rb
+++ b/Library/Homebrew/test/formulary_spec.rb
@@ -216,4 +216,12 @@ describe Formulary do
end
end
end
+
+ describe "::core_path" do
+ it "returns the path to a Formula in the core tap" do
+ name = "foo-bar"
+ expect(subject.core_path(name))
+ .to eq(Pathname.new("#{HOMEBREW_LIBRARY}/Taps/homebrew/homebrew-core/Formula/#{name}.rb"))
+ end
+ end
end
diff --git a/Library/Homebrew/test/help_test.rb b/Library/Homebrew/test/help_test.rb
deleted file mode 100644
index 92dd99721..000000000
--- a/Library/Homebrew/test/help_test.rb
+++ /dev/null
@@ -1,21 +0,0 @@
-require "testing_env"
-
-class IntegrationCommandTestHelp < IntegrationCommandTestCase
- def test_help
- assert_match "Example usage:\n",
- cmd_fail # Generic help (empty argument list).
- assert_match "Unknown command: command-that-does-not-exist",
- cmd_fail("help", "command-that-does-not-exist")
- assert_match(/^brew cat /,
- cmd_fail("cat")) # Missing formula argument triggers help.
-
- assert_match "Example usage:\n",
- cmd("help") # Generic help.
- assert_match(/^brew cat /,
- cmd("help", "cat")) # Internal command (documented, Ruby).
- assert_match(/^brew update /,
- cmd("help", "update")) # Internal command (documented, Shell).
- assert_match(/^brew update-test /,
- cmd("help", "update-test")) # Internal developer command (documented, Ruby).
- end
-end
diff --git a/Library/Homebrew/test/home_test.rb b/Library/Homebrew/test/home_test.rb
deleted file mode 100644
index ff06b72c1..000000000
--- a/Library/Homebrew/test/home_test.rb
+++ /dev/null
@@ -1,12 +0,0 @@
-require "testing_env"
-
-class IntegrationCommandTestHome < IntegrationCommandTestCase
- def test_home
- setup_test_formula "testball"
-
- assert_equal HOMEBREW_WWW,
- cmd("home", "HOMEBREW_BROWSER" => "echo")
- assert_equal Formula["testball"].homepage,
- cmd("home", "testball", "HOMEBREW_BROWSER" => "echo")
- end
-end
diff --git a/Library/Homebrew/test/info_test.rb b/Library/Homebrew/test/info_test.rb
deleted file mode 100644
index f71044bf0..000000000
--- a/Library/Homebrew/test/info_test.rb
+++ /dev/null
@@ -1,29 +0,0 @@
-require "testing_env"
-require "cmd/info"
-require "formula"
-require "testing_env"
-
-class IntegrationCommandTestInfo < IntegrationCommandTestCase
- def test_info
- setup_test_formula "testball"
-
- assert_match "testball: stable 0.1",
- cmd("info", "testball")
- end
-end
-
-class InfoCommandTests < Homebrew::TestCase
- def test_github_remote_path
- remote = "https://github.com/Homebrew/homebrew-core"
- assert_equal "https://github.com/Homebrew/homebrew-core/blob/master/Formula/git.rb",
- Homebrew.github_remote_path(remote, "Formula/git.rb")
- assert_equal "https://github.com/Homebrew/homebrew-core/blob/master/Formula/git.rb",
- Homebrew.github_remote_path("#{remote}.git", "Formula/git.rb")
-
- assert_equal "https://github.com/user/repo/blob/master/foo.rb",
- Homebrew.github_remote_path("git@github.com:user/repo", "foo.rb")
-
- assert_equal "https://mywebsite.com/foo/bar.rb",
- Homebrew.github_remote_path("https://mywebsite.com", "foo/bar.rb")
- end
-end
diff --git a/Library/Homebrew/test/inreplace_spec.rb b/Library/Homebrew/test/inreplace_spec.rb
new file mode 100644
index 000000000..5be44f50d
--- /dev/null
+++ b/Library/Homebrew/test/inreplace_spec.rb
@@ -0,0 +1,251 @@
+require "extend/string"
+require "tempfile"
+require "utils/inreplace"
+
+describe StringInreplaceExtension do
+ subject { string.extend(described_class) }
+
+ describe "#change_make_var!" do
+ context "flag" do
+ context "with spaces" do
+ let(:string) do
+ <<-EOS.undent
+ OTHER=def
+ FLAG = abc
+ FLAG2=abc
+ EOS
+ end
+
+ it "is successfully replaced" do
+ subject.change_make_var! "FLAG", "def"
+ expect(subject).to eq <<-EOS.undent
+ OTHER=def
+ FLAG=def
+ FLAG2=abc
+ EOS
+ end
+
+ it "is successfully appended" do
+ subject.change_make_var! "FLAG", "\\1 def"
+ expect(subject).to eq <<-EOS.undent
+ OTHER=def
+ FLAG=abc def
+ FLAG2=abc
+ EOS
+ end
+ end
+
+ context "with tabs" do
+ let(:string) do
+ <<-EOS.undent
+ CFLAGS\t=\t-Wall -O2
+ LDFLAGS\t=\t-lcrypto -lssl
+ EOS
+ end
+
+ it "is successfully replaced" do
+ subject.change_make_var! "CFLAGS", "-O3"
+ expect(subject).to eq <<-EOS.undent
+ CFLAGS=-O3
+ LDFLAGS\t=\t-lcrypto -lssl
+ EOS
+ end
+ end
+ end
+
+ context "empty flag between other flags" do
+ let(:string) do
+ <<-EOS.undent
+ OTHER=def
+ FLAG =
+ FLAG2=abc
+ EOS
+ end
+
+ it "is successfully replaced" do
+ subject.change_make_var! "FLAG", "def"
+ expect(subject).to eq <<-EOS.undent
+ OTHER=def
+ FLAG=def
+ FLAG2=abc
+ EOS
+ end
+ end
+
+ context "empty flag" do
+ let(:string) do
+ <<-EOS.undent
+ FLAG =
+ mv file_a file_b
+ EOS
+ end
+
+ it "is successfully replaced" do
+ subject.change_make_var! "FLAG", "def"
+ expect(subject).to eq <<-EOS.undent
+ FLAG=def
+ mv file_a file_b
+ EOS
+ end
+ end
+
+ context "shell-style variable" do
+ let(:string) do
+ <<-EOS.undent
+ OTHER=def
+ FLAG=abc
+ FLAG2=abc
+ EOS
+ end
+
+ it "is successfully replaced" do
+ subject.change_make_var! "FLAG", "def"
+ expect(subject).to eq <<-EOS.undent
+ OTHER=def
+ FLAG=def
+ FLAG2=abc
+ EOS
+ end
+ end
+ end
+
+ describe "#remove_make_var!" do
+ context "flag" do
+ context "with spaces" do
+ let(:string) do
+ <<-EOS.undent
+ OTHER=def
+ FLAG = abc
+ FLAG2 = def
+ EOS
+ end
+
+ it "is successfully removed" do
+ subject.remove_make_var! "FLAG"
+ expect(subject).to eq <<-EOS.undent
+ OTHER=def
+ FLAG2 = def
+ EOS
+ end
+ end
+
+ context "with tabs" do
+ let(:string) do
+ <<-EOS.undent
+ CFLAGS\t=\t-Wall -O2
+ LDFLAGS\t=\t-lcrypto -lssl
+ EOS
+ end
+
+ it "is successfully removed" do
+ subject.remove_make_var! "LDFLAGS"
+ expect(subject).to eq <<-EOS.undent
+ CFLAGS\t=\t-Wall -O2
+ EOS
+ end
+ end
+ end
+
+ context "multiple flags" do
+ let(:string) do
+ <<-EOS.undent
+ OTHER=def
+ FLAG = abc
+ FLAG2 = def
+ OTHER2=def
+ EOS
+ end
+
+ specify "are be successfully removed" do
+ subject.remove_make_var! ["FLAG", "FLAG2"]
+ expect(subject).to eq <<-EOS.undent
+ OTHER=def
+ OTHER2=def
+ EOS
+ end
+ end
+ end
+
+ describe "#get_make_var" do
+ context "with spaces" do
+ let(:string) do
+ <<-EOS.undent
+ CFLAGS = -Wall -O2
+ LDFLAGS = -lcrypto -lssl
+ EOS
+ end
+
+ it "extracts the value for a given variable" do
+ expect(subject.get_make_var("CFLAGS")).to eq("-Wall -O2")
+ end
+ end
+
+ context "with tabs" do
+ let(:string) do
+ <<-EOS.undent
+ CFLAGS\t=\t-Wall -O2
+ LDFLAGS\t=\t-lcrypto -lssl
+ EOS
+ end
+
+ it "extracts the value for a given variable" do
+ expect(subject.get_make_var("CFLAGS")).to eq("-Wall -O2")
+ end
+ end
+ end
+
+ describe "#sub!" do
+ let(:string) { "foo" }
+
+ it "replaces the first occurence" do
+ subject.sub!("o", "e")
+ expect(subject).to eq("feo")
+ end
+ end
+
+ describe "#gsub!" do
+ let(:string) { "foo" }
+
+ it "replaces the all occurences" do
+ subject.gsub!("o", "e") # rubocop:disable Performance/StringReplacement
+ expect(subject).to eq("fee")
+ end
+ end
+end
+
+describe Utils::Inreplace do
+ let(:file) { Tempfile.new("test") }
+
+ before(:each) do
+ file.write <<-EOS.undent
+ a
+ b
+ c
+ EOS
+ end
+
+ after(:each) { file.unlink }
+
+ it "raises error if there is nothing to replace" do
+ expect {
+ described_class.inreplace file.path, "d", "f"
+ }.to raise_error(Utils::InreplaceError)
+ end
+
+ it "raises error if there is nothing to replace" do
+ expect {
+ described_class.inreplace(file.path) do |s|
+ s.gsub!("d", "f") # rubocop:disable Performance/StringReplacement
+ end
+ }.to raise_error(Utils::InreplaceError)
+ end
+
+ it "raises error if there is nothing to replace" do
+ expect {
+ described_class.inreplace(file.path) do |s|
+ s.change_make_var! "VAR", "value"
+ s.remove_make_var! "VAR2"
+ end
+ }.to raise_error(Utils::InreplaceError)
+ end
+end
diff --git a/Library/Homebrew/test/inreplace_test.rb b/Library/Homebrew/test/inreplace_test.rb
deleted file mode 100644
index 0e62f9d3f..000000000
--- a/Library/Homebrew/test/inreplace_test.rb
+++ /dev/null
@@ -1,119 +0,0 @@
-require "testing_env"
-require "extend/string"
-require "utils/inreplace"
-
-class InreplaceTest < Homebrew::TestCase
- def test_change_make_var
- # Replace flag
- s1 = "OTHER=def\nFLAG = abc\nFLAG2=abc"
- s1.extend(StringInreplaceExtension)
- s1.change_make_var! "FLAG", "def"
- assert_equal "OTHER=def\nFLAG=def\nFLAG2=abc", s1
- end
-
- def test_change_make_var_empty
- # Replace empty flag
- s1 = "OTHER=def\nFLAG = \nFLAG2=abc"
- s1.extend(StringInreplaceExtension)
- s1.change_make_var! "FLAG", "def"
- assert_equal "OTHER=def\nFLAG=def\nFLAG2=abc", s1
- end
-
- def test_change_make_var_empty_2
- # Replace empty flag
- s1 = "FLAG = \nmv file_a file_b"
- s1.extend(StringInreplaceExtension)
- s1.change_make_var! "FLAG", "def"
- assert_equal "FLAG=def\nmv file_a file_b", s1
- end
-
- def test_change_make_var_append
- # Append to flag
- s1 = "OTHER=def\nFLAG = abc\nFLAG2=abc"
- s1.extend(StringInreplaceExtension)
- s1.change_make_var! "FLAG", "\\1 def"
- assert_equal "OTHER=def\nFLAG=abc def\nFLAG2=abc", s1
- end
-
- def test_change_make_var_shell_style
- # Shell variables have no spaces around =
- s1 = "OTHER=def\nFLAG=abc\nFLAG2=abc"
- s1.extend(StringInreplaceExtension)
- s1.change_make_var! "FLAG", "def"
- assert_equal "OTHER=def\nFLAG=def\nFLAG2=abc", s1
- end
-
- def test_remove_make_var
- # Replace flag
- s1 = "OTHER=def\nFLAG = abc\nFLAG2 = def"
- s1.extend(StringInreplaceExtension)
- s1.remove_make_var! "FLAG"
- assert_equal "OTHER=def\nFLAG2 = def", s1
- end
-
- def test_remove_make_vars
- # Replace flag
- s1 = "OTHER=def\nFLAG = abc\nFLAG2 = def\nOTHER2=def"
- s1.extend(StringInreplaceExtension)
- s1.remove_make_var! ["FLAG", "FLAG2"]
- assert_equal "OTHER=def\nOTHER2=def", s1
- end
-
- def test_get_make_var
- s = "CFLAGS = -Wall -O2\nLDFLAGS = -lcrypto -lssl"
- s.extend(StringInreplaceExtension)
- assert_equal "-Wall -O2", s.get_make_var("CFLAGS")
- end
-
- def test_change_make_var_with_tabs
- s = "CFLAGS\t=\t-Wall -O2\nLDFLAGS\t=\t-lcrypto -lssl"
- s.extend(StringInreplaceExtension)
-
- assert_equal "-Wall -O2", s.get_make_var("CFLAGS")
-
- s.change_make_var! "CFLAGS", "-O3"
- assert_equal "CFLAGS=-O3\nLDFLAGS\t=\t-lcrypto -lssl", s
-
- s.remove_make_var! "LDFLAGS"
- assert_equal "CFLAGS=-O3\n", s
- end
-
- def test_sub_gsub
- s = "foo"
- s.extend(StringInreplaceExtension)
-
- s.sub!("f", "b")
- assert_equal "boo", s
-
- # Under current context, we are testing `String#gsub!`, so let's disable rubocop temporarily.
- s.gsub!("o", "e") # rubocop:disable Performance/StringReplacement
- assert_equal "bee", s
- end
-
- def test_inreplace_errors
- require "tempfile"
- extend(Utils::Inreplace)
-
- file = Tempfile.new("test")
-
- file.write "a\nb\nc\n"
-
- assert_raises(Utils::InreplaceError) do
- inreplace file.path, "d", "f"
- end
-
- assert_raises(Utils::InreplaceError) do
- # Under current context, we are testing `String#gsub!`, so let's disable rubocop temporarily.
- inreplace(file.path) { |s| s.gsub!("d", "f") } # rubocop:disable Performance/StringReplacement
- end
-
- assert_raises(Utils::InreplaceError) do
- inreplace(file.path) do |s|
- s.change_make_var! "VAR", "value"
- s.remove_make_var! "VAR2"
- end
- end
- ensure
- file.unlink
- end
-end
diff --git a/Library/Homebrew/test/install_test.rb b/Library/Homebrew/test/install_test.rb
deleted file mode 100644
index da6c1863f..000000000
--- a/Library/Homebrew/test/install_test.rb
+++ /dev/null
@@ -1,136 +0,0 @@
-require "testing_env"
-
-class IntegrationCommandTestInstall < IntegrationCommandTestCase
- def test_install
- setup_test_formula "testball1"
- assert_match "Specify `--HEAD`", cmd_fail("install", "testball1", "--head")
- assert_match "No head is defined", cmd_fail("install", "testball1", "--HEAD")
- assert_match "No devel block", cmd_fail("install", "testball1", "--devel")
- assert_match "#{HOMEBREW_CELLAR}/testball1/0.1", cmd("install", "testball1")
- assert_match "testball1-0.1 already installed", cmd("install", "testball1")
- assert_match "MacRuby is not packaged", cmd_fail("install", "macruby")
- assert_match "No available formula", cmd_fail("install", "formula")
- assert_match "This similarly named formula was found",
- cmd_fail("install", "testball")
-
- setup_test_formula "testball2"
- assert_match "These similarly named formulae were found",
- cmd_fail("install", "testball")
-
- install_and_rename_coretap_formula "testball1", "testball2"
- assert_match "testball1 already installed, it's just not migrated",
- cmd("install", "testball2")
- end
-
- def test_install_failures
- path = setup_test_formula "testball1", "version \"1.0\""
- devel_content = <<-EOS.undent
- version "3.0"
- devel do
- url "#{Formulary.factory("testball1").stable.url}"
- sha256 "#{TESTBALL_SHA256}"
- version "2.0"
- end
- EOS
-
- assert_match "#{HOMEBREW_CELLAR}/testball1/1.0", cmd("install", "testball1")
-
- FileUtils.rm path
- setup_test_formula "testball1", devel_content
-
- assert_match "first `brew unlink testball1`", cmd_fail("install", "testball1")
- assert_match "#{HOMEBREW_CELLAR}/testball1/1.0", cmd("unlink", "testball1")
- assert_match "#{HOMEBREW_CELLAR}/testball1/2.0", cmd("install", "testball1", "--devel")
- assert_match "#{HOMEBREW_CELLAR}/testball1/2.0", cmd("unlink", "testball1")
- assert_match "#{HOMEBREW_CELLAR}/testball1/3.0", cmd("install", "testball1")
-
- cmd("switch", "testball1", "2.0")
- assert_match "already installed, however linked version is",
- cmd("install", "testball1")
- assert_match "#{HOMEBREW_CELLAR}/testball1/2.0", cmd("unlink", "testball1")
- assert_match "just not linked", cmd("install", "testball1")
- end
-
- def test_install_keg_only_outdated
- path_keg_only = setup_test_formula "testball1", <<-EOS.undent
- version "1.0"
- keg_only "test reason"
- EOS
-
- assert_match "#{HOMEBREW_CELLAR}/testball1/1.0", cmd("install", "testball1")
-
- FileUtils.rm path_keg_only
- setup_test_formula "testball1", <<-EOS.undent
- version "2.0"
- keg_only "test reason"
- EOS
-
- assert_match "keg-only and another version is linked to opt",
- cmd("install", "testball1")
-
- assert_match "#{HOMEBREW_CELLAR}/testball1/2.0",
- cmd("install", "testball1", "--force")
- end
-
- def test_install_head_installed
- 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.
- assert_match "#{HOMEBREW_CELLAR}/testball1/HEAD-d5eb689", cmd("install", "testball1", "--HEAD", "--ignore-dependencies")
- assert_match "testball1-HEAD-d5eb689 already installed",
- cmd("install", "testball1", "--HEAD", "--ignore-dependencies")
- assert_match "#{HOMEBREW_CELLAR}/testball1/HEAD-d5eb689", cmd("unlink", "testball1")
- assert_match "#{HOMEBREW_CELLAR}/testball1/1.0", cmd("install", "testball1")
- end
-
- def test_install_with_invalid_option
- setup_test_formula "testball1"
- assert_match "testball1: this formula has no --with-fo option so it will be ignored!",
- cmd("install", "testball1", "--with-fo")
- end
-
- def test_install_with_nonfatal_requirement
- setup_test_formula "testball1", <<-EOS.undent
- class NonFatalRequirement < Requirement
- satisfy { false }
- end
- depends_on NonFatalRequirement
- EOS
- message = "NonFatalRequirement unsatisfied!"
- assert_equal 1, cmd("install", "testball1").scan(message).size
- end
-
- def test_install_with_fatal_requirement
- setup_test_formula "testball1", <<-EOS.undent
- class FatalRequirement < Requirement
- fatal true
- satisfy { false }
- end
- depends_on FatalRequirement
- EOS
- message = "FatalRequirement unsatisfied!"
- assert_equal 1, cmd_fail("install", "testball1").scan(message).size
- end
-end
diff --git a/Library/Homebrew/test/irb_test.rb b/Library/Homebrew/test/irb_test.rb
deleted file mode 100644
index 832ca39a5..000000000
--- a/Library/Homebrew/test/irb_test.rb
+++ /dev/null
@@ -1,19 +0,0 @@
-require "testing_env"
-
-class IntegrationCommandTestIrb < IntegrationCommandTestCase
- def test_irb
- assert_match "'v8'.f # => instance of the v8 formula",
- cmd("irb", "--examples")
-
- setup_test_formula "testball"
-
- irb_test = HOMEBREW_TEMP/"irb-test.rb"
- irb_test.write <<-EOS.undent
- "testball".f
- :testball.f
- exit
- EOS
-
- assert_match "Interactive Homebrew Shell", cmd("irb", irb_test)
- end
-end
diff --git a/Library/Homebrew/test/java_requirement_spec.rb b/Library/Homebrew/test/java_requirement_spec.rb
new file mode 100644
index 000000000..5adf64c7c
--- /dev/null
+++ b/Library/Homebrew/test/java_requirement_spec.rb
@@ -0,0 +1,107 @@
+require "requirements/java_requirement"
+
+describe JavaRequirement do
+ subject { described_class.new([]) }
+
+ before(:each) do
+ ENV["JAVA_HOME"] = nil
+ end
+
+ describe "#message" do
+ its(:message) { is_expected.to match(/Java is required to install this formula./) }
+ end
+
+ describe "#inspect" do
+ subject { described_class.new(%w[1.7+]) }
+ its(:inspect) { is_expected.to eq('#<JavaRequirement: "java" [] version="1.7+">') }
+ end
+
+ describe "#display_s" do
+ context "without specific version" do
+ its(:display_s) { is_expected.to eq("java") }
+ end
+
+ context "with version 1.8" do
+ subject { described_class.new(%w[1.8]) }
+ its(:display_s) { is_expected.to eq("java = 1.8") }
+ end
+
+ context "with version 1.8+" do
+ subject { described_class.new(%w[1.8+]) }
+ its(:display_s) { is_expected.to eq("java >= 1.8") }
+ end
+ end
+
+ describe "#satisfied?" do
+ subject { described_class.new(%w[1.8]) }
+
+ it "returns false if no `java` executable can be found" do
+ allow(File).to receive(:executable?).and_return(false)
+ expect(subject).not_to be_satisfied
+ end
+
+ it "returns true if #preferred_java returns a path" do
+ allow(subject).to receive(:preferred_java).and_return(Pathname.new("/usr/bin/java"))
+ expect(subject).to be_satisfied
+ end
+
+ context "when #possible_javas contains paths" do
+ let(:path) { Pathname.new(Dir.mktmpdir) }
+ let(:java) { path/"java" }
+
+ def setup_java_with_version(version)
+ IO.write java, <<-EOS.undent
+ #!/bin/sh
+ echo 'java version "#{version}"'
+ EOS
+ FileUtils.chmod "+x", java
+ end
+
+ before(:each) do
+ allow(subject).to receive(:possible_javas).and_return([java])
+ end
+
+ after(:each) do
+ path.rmtree
+ end
+
+ context "and 1.7 is required" do
+ subject { described_class.new(%w[1.7]) }
+
+ it "returns false if all are lower" do
+ setup_java_with_version "1.6.0_5"
+ expect(subject).not_to be_satisfied
+ end
+
+ it "returns true if one is equal" do
+ setup_java_with_version "1.7.0_5"
+ expect(subject).to be_satisfied
+ end
+
+ it "returns false if all are higher" do
+ setup_java_with_version "1.8.0_5"
+ expect(subject).not_to be_satisfied
+ end
+ end
+
+ context "and 1.7+ is required" do
+ subject { described_class.new(%w[1.7+]) }
+
+ it "returns false if all are lower" do
+ setup_java_with_version "1.6.0_5"
+ expect(subject).not_to be_satisfied
+ end
+
+ it "returns true if one is equal" do
+ setup_java_with_version "1.7.0_5"
+ expect(subject).to be_satisfied
+ end
+
+ it "returns true if one is higher" do
+ setup_java_with_version "1.8.0_5"
+ expect(subject).to be_satisfied
+ end
+ end
+ end
+ end
+end
diff --git a/Library/Homebrew/test/java_requirement_test.rb b/Library/Homebrew/test/java_requirement_test.rb
deleted file mode 100644
index d0b51f92c..000000000
--- a/Library/Homebrew/test/java_requirement_test.rb
+++ /dev/null
@@ -1,50 +0,0 @@
-require "testing_env"
-require "requirements/java_requirement"
-
-class JavaRequirementTests < Homebrew::TestCase
- def setup
- super
- ENV["JAVA_HOME"] = nil
- end
-
- def test_message
- a = JavaRequirement.new([])
- assert_match(/Java is required to install this formula./, a.message)
- end
-
- def test_inspect
- a = JavaRequirement.new(%w[1.7+])
- assert_equal a.inspect, '#<JavaRequirement: "java" [] version="1.7+">'
- end
-
- def test_display_s
- x = JavaRequirement.new([])
- assert_equal x.display_s, "java"
- y = JavaRequirement.new(%w[1.8])
- assert_equal y.display_s, "java = 1.8"
- z = JavaRequirement.new(%w[1.8+])
- assert_equal z.display_s, "java >= 1.8"
- end
-
- def test_satisfied?
- a = JavaRequirement.new(%w[1.8])
- File.stubs(:executable?).returns(false)
- refute_predicate a, :satisfied?
-
- b = JavaRequirement.new([])
- b.stubs(:preferred_java).returns(Pathname.new("/usr/bin/java"))
- assert_predicate b, :satisfied?
-
- c = JavaRequirement.new(%w[1.7+])
- c.stubs(:possible_javas).returns([Pathname.new("/usr/bin/java")])
- Utils.stubs(:popen_read).returns('java version "1.6.0_5"')
- refute_predicate c, :satisfied?
- Utils.stubs(:popen_read).returns('java version "1.8.0_5"')
- assert_predicate c, :satisfied?
-
- d = JavaRequirement.new(%w[1.7])
- d.stubs(:possible_javas).returns([Pathname.new("/usr/bin/java")])
- Utils.stubs(:popen_read).returns('java version "1.8.0_5"')
- refute_predicate d, :satisfied?
- end
-end
diff --git a/Library/Homebrew/test/keg_spec.rb b/Library/Homebrew/test/keg_spec.rb
new file mode 100644
index 000000000..3bf1257e6
--- /dev/null
+++ b/Library/Homebrew/test/keg_spec.rb
@@ -0,0 +1,490 @@
+require "keg"
+require "stringio"
+
+describe Keg do
+ include FileUtils
+
+ def setup_test_keg(name, version)
+ path = HOMEBREW_CELLAR/name/version
+ (path/"bin").mkpath
+
+ %w[hiworld helloworld goodbye_cruel_world].each do |file|
+ touch path/"bin"/file
+ end
+
+ keg = described_class.new(path)
+ kegs << keg
+ keg
+ end
+
+ around(:each) do |example|
+ begin
+ @old_stdout = $stdout
+ $stdout = StringIO.new
+
+ example.run
+ ensure
+ $stdout = @old_stdout
+ end
+ end
+
+ let(:dst) { HOMEBREW_PREFIX/"bin"/"helloworld" }
+ let(:nonexistent) { Pathname.new("/some/nonexistent/path") }
+ let(:mode) { OpenStruct.new }
+ let!(:keg) { setup_test_keg("foo", "1.0") }
+ let(:kegs) { [] }
+
+ before(:each) do
+ (HOMEBREW_PREFIX/"bin").mkpath
+ (HOMEBREW_PREFIX/"lib").mkpath
+ end
+
+ after(:each) do
+ kegs.each(&:unlink)
+ rmtree HOMEBREW_PREFIX/"lib"
+ end
+
+ specify "::all" do
+ Formula.clear_racks_cache
+ expect(described_class.all).to eq([keg])
+ end
+
+ specify "#empty_installation?" do
+ %w[.DS_Store INSTALL_RECEIPT.json LICENSE.txt].each do |file|
+ touch keg/file
+ end
+
+ expect(keg).to exist
+ expect(keg).to be_a_directory
+ expect(keg).not_to be_an_empty_installation
+
+ (keg/"bin").rmtree
+ expect(keg).to be_an_empty_installation
+
+ (keg/"bin").mkpath
+ touch keg.join("bin", "todo")
+ expect(keg).not_to be_an_empty_installation
+ end
+
+ specify "#oldname_opt_record" do
+ expect(keg.oldname_opt_record).to be nil
+ oldname_opt_record = HOMEBREW_PREFIX/"opt/oldfoo"
+ oldname_opt_record.make_relative_symlink(HOMEBREW_CELLAR/"foo/1.0")
+ expect(keg.oldname_opt_record).to eq(oldname_opt_record)
+ end
+
+ specify "#remove_oldname_opt_record" do
+ oldname_opt_record = HOMEBREW_PREFIX/"opt/oldfoo"
+ oldname_opt_record.make_relative_symlink(HOMEBREW_CELLAR/"foo/2.0")
+ keg.remove_oldname_opt_record
+ expect(oldname_opt_record).to be_a_symlink
+ oldname_opt_record.unlink
+ oldname_opt_record.make_relative_symlink(HOMEBREW_CELLAR/"foo/1.0")
+ keg.remove_oldname_opt_record
+ expect(oldname_opt_record).not_to be_a_symlink
+ end
+
+ describe "#link" do
+ it "links a Keg" do
+ expect(keg.link).to eq(3)
+ (HOMEBREW_PREFIX/"bin").children.each do |c|
+ expect(c.readlink).to be_relative
+ end
+ end
+
+ context "with dry run set to true" do
+ it "only prints what would be done" do
+ mode.dry_run = true
+
+ expect(keg.link(mode)).to eq(0)
+ expect(keg).not_to be_linked
+
+ ["hiworld", "helloworld", "goodbye_cruel_world"].each do |file|
+ expect($stdout.string).to match("#{HOMEBREW_PREFIX}/bin/#{file}")
+ end
+ expect($stdout.string.lines.count).to eq(3)
+ end
+ end
+
+ it "fails when already linked" do
+ keg.link
+
+ expect { keg.link }.to raise_error(Keg::AlreadyLinkedError)
+ end
+
+ it "fails when files exist" do
+ touch dst
+
+ expect { keg.link }.to raise_error(Keg::ConflictError)
+ end
+
+ it "ignores broken symlinks at target" do
+ src = keg/"bin"/"helloworld"
+ dst.make_symlink(nonexistent)
+ keg.link
+ expect(dst.readlink).to eq(src.relative_path_from(dst.dirname))
+ end
+
+ context "with overwrite set to true" do
+ it "overwrite existing files" do
+ touch dst
+ mode.overwrite = true
+ expect(keg.link(mode)).to eq(3)
+ expect(keg).to be_linked
+ end
+
+ it "overwrites broken symlinks" do
+ dst.make_symlink "nowhere"
+ mode.overwrite = true
+ expect(keg.link(mode)).to eq(3)
+ expect(keg).to be_linked
+ end
+
+ it "still supports dryrun" do
+ touch dst
+ mode.overwrite = true
+ mode.dry_run = true
+
+ expect(keg.link(mode)).to eq(0)
+ expect(keg).not_to be_linked
+
+ expect($stdout.string).to eq("#{dst}\n")
+ end
+ end
+
+ it "also creates an opt link" do
+ expect(keg).not_to be_optlinked
+ keg.link
+ expect(keg).to be_optlinked
+ end
+
+ specify "pkgconfig directory is created" do
+ link = HOMEBREW_PREFIX/"lib"/"pkgconfig"
+ (keg/"lib"/"pkgconfig").mkpath
+ keg.link
+ expect(link.lstat).to be_a_directory
+ end
+
+ specify "cmake directory is created" do
+ link = HOMEBREW_PREFIX/"lib"/"cmake"
+ (keg/"lib"/"cmake").mkpath
+ keg.link
+ expect(link.lstat).to be_a_directory
+ end
+
+ specify "symlinks are linked directly" do
+ link = HOMEBREW_PREFIX/"lib"/"pkgconfig"
+
+ (keg/"lib"/"example").mkpath
+ (keg/"lib"/"pkgconfig").make_symlink "example"
+ keg.link
+
+ expect(link.resolved_path).to be_a_symlink
+ expect(link.lstat).to be_a_symlink
+ end
+ end
+
+ describe "#unlink" do
+ it "unlinks a Keg" do
+ keg.link
+ expect(dst).to be_a_symlink
+ expect(keg.unlink).to eq(3)
+ expect(dst).not_to be_a_symlink
+ end
+
+ it "prunes empty top-level directories" do
+ mkpath HOMEBREW_PREFIX/"lib/foo/bar"
+ mkpath keg/"lib/foo/bar"
+ touch keg/"lib/foo/bar/file1"
+
+ keg.unlink
+
+ expect(HOMEBREW_PREFIX/"lib/foo").not_to be_a_directory
+ end
+
+ it "ignores .DS_Store when pruning empty directories" do
+ mkpath HOMEBREW_PREFIX/"lib/foo/bar"
+ touch HOMEBREW_PREFIX/"lib/foo/.DS_Store"
+ mkpath keg/"lib/foo/bar"
+ touch keg/"lib/foo/bar/file1"
+
+ keg.unlink
+
+ expect(HOMEBREW_PREFIX/"lib/foo").not_to be_a_directory
+ expect(HOMEBREW_PREFIX/"lib/foo/.DS_Store").not_to exist
+ end
+
+ it "doesn't remove opt link" do
+ keg.link
+ keg.unlink
+ expect(keg).to be_optlinked
+ end
+
+ it "preverves broken symlinks pointing outside the Keg" do
+ keg.link
+ dst.delete
+ dst.make_symlink(nonexistent)
+ keg.unlink
+ expect(dst).to be_a_symlink
+ end
+
+ it "preverves broken symlinks pointing into the Keg" do
+ keg.link
+ dst.resolved_path.delete
+ keg.unlink
+ expect(dst).to be_a_symlink
+ end
+
+ it "preverves symlinks pointing outside the Keg" do
+ keg.link
+ dst.delete
+ dst.make_symlink(Pathname.new("/bin/sh"))
+ keg.unlink
+ expect(dst).to be_a_symlink
+ end
+
+ it "preserves real files" do
+ keg.link
+ dst.delete
+ touch dst
+ keg.unlink
+ expect(dst).to be_a_file
+ end
+
+ it "ignores nonexistent file" do
+ keg.link
+ dst.delete
+ expect(keg.unlink).to eq(2)
+ end
+
+ it "doesn't remove links to symlinks" do
+ a = HOMEBREW_CELLAR/"a"/"1.0"
+ b = HOMEBREW_CELLAR/"b"/"1.0"
+
+ (a/"lib"/"example").mkpath
+ (a/"lib"/"example2").make_symlink "example"
+ (b/"lib"/"example2").mkpath
+
+ a = described_class.new(a)
+ b = described_class.new(b)
+ a.link
+
+ lib = HOMEBREW_PREFIX/"lib"
+ expect(lib.children.length).to eq(2)
+ expect { b.link }.to raise_error(Keg::ConflictError)
+ expect(lib.children.length).to eq(2)
+ end
+
+ it "removes broken symlinks that conflict with directories" do
+ a = HOMEBREW_CELLAR/"a"/"1.0"
+ (a/"lib"/"foo").mkpath
+
+ keg = described_class.new(a)
+
+ link = HOMEBREW_PREFIX/"lib"/"foo"
+ link.parent.mkpath
+ link.make_symlink(nonexistent)
+
+ keg.link
+ end
+ end
+
+ describe "#optlink" do
+ it "creates an opt link" do
+ oldname_opt_record = HOMEBREW_PREFIX/"opt/oldfoo"
+ oldname_opt_record.make_relative_symlink(HOMEBREW_CELLAR/"foo/1.0")
+ keg_record = HOMEBREW_CELLAR/"foo"/"2.0"
+ (keg_record/"bin").mkpath
+ keg = described_class.new(keg_record)
+ keg.optlink
+ expect(keg_record).to eq(oldname_opt_record.resolved_path)
+ keg.uninstall
+ expect(oldname_opt_record).not_to be_a_symlink
+ end
+
+ it "doesn't fail if already opt-linked" do
+ keg.opt_record.make_relative_symlink Pathname.new(keg)
+ keg.optlink
+ expect(keg).to be_optlinked
+ end
+
+ it "replaces an existing directory" do
+ keg.opt_record.mkpath
+ keg.optlink
+ expect(keg).to be_optlinked
+ end
+
+ it "replaces an existing file" do
+ keg.opt_record.parent.mkpath
+ keg.opt_record.write("foo")
+ keg.optlink
+ expect(keg).to be_optlinked
+ end
+ end
+
+ specify "#link and #unlink" do
+ expect(keg).not_to be_linked
+ keg.link
+ expect(keg).to be_linked
+ keg.unlink
+ expect(keg).not_to be_linked
+ end
+
+ describe "::find_some_installed_dependents" do
+ def stub_formula_name(name)
+ f = formula(name) { url "foo-1.0" }
+ stub_formula_loader f
+ stub_formula_loader f, "homebrew/core/#{f}"
+ f
+ end
+
+ def setup_test_keg(name, version)
+ f = stub_formula_name(name)
+ keg = super
+ Tab.create(f, DevelopmentTools.default_compiler, :libcxx).write
+ keg
+ end
+
+ before(:each) do
+ keg.link
+ end
+
+ def alter_tab(keg = dependent)
+ tab = Tab.for_keg(keg)
+ yield tab
+ tab.write
+ end
+
+ # 1.1.6 is the earliest version of Homebrew that generates correct runtime
+ # dependency lists in Tabs.
+ def dependencies(deps, homebrew_version: "1.1.6")
+ alter_tab do |tab|
+ tab.homebrew_version = homebrew_version
+ tab.tabfile = dependent/Tab::FILENAME
+ tab.runtime_dependencies = deps
+ end
+ end
+
+ def unreliable_dependencies(deps)
+ # 1.1.5 is (hopefully!) the last version of Homebrew that generates
+ # incorrect runtime dependency lists in Tabs.
+ dependencies(deps, homebrew_version: "1.1.5")
+ end
+
+ let(:dependent) { setup_test_keg("bar", "1.0") }
+
+ # Test with a keg whose formula isn't known.
+ # This can happen if e.g. a formula is installed
+ # from a file path or URL.
+ specify "unknown Formula" do
+ allow(Formulary).to receive(:loader_for).and_call_original
+ alter_tab(keg) do |t|
+ t.source["tap"] = "some/tap"
+ t.source["path"] = nil
+ end
+
+ dependencies [{ "full_name" => "some/tap/foo", "version" => "1.0" }]
+ expect(keg.installed_dependents).to eq([dependent])
+ expect(described_class.find_some_installed_dependents([keg])).to eq([[keg], ["bar 1.0"]])
+
+ dependencies nil
+ # It doesn't make sense for a keg with no formula to have any dependents,
+ # so that can't really be tested.
+ expect(described_class.find_some_installed_dependents([keg])).to be nil
+ end
+
+ specify "a dependency with no Tap in Tab" do
+ tap_dep = setup_test_keg("baz", "1.0")
+
+ alter_tab(keg) { |t| t.source["tap"] = nil }
+
+ dependencies nil
+ Formula["bar"].class.depends_on "foo"
+ Formula["bar"].class.depends_on "baz"
+
+ result = described_class.find_some_installed_dependents([keg, tap_dep])
+ expect(result).to eq([[keg, tap_dep], ["bar"]])
+ end
+
+ specify "no dependencies anywhere" do
+ dependencies nil
+ expect(keg.installed_dependents).to be_empty
+ expect(described_class.find_some_installed_dependents([keg])).to be nil
+ end
+
+ specify "missing Formula dependency" do
+ dependencies nil
+ Formula["bar"].class.depends_on "foo"
+ expect(keg.installed_dependents).to be_empty
+ expect(described_class.find_some_installed_dependents([keg])).to eq([[keg], ["bar"]])
+ end
+
+ specify "uninstalling dependent and dependency" do
+ dependencies nil
+ Formula["bar"].class.depends_on "foo"
+ expect(keg.installed_dependents).to be_empty
+ expect(described_class.find_some_installed_dependents([keg, dependent])).to be nil
+ end
+
+ specify "renamed dependency" do
+ dependencies nil
+
+ stub_formula_loader Formula["foo"], "homebrew/core/foo-old"
+ renamed_path = HOMEBREW_CELLAR/"foo-old"
+ (HOMEBREW_CELLAR/"foo").rename(renamed_path)
+ renamed_keg = described_class.new(renamed_path/"1.0")
+
+ Formula["bar"].class.depends_on "foo"
+
+ result = described_class.find_some_installed_dependents([renamed_keg])
+ expect(result).to eq([[renamed_keg], ["bar"]])
+ end
+
+ specify "empty dependencies in Tab" do
+ dependencies []
+ expect(keg.installed_dependents).to be_empty
+ expect(described_class.find_some_installed_dependents([keg])).to be nil
+ end
+
+ specify "same name but different version in Tab" do
+ dependencies [{ "full_name" => "foo", "version" => "1.1" }]
+ expect(keg.installed_dependents).to eq([dependent])
+ expect(described_class.find_some_installed_dependents([keg])).to eq([[keg], ["bar 1.0"]])
+ end
+
+ specify "different name and same version in Tab" do
+ stub_formula_name("baz")
+ dependencies [{ "full_name" => "baz", "version" => keg.version.to_s }]
+ expect(keg.installed_dependents).to be_empty
+ expect(described_class.find_some_installed_dependents([keg])).to be nil
+ end
+
+ specify "same name and version in Tab" do
+ dependencies [{ "full_name" => "foo", "version" => "1.0" }]
+ expect(keg.installed_dependents).to eq([dependent])
+ expect(described_class.find_some_installed_dependents([keg])).to eq([[keg], ["bar 1.0"]])
+ end
+
+ specify "fallback for old versions" do
+ unreliable_dependencies [{ "full_name" => "baz", "version" => "1.0" }]
+ Formula["bar"].class.depends_on "foo"
+ expect(keg.installed_dependents).to be_empty
+ expect(described_class.find_some_installed_dependents([keg])).to eq([[keg], ["bar"]])
+ end
+
+ specify "non-opt-linked" do
+ keg.remove_opt_record
+ dependencies [{ "full_name" => "foo", "version" => "1.0" }]
+ expect(keg.installed_dependents).to be_empty
+ expect(described_class.find_some_installed_dependents([keg])).to be nil
+ end
+
+ specify "keg-only" do
+ keg.unlink
+ Formula["foo"].class.keg_only "a good reason"
+ dependencies [{ "full_name" => "foo", "version" => "1.1" }] # different version
+ expect(keg.installed_dependents).to eq([dependent])
+ expect(described_class.find_some_installed_dependents([keg])).to eq([[keg], ["bar 1.0"]])
+ end
+ end
+end
diff --git a/Library/Homebrew/test/keg_test.rb b/Library/Homebrew/test/keg_test.rb
deleted file mode 100644
index e8f99b777..000000000
--- a/Library/Homebrew/test/keg_test.rb
+++ /dev/null
@@ -1,479 +0,0 @@
-require "testing_env"
-require "keg"
-require "stringio"
-
-class LinkTestCase < Homebrew::TestCase
- include FileUtils
-
- def setup_test_keg(name, version)
- path = HOMEBREW_CELLAR.join(name, version)
- path.join("bin").mkpath
-
- %w[hiworld helloworld goodbye_cruel_world].each do |file|
- touch path.join("bin", file)
- end
-
- keg = Keg.new(path)
- @kegs ||= []
- @kegs << keg
- keg
- end
-
- def setup
- super
-
- @keg = setup_test_keg("foo", "1.0")
- @dst = HOMEBREW_PREFIX.join("bin", "helloworld")
- @nonexistent = Pathname.new("/some/nonexistent/path")
-
- @mode = OpenStruct.new
-
- @old_stdout = $stdout
- $stdout = StringIO.new
-
- mkpath HOMEBREW_PREFIX/"bin"
- mkpath HOMEBREW_PREFIX/"lib"
- end
-
- def teardown
- @kegs.each(&:unlink)
- $stdout = @old_stdout
- rmtree HOMEBREW_PREFIX/"lib"
- super
- end
-end
-
-class LinkTests < LinkTestCase
- def test_all
- Formula.clear_racks_cache
- assert_equal [@keg], Keg.all
- end
-
- def test_empty_installation
- %w[.DS_Store INSTALL_RECEIPT.json LICENSE.txt].each do |file|
- touch @keg/file
- end
- assert_predicate @keg, :exist?
- assert_predicate @keg, :directory?
- refute_predicate @keg, :empty_installation?
-
- (@keg/"bin").rmtree
- assert_predicate @keg, :empty_installation?
-
- (@keg/"bin").mkpath
- touch @keg.join("bin", "todo")
- refute_predicate @keg, :empty_installation?
- end
-
- def test_linking_keg
- assert_equal 3, @keg.link
- (HOMEBREW_PREFIX/"bin").children.each { |c| assert_predicate c.readlink, :relative? }
- end
-
- def test_unlinking_keg
- @keg.link
- assert_predicate @dst, :symlink?
- assert_equal 3, @keg.unlink
- refute_predicate @dst, :symlink?
- end
-
- def test_oldname_opt_record
- assert_nil @keg.oldname_opt_record
- oldname_opt_record = HOMEBREW_PREFIX/"opt/oldfoo"
- oldname_opt_record.make_relative_symlink(HOMEBREW_CELLAR/"foo/1.0")
- assert_equal oldname_opt_record, @keg.oldname_opt_record
- end
-
- def test_optlink_relink
- oldname_opt_record = HOMEBREW_PREFIX/"opt/oldfoo"
- oldname_opt_record.make_relative_symlink(HOMEBREW_CELLAR/"foo/1.0")
- keg_record = HOMEBREW_CELLAR.join("foo", "2.0")
- keg_record.join("bin").mkpath
- keg = Keg.new(keg_record)
- keg.optlink
- assert_equal keg_record, oldname_opt_record.resolved_path
- keg.uninstall
- refute_predicate oldname_opt_record, :symlink?
- end
-
- def test_remove_oldname_opt_record
- oldname_opt_record = HOMEBREW_PREFIX/"opt/oldfoo"
- oldname_opt_record.make_relative_symlink(HOMEBREW_CELLAR/"foo/2.0")
- @keg.remove_oldname_opt_record
- assert_predicate oldname_opt_record, :symlink?
- oldname_opt_record.unlink
- oldname_opt_record.make_relative_symlink(HOMEBREW_CELLAR/"foo/1.0")
- @keg.remove_oldname_opt_record
- refute_predicate oldname_opt_record, :symlink?
- end
-
- def test_link_dry_run
- @mode.dry_run = true
-
- assert_equal 0, @keg.link(@mode)
- refute_predicate @keg, :linked?
-
- ["hiworld", "helloworld", "goodbye_cruel_world"].each do |file|
- assert_match "#{HOMEBREW_PREFIX}/bin/#{file}", $stdout.string
- end
- assert_equal 3, $stdout.string.lines.count
- end
-
- def test_linking_fails_when_already_linked
- @keg.link
- assert_raises(Keg::AlreadyLinkedError) { @keg.link }
- end
-
- def test_linking_fails_when_files_exist
- touch @dst
- assert_raises(Keg::ConflictError) { @keg.link }
- end
-
- def test_link_ignores_broken_symlinks_at_target
- src = @keg.join("bin", "helloworld")
- @dst.make_symlink(@nonexistent)
- @keg.link
- assert_equal src.relative_path_from(@dst.dirname), @dst.readlink
- end
-
- def test_link_overwrite
- touch @dst
- @mode.overwrite = true
- assert_equal 3, @keg.link(@mode)
- assert_predicate @keg, :linked?
- end
-
- def test_link_overwrite_broken_symlinks
- @dst.make_symlink "nowhere"
- @mode.overwrite = true
- assert_equal 3, @keg.link(@mode)
- assert_predicate @keg, :linked?
- end
-
- def test_link_overwrite_dryrun
- touch @dst
- @mode.overwrite = true
- @mode.dry_run = true
-
- assert_equal 0, @keg.link(@mode)
- refute_predicate @keg, :linked?
-
- assert_equal "#{@dst}\n", $stdout.string
- end
-
- def test_unlink_prunes_empty_toplevel_directories
- mkpath HOMEBREW_PREFIX/"lib/foo/bar"
- mkpath @keg/"lib/foo/bar"
- touch @keg/"lib/foo/bar/file1"
-
- @keg.unlink
-
- refute_predicate HOMEBREW_PREFIX/"lib/foo", :directory?
- end
-
- def test_unlink_ignores_ds_store_when_pruning_empty_dirs
- mkpath HOMEBREW_PREFIX/"lib/foo/bar"
- touch HOMEBREW_PREFIX/"lib/foo/.DS_Store"
- mkpath @keg/"lib/foo/bar"
- touch @keg/"lib/foo/bar/file1"
-
- @keg.unlink
-
- refute_predicate HOMEBREW_PREFIX/"lib/foo", :directory?
- refute_predicate HOMEBREW_PREFIX/"lib/foo/.DS_Store", :exist?
- end
-
- def test_linking_creates_opt_link
- refute_predicate @keg, :optlinked?
- @keg.link
- assert_predicate @keg, :optlinked?
- end
-
- def test_unlinking_does_not_remove_opt_link
- @keg.link
- @keg.unlink
- assert_predicate @keg, :optlinked?
- end
-
- def test_existing_opt_link
- @keg.opt_record.make_relative_symlink Pathname.new(@keg)
- @keg.optlink
- assert_predicate @keg, :optlinked?
- end
-
- def test_existing_opt_link_directory
- @keg.opt_record.mkpath
- @keg.optlink
- assert_predicate @keg, :optlinked?
- end
-
- def test_existing_opt_link_file
- @keg.opt_record.parent.mkpath
- @keg.opt_record.write("foo")
- @keg.optlink
- assert_predicate @keg, :optlinked?
- end
-
- def test_linked_keg
- refute_predicate @keg, :linked?
- @keg.link
- assert_predicate @keg, :linked?
- @keg.unlink
- refute_predicate @keg, :linked?
- end
-
- def test_unlink_preserves_broken_symlink_pointing_outside_the_keg
- @keg.link
- @dst.delete
- @dst.make_symlink(@nonexistent)
- @keg.unlink
- assert_predicate @dst, :symlink?
- end
-
- def test_unlink_preserves_broken_symlink_pointing_into_the_keg
- @keg.link
- @dst.resolved_path.delete
- @keg.unlink
- assert_predicate @dst, :symlink?
- end
-
- def test_unlink_preserves_symlink_pointing_outside_of_keg
- @keg.link
- @dst.delete
- @dst.make_symlink(Pathname.new("/bin/sh"))
- @keg.unlink
- assert_predicate @dst, :symlink?
- end
-
- def test_unlink_preserves_real_file
- @keg.link
- @dst.delete
- touch @dst
- @keg.unlink
- assert_predicate @dst, :file?
- end
-
- def test_unlink_ignores_nonexistent_file
- @keg.link
- @dst.delete
- assert_equal 2, @keg.unlink
- end
-
- def test_pkgconfig_is_mkpathed
- link = HOMEBREW_PREFIX.join("lib", "pkgconfig")
- @keg.join("lib", "pkgconfig").mkpath
- @keg.link
- assert_predicate link.lstat, :directory?
- end
-
- def test_cmake_is_mkpathed
- link = HOMEBREW_PREFIX.join("lib", "cmake")
- @keg.join("lib", "cmake").mkpath
- @keg.link
- assert_predicate link.lstat, :directory?
- end
-
- def test_symlinks_are_linked_directly
- link = HOMEBREW_PREFIX.join("lib", "pkgconfig")
-
- @keg.join("lib", "example").mkpath
- @keg.join("lib", "pkgconfig").make_symlink "example"
- @keg.link
-
- assert_predicate link.resolved_path, :symlink?
- assert_predicate link.lstat, :symlink?
- end
-
- def test_links_to_symlinks_are_not_removed
- a = HOMEBREW_CELLAR.join("a", "1.0")
- b = HOMEBREW_CELLAR.join("b", "1.0")
-
- a.join("lib", "example").mkpath
- a.join("lib", "example2").make_symlink "example"
- b.join("lib", "example2").mkpath
-
- a = Keg.new(a)
- b = Keg.new(b)
- a.link
-
- lib = HOMEBREW_PREFIX.join("lib")
- assert_equal 2, lib.children.length
- assert_raises(Keg::ConflictError) { b.link }
- assert_equal 2, lib.children.length
- ensure
- a.unlink
- end
-
- def test_removes_broken_symlinks_that_conflict_with_directories
- a = HOMEBREW_CELLAR.join("a", "1.0")
- a.join("lib", "foo").mkpath
-
- keg = Keg.new(a)
-
- link = HOMEBREW_PREFIX.join("lib", "foo")
- link.parent.mkpath
- link.make_symlink(@nonexistent)
-
- keg.link
- ensure
- keg.unlink
- end
-end
-
-class InstalledDependantsTests < LinkTestCase
- def stub_formula_name(name)
- f = formula(name) { url "foo-1.0" }
- stub_formula_loader f
- stub_formula_loader f, "homebrew/core/#{f}"
- f
- end
-
- def setup_test_keg(name, version)
- f = stub_formula_name(name)
- keg = super
- Tab.create(f, DevelopmentTools.default_compiler, :libcxx).write
- keg
- end
-
- def setup
- super
- @dependent = setup_test_keg("bar", "1.0")
- @keg.link
- end
-
- def alter_tab(keg = @dependent)
- tab = Tab.for_keg(keg)
- yield tab
- tab.write
- end
-
- # 1.1.6 is the earliest version of Homebrew that generates correct runtime
- # dependency lists in tabs.
- def dependencies(deps, homebrew_version: "1.1.6")
- alter_tab do |tab|
- tab.homebrew_version = homebrew_version
- tab.tabfile = @dependent.join("INSTALL_RECEIPT.json")
- tab.runtime_dependencies = deps
- end
- end
-
- def unreliable_dependencies(deps)
- # 1.1.5 is (hopefully!) the last version of Homebrew that generates
- # incorrect runtime dependency lists in tabs.
- dependencies(deps, homebrew_version: "1.1.5")
- end
-
- # Test with a keg whose formula isn't known.
- # This can happen if e.g. a formula is installed
- # from a file path or URL.
- def test_unknown_formula
- Formulary.unstub(:loader_for)
- alter_tab(@keg) do |t|
- t.source["tap"] = "some/tap"
- t.source["path"] = nil
- end
-
- dependencies [{ "full_name" => "some/tap/foo", "version" => "1.0" }]
- assert_equal [@dependent], @keg.installed_dependents
- assert_equal [[@keg], ["bar 1.0"]], Keg.find_some_installed_dependents([@keg])
-
- dependencies nil
- # It doesn't make sense for a keg with no formula to have any dependents,
- # so that can't really be tested.
- assert_nil Keg.find_some_installed_dependents([@keg])
- end
-
- def test_a_dependency_with_no_tap_in_tab
- @tap_dep = setup_test_keg("baz", "1.0")
-
- alter_tab(@keg) { |t| t.source["tap"] = nil }
-
- dependencies nil
- Formula["bar"].class.depends_on "foo"
- Formula["bar"].class.depends_on "baz"
-
- result = Keg.find_some_installed_dependents([@keg, @tap_dep])
- assert_equal [[@keg, @tap_dep], ["bar"]], result
- end
-
- def test_no_dependencies_anywhere
- dependencies nil
- assert_empty @keg.installed_dependents
- assert_nil Keg.find_some_installed_dependents([@keg])
- end
-
- def test_missing_formula_dependency
- dependencies nil
- Formula["bar"].class.depends_on "foo"
- assert_empty @keg.installed_dependents
- assert_equal [[@keg], ["bar"]], Keg.find_some_installed_dependents([@keg])
- end
-
- def test_uninstalling_dependent_and_dependency
- dependencies nil
- Formula["bar"].class.depends_on "foo"
- assert_empty @keg.installed_dependents
- assert_nil Keg.find_some_installed_dependents([@keg, @dependent])
- end
-
- def test_renamed_dependency
- dependencies nil
-
- stub_formula_loader Formula["foo"], "homebrew/core/foo-old"
- renamed_path = HOMEBREW_CELLAR/"foo-old"
- (HOMEBREW_CELLAR/"foo").rename(renamed_path)
- renamed_keg = Keg.new(renamed_path.join("1.0"))
-
- Formula["bar"].class.depends_on "foo"
-
- result = Keg.find_some_installed_dependents([renamed_keg])
- assert_equal [[renamed_keg], ["bar"]], result
- end
-
- def test_empty_dependencies_in_tab
- dependencies []
- assert_empty @keg.installed_dependents
- assert_nil Keg.find_some_installed_dependents([@keg])
- end
-
- def test_same_name_different_version_in_tab
- dependencies [{ "full_name" => "foo", "version" => "1.1" }]
- assert_equal [@dependent], @keg.installed_dependents
- assert_equal [[@keg], ["bar 1.0"]], Keg.find_some_installed_dependents([@keg])
- end
-
- def test_different_name_same_version_in_tab
- stub_formula_name("baz")
- dependencies [{ "full_name" => "baz", "version" => @keg.version.to_s }]
- assert_empty @keg.installed_dependents
- assert_nil Keg.find_some_installed_dependents([@keg])
- end
-
- def test_same_name_and_version_in_tab
- dependencies [{ "full_name" => "foo", "version" => "1.0" }]
- assert_equal [@dependent], @keg.installed_dependents
- assert_equal [[@keg], ["bar 1.0"]], Keg.find_some_installed_dependents([@keg])
- end
-
- def test_fallback_for_old_versions
- unreliable_dependencies [{ "full_name" => "baz", "version" => "1.0" }]
- Formula["bar"].class.depends_on "foo"
- assert_empty @keg.installed_dependents
- assert_equal [[@keg], ["bar"]], Keg.find_some_installed_dependents([@keg])
- end
-
- def test_nonoptlinked
- @keg.remove_opt_record
- dependencies [{ "full_name" => "foo", "version" => "1.0" }]
- assert_empty @keg.installed_dependents
- assert_nil Keg.find_some_installed_dependents([@keg])
- end
-
- def test_keg_only
- @keg.unlink
- Formula["foo"].class.keg_only "a good reason"
- dependencies [{ "full_name" => "foo", "version" => "1.1" }] # different version
- assert_equal [@dependent], @keg.installed_dependents
- assert_equal [[@keg], ["bar 1.0"]], Keg.find_some_installed_dependents([@keg])
- end
-end
diff --git a/Library/Homebrew/test/leaves_test.rb b/Library/Homebrew/test/leaves_test.rb
deleted file mode 100644
index f73fba1ea..000000000
--- a/Library/Homebrew/test/leaves_test.rb
+++ /dev/null
@@ -1,15 +0,0 @@
-require "testing_env"
-
-class IntegrationCommandTestLeaves < IntegrationCommandTestCase
- def test_leaves
- setup_test_formula "foo"
- setup_test_formula "bar"
- assert_equal "", cmd("leaves")
-
- (HOMEBREW_CELLAR/"foo/0.1/somedir").mkpath
- assert_equal "foo", cmd("leaves")
-
- (HOMEBREW_CELLAR/"bar/0.1/somedir").mkpath
- assert_equal "bar", cmd("leaves")
- end
-end
diff --git a/Library/Homebrew/test/link_test.rb b/Library/Homebrew/test/link_test.rb
deleted file mode 100644
index 062caa0c0..000000000
--- a/Library/Homebrew/test/link_test.rb
+++ /dev/null
@@ -1,23 +0,0 @@
-require "testing_env"
-
-class IntegrationCommandTestLink < IntegrationCommandTestCase
- def test_link
- assert_match "This command requires a keg argument", cmd_fail("link")
-
- setup_test_formula "testball1"
- cmd("install", "testball1")
- cmd("link", "testball1")
-
- cmd("unlink", "testball1")
- assert_match "Would link", cmd("link", "--dry-run", "testball1")
- assert_match "Would remove",
- cmd("link", "--dry-run", "--overwrite", "testball1")
- assert_match "Linking", cmd("link", "testball1")
-
- setup_test_formula "testball2", <<-EOS.undent
- keg_only "just because"
- EOS
- cmd("install", "testball2")
- assert_match "testball2 is keg-only", cmd("link", "testball2")
- end
-end
diff --git a/Library/Homebrew/test/linkapps_test.rb b/Library/Homebrew/test/linkapps_test.rb
deleted file mode 100644
index 4c5b8ec13..000000000
--- a/Library/Homebrew/test/linkapps_test.rb
+++ /dev/null
@@ -1,15 +0,0 @@
-require "testing_env"
-
-class IntegrationCommandTestLinkapps < IntegrationCommandTestCase
- def test_linkapps
- home_dir = Pathname.new(mktmpdir)
- (home_dir/"Applications").mkpath
-
- setup_test_formula "testball"
-
- source_dir = HOMEBREW_CELLAR/"testball/0.1/TestBall.app"
- source_dir.mkpath
- assert_match "Linking: #{source_dir}",
- cmd("linkapps", "--local", "HOME" => home_dir)
- end
-end
diff --git a/Library/Homebrew/test/list_test.rb b/Library/Homebrew/test/list_test.rb
deleted file mode 100644
index 3c691e3ad..000000000
--- a/Library/Homebrew/test/list_test.rb
+++ /dev/null
@@ -1,13 +0,0 @@
-require "testing_env"
-
-class IntegrationCommandTestList < IntegrationCommandTestCase
- def test_list
- formulae = %w[bar foo qux]
- formulae.each do |f|
- (HOMEBREW_CELLAR/"#{f}/1.0/somedir").mkpath
- end
-
- assert_equal formulae.join("\n"),
- cmd("list")
- end
-end
diff --git a/Library/Homebrew/test/log_formula_test.rb b/Library/Homebrew/test/log_formula_test.rb
deleted file mode 100644
index bb6a1f661..000000000
--- a/Library/Homebrew/test/log_formula_test.rb
+++ /dev/null
@@ -1,27 +0,0 @@
-require "testing_env"
-
-class IntegrationCommandTestLogFormula < IntegrationCommandTestCase
- def test_log_formula
- core_tap = CoreTap.new
- setup_test_formula "testball"
-
- 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
-
- assert_match "This is a test commit for Testball",
- cmd("log", "#{shallow_tap}/testball")
- assert_predicate shallow_tap.path/".git/shallow", :exist?,
- "A shallow clone should have been created."
- end
-end
diff --git a/Library/Homebrew/test/log_test.rb b/Library/Homebrew/test/log_test.rb
deleted file mode 100644
index b2e150ccd..000000000
--- a/Library/Homebrew/test/log_test.rb
+++ /dev/null
@@ -1,13 +0,0 @@
-require "testing_env"
-
-class IntegrationCommandTestLog < IntegrationCommandTestCase
- def test_log
- FileUtils.cd HOMEBREW_REPOSITORY do
- shutup do
- system "git", "init"
- system "git", "commit", "--allow-empty", "-m", "This is a test commit"
- end
- end
- assert_match "This is a test commit", cmd("log")
- end
-end
diff --git a/Library/Homebrew/test/migrate_test.rb b/Library/Homebrew/test/migrate_test.rb
deleted file mode 100644
index 17929d038..000000000
--- a/Library/Homebrew/test/migrate_test.rb
+++ /dev/null
@@ -1,18 +0,0 @@
-require "testing_env"
-
-class IntegrationCommandTestMigrate < IntegrationCommandTestCase
- def test_migrate
- setup_test_formula "testball1"
- setup_test_formula "testball2"
- assert_match "Invalid usage", cmd_fail("migrate")
- assert_match "No available formula with the name \"testball\"",
- cmd_fail("migrate", "testball")
- assert_match "testball1 doesn't replace any formula",
- cmd_fail("migrate", "testball1")
-
- install_and_rename_coretap_formula "testball1", "testball2"
- assert_match "Migrating testball1 to testball2", cmd("migrate", "testball1")
- (HOMEBREW_CELLAR/"testball1").unlink
- assert_match "Error: No such keg", cmd_fail("migrate", "testball1")
- end
-end
diff --git a/Library/Homebrew/test/migrator_spec.rb b/Library/Homebrew/test/migrator_spec.rb
new file mode 100644
index 000000000..90ee9d8ff
--- /dev/null
+++ b/Library/Homebrew/test/migrator_spec.rb
@@ -0,0 +1,264 @@
+require "migrator"
+require "test/support/fixtures/testball"
+require "tab"
+require "keg"
+
+describe Migrator do
+ subject { described_class.new(new_formula) }
+
+ let(:new_formula) { Testball.new("newname") }
+ let(:old_formula) { Testball.new("oldname") }
+
+ let(:new_keg_record) { HOMEBREW_CELLAR/"newname/0.1" }
+ let(:old_keg_record) { HOMEBREW_CELLAR/"oldname/0.1" }
+
+ let(:old_tab) { Tab.empty }
+
+ let(:keg) { Keg.new(old_keg_record) }
+ let(:old_pin) { HOMEBREW_PINNED_KEGS/"oldname" }
+
+ before(:each) do |example|
+ allow(new_formula).to receive(:oldname).and_return("oldname")
+
+ # do not create directories for error tests
+ next if example.metadata[:description].start_with?("raises an error")
+
+ (old_keg_record/"bin").mkpath
+
+ %w[inside bindir].each do |file|
+ FileUtils.touch old_keg_record/"bin/#{file}"
+ end
+
+ old_tab.tabfile = HOMEBREW_CELLAR/"oldname/0.1/INSTALL_RECEIPT.json"
+ old_tab.source["path"] = "/oldname"
+ old_tab.write
+
+ keg.link
+ keg.optlink
+
+ old_pin.make_relative_symlink old_keg_record
+
+ subject # needs to be evaluated eagerly
+
+ (HOMEBREW_PREFIX/"bin").mkpath
+ end
+
+ after(:each) do
+ if !old_keg_record.parent.symlink? && old_keg_record.directory?
+ keg.unlink
+ end
+
+ if new_keg_record.directory?
+ new_keg = Keg.new(new_keg_record)
+ new_keg.unlink
+ end
+ end
+
+ describe "::new" do
+ it "raises an error if there is no old name" do
+ expect {
+ described_class.new(old_formula)
+ }.to raise_error(Migrator::MigratorNoOldnameError)
+ end
+
+ it "raises an error if there is no old path" do
+ expect {
+ described_class.new(new_formula)
+ }.to raise_error(Migrator::MigratorNoOldpathError)
+ end
+
+ it "raises an error if the Taps differ" do
+ keg = HOMEBREW_CELLAR/"oldname/0.1"
+ keg.mkpath
+ tab = Tab.empty
+ tab.tabfile = HOMEBREW_CELLAR/"oldname/0.1/INSTALL_RECEIPT.json"
+ tab.source["tap"] = "homebrew/core"
+ tab.write
+
+ expect {
+ described_class.new(new_formula)
+ }.to raise_error(Migrator::MigratorDifferentTapsError)
+ end
+ end
+
+ specify "#move_to_new_directory" do
+ keg.unlink
+ shutup do
+ subject.move_to_new_directory
+ end
+
+ expect(new_keg_record).to be_a_directory
+ expect(new_keg_record/"bin").to be_a_directory
+ expect(new_keg_record/"bin/inside").to be_a_file
+ expect(new_keg_record/"bin/bindir").to be_a_file
+ expect(old_keg_record).not_to be_a_directory
+ end
+
+ specify "#backup_oldname_cellar" do
+ old_keg_record.parent.rmtree
+ (new_keg_record/"bin").mkpath
+
+ subject.backup_oldname_cellar
+
+ expect(old_keg_record/"bin").to be_a_directory
+ expect(old_keg_record/"bin").to be_a_directory
+ end
+
+ specify "#repin" do
+ (new_keg_record/"bin").mkpath
+ expected_relative = new_keg_record.relative_path_from HOMEBREW_PINNED_KEGS
+
+ subject.repin
+
+ expect(subject.new_pin_record).to be_a_symlink
+ expect(subject.new_pin_record.readlink).to eq(expected_relative)
+ expect(subject.old_pin_record).not_to exist
+ end
+
+ specify "#unlink_oldname" do
+ expect(HOMEBREW_LINKED_KEGS.children.count).to eq(1)
+ expect((HOMEBREW_PREFIX/"opt").children.count).to eq(1)
+
+ shutup do
+ subject.unlink_oldname
+ end
+
+ expect(HOMEBREW_LINKED_KEGS).not_to exist
+ expect(HOMEBREW_LIBRARY/"bin").not_to exist
+ end
+
+ specify "#link_newname" do
+ keg.unlink
+ keg.uninstall
+
+ (new_keg_record/"bin").mkpath
+ %w[inside bindir].each do |file|
+ FileUtils.touch new_keg_record/"bin"/file
+ end
+
+ shutup do
+ subject.link_newname
+ end
+
+ expect(HOMEBREW_LINKED_KEGS.children.count).to eq(1)
+ expect((HOMEBREW_PREFIX/"opt").children.count).to eq(1)
+ end
+
+ specify "#link_oldname_opt" do
+ new_keg_record.mkpath
+ subject.link_oldname_opt
+ expect((HOMEBREW_PREFIX/"opt/oldname").realpath).to eq(new_keg_record.realpath)
+ end
+
+ specify "#link_oldname_cellar" do
+ (new_keg_record/"bin").mkpath
+ keg.unlink
+ keg.uninstall
+ subject.link_oldname_cellar
+ expect((HOMEBREW_CELLAR/"oldname").realpath).to eq(new_keg_record.parent.realpath)
+ end
+
+ specify "#update_tabs" do
+ (new_keg_record/"bin").mkpath
+ tab = Tab.empty
+ tab.tabfile = HOMEBREW_CELLAR/"newname/0.1/INSTALL_RECEIPT.json"
+ tab.source["path"] = "/path/that/must/be/changed/by/update_tabs"
+ tab.write
+ subject.update_tabs
+ expect(Tab.for_keg(new_keg_record).source["path"]).to eq(new_formula.path.to_s)
+ end
+
+ specify "#migrate" do
+ tab = Tab.empty
+ tab.tabfile = HOMEBREW_CELLAR/"oldname/0.1/INSTALL_RECEIPT.json"
+ tab.source["path"] = old_formula.path.to_s
+ tab.write
+
+ shutup do
+ subject.migrate
+ end
+
+ expect(new_keg_record).to exist
+ expect(old_keg_record.parent).to be_a_symlink
+ expect(HOMEBREW_LINKED_KEGS/"oldname").not_to exist
+ expect((HOMEBREW_LINKED_KEGS/"newname").realpath).to eq(new_keg_record.realpath)
+ expect(old_keg_record.realpath).to eq(new_keg_record.realpath)
+ expect((HOMEBREW_PREFIX/"opt/oldname").realpath).to eq(new_keg_record.realpath)
+ expect((HOMEBREW_CELLAR/"oldname").realpath).to eq(new_keg_record.parent.realpath)
+ expect((HOMEBREW_PINNED_KEGS/"newname").realpath).to eq(new_keg_record.realpath)
+ expect(Tab.for_keg(new_keg_record).source["path"]).to eq(new_formula.path.to_s)
+ end
+
+ specify "#unlinik_oldname_opt" do
+ new_keg_record.mkpath
+ old_opt_record = HOMEBREW_PREFIX/"opt/oldname"
+ old_opt_record.unlink if old_opt_record.symlink?
+ old_opt_record.make_relative_symlink(new_keg_record)
+ subject.unlink_oldname_opt
+ expect(old_opt_record).not_to be_a_symlink
+ end
+
+ specify "#unlink_oldname_cellar" do
+ new_keg_record.mkpath
+ keg.unlink
+ keg.uninstall
+ old_keg_record.parent.make_relative_symlink(new_keg_record.parent)
+ subject.unlink_oldname_cellar
+ expect(old_keg_record.parent).not_to be_a_symlink
+ end
+
+ specify "#backup_oldname_cellar" do
+ (new_keg_record/"bin").mkpath
+ keg.unlink
+ keg.uninstall
+ subject.backup_oldname_cellar
+ expect(old_keg_record.subdirs).not_to be_empty
+ end
+
+ specify "#backup_old_tabs" do
+ tab = Tab.empty
+ tab.tabfile = HOMEBREW_CELLAR/"oldname/0.1/INSTALL_RECEIPT.json"
+ tab.source["path"] = "/should/be/the/same"
+ tab.write
+ migrator = Migrator.new(new_formula)
+ tab.tabfile.delete
+ migrator.backup_old_tabs
+ expect(Tab.for_keg(old_keg_record).source["path"]).to eq("/should/be/the/same")
+ end
+
+ describe "#backup_oldname" do
+ after(:each) do
+ expect(old_keg_record.parent).to be_a_directory
+ expect(old_keg_record.parent.subdirs).not_to be_empty
+ expect(HOMEBREW_LINKED_KEGS/"oldname").to exist
+ expect(HOMEBREW_PREFIX/"opt/oldname").to exist
+ expect(HOMEBREW_PINNED_KEGS/"oldname").to be_a_symlink
+ expect(keg).to be_linked
+ end
+
+ context "when cellar exists" do
+ it "backs up the old name" do
+ subject.backup_oldname
+ end
+ end
+
+ context "when cellar is removed" do
+ it "backs up the old name" do
+ (new_keg_record/"bin").mkpath
+ keg.unlink
+ keg.uninstall
+ subject.backup_oldname
+ end
+ end
+
+ context "when cellar is linked" do
+ it "backs up the old name" do
+ (new_keg_record/"bin").mkpath
+ keg.unlink
+ keg.uninstall
+ old_keg_record.parent.make_relative_symlink(new_keg_record.parent)
+ subject.backup_oldname
+ end
+ end
+ end
+end
diff --git a/Library/Homebrew/test/migrator_test.rb b/Library/Homebrew/test/migrator_test.rb
deleted file mode 100644
index 012ea12bb..000000000
--- a/Library/Homebrew/test/migrator_test.rb
+++ /dev/null
@@ -1,251 +0,0 @@
-require "testing_env"
-require "migrator"
-require "test/support/fixtures/testball"
-require "tab"
-require "keg"
-
-class Formula
- attr_writer :oldname
-end
-
-class MigratorErrorsTests < Homebrew::TestCase
- def setup
- super
- @new_f = Testball.new("newname")
- @new_f.oldname = "oldname"
- @old_f = Testball.new("oldname")
- end
-
- def test_no_oldname
- assert_raises(Migrator::MigratorNoOldnameError) { Migrator.new(@old_f) }
- end
-
- def test_no_oldpath
- assert_raises(Migrator::MigratorNoOldpathError) { Migrator.new(@new_f) }
- end
-
- def test_different_taps
- keg = HOMEBREW_CELLAR/"oldname/0.1"
- keg.mkpath
- tab = Tab.empty
- tab.tabfile = HOMEBREW_CELLAR/"oldname/0.1/INSTALL_RECEIPT.json"
- tab.source["tap"] = "homebrew/core"
- tab.write
- assert_raises(Migrator::MigratorDifferentTapsError) { Migrator.new(@new_f) }
- end
-end
-
-class MigratorTests < Homebrew::TestCase
- include FileUtils
-
- def setup
- super
-
- @new_f = Testball.new("newname")
- @new_f.oldname = "oldname"
-
- @old_f = Testball.new("oldname")
-
- @old_keg_record = HOMEBREW_CELLAR/"oldname/0.1"
- @old_keg_record.join("bin").mkpath
- @new_keg_record = HOMEBREW_CELLAR/"newname/0.1"
-
- %w[inside bindir].each { |file| touch @old_keg_record.join("bin", file) }
-
- @old_tab = Tab.empty
- @old_tab.tabfile = HOMEBREW_CELLAR/"oldname/0.1/INSTALL_RECEIPT.json"
- @old_tab.source["path"] = "/oldname"
- @old_tab.write
-
- @keg = Keg.new(@old_keg_record)
- @keg.link
- @keg.optlink
-
- @old_pin = HOMEBREW_PINNED_KEGS/"oldname"
- @old_pin.make_relative_symlink @old_keg_record
-
- @migrator = Migrator.new(@new_f)
-
- mkpath HOMEBREW_PREFIX/"bin"
- end
-
- def teardown
- if !@old_keg_record.parent.symlink? && @old_keg_record.directory?
- @keg.unlink
- end
-
- if @new_keg_record.directory?
- new_keg = Keg.new(@new_keg_record)
- new_keg.unlink
- end
-
- super
- end
-
- def test_move_cellar
- @keg.unlink
- shutup { @migrator.move_to_new_directory }
- assert_predicate @new_keg_record, :directory?
- assert_predicate @new_keg_record/"bin", :directory?
- assert_predicate @new_keg_record/"bin/inside", :file?
- assert_predicate @new_keg_record/"bin/bindir", :file?
- refute_predicate @old_keg_record, :directory?
- end
-
- def test_backup_cellar
- @old_keg_record.parent.rmtree
- @new_keg_record.join("bin").mkpath
-
- @migrator.backup_oldname_cellar
-
- assert_predicate @old_keg_record, :directory?
- assert_predicate @old_keg_record/"bin", :directory?
- end
-
- def test_repin
- @new_keg_record.join("bin").mkpath
- expected_relative = @new_keg_record.relative_path_from HOMEBREW_PINNED_KEGS
-
- @migrator.repin
-
- assert_predicate @migrator.new_pin_record, :symlink?
- assert_equal expected_relative, @migrator.new_pin_record.readlink
- refute_predicate @migrator.old_pin_record, :exist?
- end
-
- def test_unlink_oldname
- assert_equal 1, HOMEBREW_LINKED_KEGS.children.size
- assert_equal 1, (HOMEBREW_PREFIX/"opt").children.size
-
- shutup { @migrator.unlink_oldname }
-
- refute_predicate HOMEBREW_LINKED_KEGS, :exist?
- refute_predicate HOMEBREW_LIBRARY/"bin", :exist?
- end
-
- def test_link_newname
- @keg.unlink
- @keg.uninstall
- @new_keg_record.join("bin").mkpath
- %w[inside bindir].each { |file| touch @new_keg_record.join("bin", file) }
-
- shutup { @migrator.link_newname }
-
- assert_equal 1, HOMEBREW_LINKED_KEGS.children.size
- assert_equal 1, (HOMEBREW_PREFIX/"opt").children.size
- end
-
- def test_link_oldname_opt
- @new_keg_record.mkpath
- @migrator.link_oldname_opt
- assert_equal @new_keg_record.realpath, (HOMEBREW_PREFIX/"opt/oldname").realpath
- end
-
- def test_link_oldname_cellar
- @new_keg_record.join("bin").mkpath
- @keg.unlink
- @keg.uninstall
- @migrator.link_oldname_cellar
- assert_equal @new_keg_record.parent.realpath, (HOMEBREW_CELLAR/"oldname").realpath
- end
-
- def test_update_tabs
- @new_keg_record.join("bin").mkpath
- tab = Tab.empty
- tab.tabfile = HOMEBREW_CELLAR/"newname/0.1/INSTALL_RECEIPT.json"
- tab.source["path"] = "/path/that/must/be/changed/by/update_tabs"
- tab.write
- @migrator.update_tabs
- assert_equal @new_f.path.to_s, Tab.for_keg(@new_keg_record).source["path"]
- end
-
- def test_migrate
- tab = Tab.empty
- tab.tabfile = HOMEBREW_CELLAR/"oldname/0.1/INSTALL_RECEIPT.json"
- tab.source["path"] = @old_f.path.to_s
- tab.write
-
- shutup { @migrator.migrate }
-
- assert_predicate @new_keg_record, :exist?
- assert_predicate @old_keg_record.parent, :symlink?
- refute_predicate HOMEBREW_LINKED_KEGS/"oldname", :exist?
- assert_equal @new_keg_record.realpath, (HOMEBREW_LINKED_KEGS/"newname").realpath
- assert_equal @new_keg_record.realpath, @old_keg_record.realpath
- assert_equal @new_keg_record.realpath, (HOMEBREW_PREFIX/"opt/oldname").realpath
- assert_equal @new_keg_record.parent.realpath, (HOMEBREW_CELLAR/"oldname").realpath
- assert_equal @new_keg_record.realpath, (HOMEBREW_PINNED_KEGS/"newname").realpath
- assert_equal @new_f.path.to_s, Tab.for_keg(@new_keg_record).source["path"]
- end
-
- def test_unlinik_oldname_opt
- @new_keg_record.mkpath
- old_opt_record = HOMEBREW_PREFIX/"opt/oldname"
- old_opt_record.unlink if old_opt_record.symlink?
- old_opt_record.make_relative_symlink(@new_keg_record)
- @migrator.unlink_oldname_opt
- refute_predicate old_opt_record, :symlink?
- end
-
- def test_unlink_oldname_cellar
- @new_keg_record.mkpath
- @keg.unlink
- @keg.uninstall
- @old_keg_record.parent.make_relative_symlink(@new_keg_record.parent)
- @migrator.unlink_oldname_cellar
- refute_predicate @old_keg_record.parent, :symlink?
- end
-
- def test_backup_oldname_cellar
- @new_keg_record.join("bin").mkpath
- @keg.unlink
- @keg.uninstall
- @migrator.backup_oldname_cellar
- refute_predicate @old_keg_record.subdirs, :empty?
- end
-
- def test_backup_old_tabs
- tab = Tab.empty
- tab.tabfile = HOMEBREW_CELLAR/"oldname/0.1/INSTALL_RECEIPT.json"
- tab.source["path"] = "/should/be/the/same"
- tab.write
- migrator = Migrator.new(@new_f)
- tab.tabfile.delete
- migrator.backup_old_tabs
- assert_equal "/should/be/the/same", Tab.for_keg(@old_keg_record).source["path"]
- end
-
- # Backup tests are divided into three groups: when oldname Cellar is deleted
- # and when it still exists and when it's a symlink
-
- def check_after_backup
- assert_predicate @old_keg_record.parent, :directory?
- refute_predicate @old_keg_record.parent.subdirs, :empty?
- assert_predicate HOMEBREW_LINKED_KEGS/"oldname", :exist?
- assert_predicate HOMEBREW_PREFIX/"opt/oldname", :exist?
- assert_predicate HOMEBREW_PINNED_KEGS/"oldname", :symlink?
- assert_predicate @keg, :linked?
- end
-
- def test_backup_cellar_exist
- @migrator.backup_oldname
- check_after_backup
- end
-
- def test_backup_cellar_removed
- @new_keg_record.join("bin").mkpath
- @keg.unlink
- @keg.uninstall
- @migrator.backup_oldname
- check_after_backup
- end
-
- def test_backup_cellar_linked
- @new_keg_record.join("bin").mkpath
- @keg.unlink
- @keg.uninstall
- @old_keg_record.parent.make_relative_symlink(@new_keg_record.parent)
- @migrator.backup_oldname
- check_after_backup
- end
-end
diff --git a/Library/Homebrew/test/missing_test.rb b/Library/Homebrew/test/missing_test.rb
deleted file mode 100644
index 4f20d8a7a..000000000
--- a/Library/Homebrew/test/missing_test.rb
+++ /dev/null
@@ -1,34 +0,0 @@
-require "testing_env"
-
-class IntegrationCommandTestMissing < IntegrationCommandTestCase
- def setup
- super
-
- setup_test_formula "foo"
- setup_test_formula "bar"
- end
-
- def make_prefix(name)
- (HOMEBREW_CELLAR/name/"1.0").mkpath
- end
-
- def test_missing_missing
- make_prefix "bar"
-
- assert_match "foo", cmd("missing")
- end
-
- def test_missing_not_missing
- make_prefix "foo"
- make_prefix "bar"
-
- assert_empty cmd("missing")
- end
-
- def test_missing_hide
- make_prefix "foo"
- make_prefix "bar"
-
- assert_match "foo", cmd("missing", "--hide=foo")
- end
-end
diff --git a/Library/Homebrew/test/options_spec.rb b/Library/Homebrew/test/options_spec.rb
new file mode 100644
index 000000000..a05bb139e
--- /dev/null
+++ b/Library/Homebrew/test/options_spec.rb
@@ -0,0 +1,148 @@
+require "options"
+
+describe Option do
+ subject { described_class.new("foo") }
+
+ specify "#to_s" do
+ expect(subject.to_s).to eq("--foo")
+ end
+
+ specify "equality" do
+ foo = Option.new("foo")
+ bar = Option.new("bar")
+ expect(subject).to eq(foo)
+ expect(subject).not_to eq(bar)
+ expect(subject).to eql(foo)
+ expect(subject).not_to eql(bar)
+ end
+
+ specify "#description" do
+ expect(subject.description).to be_empty
+ expect(Option.new("foo", "foo").description).to eq("foo")
+ end
+
+ specify "#inspect" do
+ expect(subject.inspect).to eq("#<Option: \"--foo\">")
+ end
+end
+
+describe DeprecatedOption do
+ subject { described_class.new("foo", "bar") }
+
+ specify "#old" do
+ expect(subject.old).to eq("foo")
+ end
+
+ specify "#old_flag" do
+ expect(subject.old_flag).to eq("--foo")
+ end
+
+ specify "#current" do
+ expect(subject.current).to eq("bar")
+ end
+
+ specify "#current_flag" do
+ expect(subject.current_flag).to eq("--bar")
+ end
+
+ specify "equality" do
+ foobar = DeprecatedOption.new("foo", "bar")
+ boofar = DeprecatedOption.new("boo", "far")
+ expect(foobar).to eq(subject)
+ expect(subject).to eq(foobar)
+ expect(boofar).not_to eq(subject)
+ expect(subject).not_to eq(boofar)
+ end
+end
+
+describe Options do
+ it "removes duplicate options" do
+ subject << Option.new("foo")
+ subject << Option.new("foo")
+ expect(subject).to include("--foo")
+ expect(subject.count).to eq(1)
+ end
+
+ it "preserves existing member when adding a duplicate" do
+ a = Option.new("foo", "bar")
+ b = Option.new("foo", "qux")
+ subject << a << b
+ expect(subject.count).to eq(1)
+ expect(subject.first).to be(a)
+ expect(subject.first.description).to eq(a.description)
+ end
+
+ specify "#include?" do
+ subject << Option.new("foo")
+ expect(subject).to include("--foo")
+ expect(subject).to include("foo")
+ expect(subject).to include(Option.new("foo"))
+ end
+
+ describe "#+" do
+ it "returns options" do
+ expect(subject + Options.new).to be_an_instance_of(Options)
+ end
+ end
+
+ describe "#-" do
+ it "returns options" do
+ expect(subject - Options.new).to be_an_instance_of(Options)
+ end
+ end
+
+ specify "#&" do
+ foo, bar, baz = %w[foo bar baz].map { |o| Option.new(o) }
+ options = Options.new << foo << bar
+ subject << foo << baz
+ expect((subject & options).to_a).to eq([foo])
+ end
+
+ specify "#|" do
+ foo, bar, baz = %w[foo bar baz].map { |o| Option.new(o) }
+ options = Options.new << foo << bar
+ subject << foo << baz
+ expect((subject | options).sort).to eq([foo, bar, baz].sort)
+ end
+
+ specify "#*" do
+ subject << Option.new("aa") << Option.new("bb") << Option.new("cc")
+ expect((subject * "XX").split("XX").sort).to eq(%w[--aa --bb --cc])
+ end
+
+ describe "<<" do
+ it "returns itself" do
+ expect(subject << Option.new("foo")).to be subject
+ end
+ end
+
+ specify "#as_flags" do
+ subject << Option.new("foo")
+ expect(subject.as_flags).to eq(%w[--foo])
+ end
+
+ specify "#to_a" do
+ option = Option.new("foo")
+ subject << option
+ expect(subject.to_a).to eq([option])
+ end
+
+ specify "#to_ary" do
+ option = Option.new("foo")
+ subject << option
+ expect(subject.to_ary).to eq([option])
+ end
+
+ specify "::create_with_array" do
+ array = %w[--foo --bar]
+ option1 = Option.new("foo")
+ option2 = Option.new("bar")
+ expect(Options.create(array).sort).to eq([option1, option2].sort)
+ end
+
+ specify "#inspect" do
+ expect(subject.inspect).to eq("#<Options: []>")
+ subject << Option.new("foo")
+ expect(subject.inspect).to eq("#<Options: [#<Option: \"--foo\">]>")
+ end
+end
diff --git a/Library/Homebrew/test/options_test.rb b/Library/Homebrew/test/options_test.rb
deleted file mode 100644
index 09ea14180..000000000
--- a/Library/Homebrew/test/options_test.rb
+++ /dev/null
@@ -1,160 +0,0 @@
-require "testing_env"
-require "options"
-require "testing_env"
-
-class IntegrationCommandTestOptions < IntegrationCommandTestCase
- def test_options
- setup_test_formula "testball", <<-EOS.undent
- depends_on "bar" => :recommended
- EOS
-
- assert_equal "--with-foo\n\tBuild with foo\n--without-bar\n\tBuild without bar support",
- cmd("options", "testball").chomp
- end
-end
-
-class OptionTests < Homebrew::TestCase
- def setup
- super
- @option = Option.new("foo")
- end
-
- def test_to_s
- assert_equal "--foo", @option.to_s
- end
-
- def test_equality
- foo = Option.new("foo")
- bar = Option.new("bar")
- assert_equal foo, @option
- refute_equal bar, @option
- assert_eql @option, foo
- refute_eql @option, bar
- end
-
- def test_description
- assert_empty @option.description
- assert_equal "foo", Option.new("foo", "foo").description
- end
-
- def test_inspect
- assert_equal "#<Option: \"--foo\">", @option.inspect
- end
-end
-
-class DeprecatedOptionTests < Homebrew::TestCase
- def setup
- super
- @deprecated_option = DeprecatedOption.new("foo", "bar")
- end
-
- def test_old
- assert_equal "foo", @deprecated_option.old
- assert_equal "--foo", @deprecated_option.old_flag
- end
-
- def test_current
- assert_equal "bar", @deprecated_option.current
- assert_equal "--bar", @deprecated_option.current_flag
- end
-
- def test_equality
- foobar = DeprecatedOption.new("foo", "bar")
- boofar = DeprecatedOption.new("boo", "far")
- assert_equal foobar, @deprecated_option
- refute_equal boofar, @deprecated_option
- assert_eql @deprecated_option, foobar
- refute_eql @deprecated_option, boofar
- end
-end
-
-class OptionsTests < Homebrew::TestCase
- def setup
- super
- @options = Options.new
- end
-
- def test_no_duplicate_options
- @options << Option.new("foo")
- @options << Option.new("foo")
- assert_includes @options, "--foo"
- assert_equal 1, @options.count
- end
-
- def test_preserves_existing_member_when_pushing_duplicate
- a = Option.new("foo", "bar")
- b = Option.new("foo", "qux")
- @options << a << b
- assert_equal 1, @options.count
- assert_same a, @options.first
- assert_equal a.description, @options.first.description
- end
-
- def test_include
- @options << Option.new("foo")
- assert_includes @options, "--foo"
- assert_includes @options, "foo"
- assert_includes @options, Option.new("foo")
- end
-
- def test_union_returns_options
- assert_instance_of Options, @options + Options.new
- end
-
- def test_difference_returns_options
- assert_instance_of Options, @options - Options.new
- end
-
- def test_shovel_returns_self
- assert_same @options, @options << Option.new("foo")
- end
-
- def test_as_flags
- @options << Option.new("foo")
- assert_equal %w[--foo], @options.as_flags
- end
-
- def test_to_a
- option = Option.new("foo")
- @options << option
- assert_equal [option], @options.to_a
- end
-
- def test_to_ary
- option = Option.new("foo")
- @options << option
- assert_equal [option], @options.to_ary
- end
-
- def test_intersection
- foo, bar, baz = %w[foo bar baz].map { |o| Option.new(o) }
- options = Options.new << foo << bar
- @options << foo << baz
- assert_equal [foo], (@options & options).to_a
- end
-
- def test_set_union
- foo, bar, baz = %w[foo bar baz].map { |o| Option.new(o) }
- options = Options.new << foo << bar
- @options << foo << baz
- assert_equal [foo, bar, baz].sort, (@options | options).sort
- end
-
- def test_times
- @options << Option.new("aa") << Option.new("bb") << Option.new("cc")
- assert_equal %w[--aa --bb --cc], (@options * "XX").split("XX").sort
- end
-
- def test_create_with_array
- array = %w[--foo --bar]
- option1 = Option.new("foo")
- option2 = Option.new("bar")
- assert_equal [option1, option2].sort, Options.create(array).sort
- end
-
- def test_inspect
- assert_equal "#<Options: []>", @options.inspect
- @options << Option.new("foo")
- assert_equal "#<Options: [#<Option: \"--foo\">]>", @options.inspect
- end
-end
diff --git a/Library/Homebrew/test/os/mac/bottle_tag_test.rb b/Library/Homebrew/test/os/mac/bottle_tag_test.rb
deleted file mode 100644
index 996bd4d53..000000000
--- a/Library/Homebrew/test/os/mac/bottle_tag_test.rb
+++ /dev/null
@@ -1,79 +0,0 @@
-require "testing_env"
-require "utils/bottles"
-
-class OSMacBottleTagTests < Homebrew::TestCase
- def test_tag_tiger_ppc
- MacOS.stubs(:version).returns(MacOS::Version.new("10.4"))
- Hardware::CPU.stubs(:type).returns(:ppc)
- Hardware::CPU.stubs(:family).returns(:foo)
- MacOS.stubs(:prefer_64_bit?).returns(false)
- assert_equal :tiger_foo, Utils::Bottles.tag
- end
-
- def test_tag_tiger_intel
- MacOS.stubs(:version).returns(MacOS::Version.new("10.4"))
- Hardware::CPU.stubs(:type).returns(:intel)
- MacOS.stubs(:prefer_64_bit?).returns(false)
- assert_equal :tiger, Utils::Bottles.tag
- end
-
- def test_tag_tiger_ppc_64
- MacOS.stubs(:version).returns(MacOS::Version.new("10.4"))
- Hardware::CPU.stubs(:type).returns(:ppc)
- Hardware::CPU.stubs(:family).returns(:g5)
- MacOS.stubs(:prefer_64_bit?).returns(true)
- assert_equal :tiger_g5_64, Utils::Bottles.tag
- end
-
- # Note that this will probably never be used
- def test_tag_tiger_intel_64
- MacOS.stubs(:version).returns(MacOS::Version.new("10.4"))
- Hardware::CPU.stubs(:type).returns(:intel)
- MacOS.stubs(:prefer_64_bit?).returns(true)
- assert_equal :tiger_64, Utils::Bottles.tag
- end
-
- def test_tag_leopard_intel
- MacOS.stubs(:version).returns(MacOS::Version.new("10.5"))
- Hardware::CPU.stubs(:type).returns(:intel)
- MacOS.stubs(:prefer_64_bit?).returns(false)
- assert_equal :leopard, Utils::Bottles.tag
- end
-
- def test_tag_leopard_ppc_64
- MacOS.stubs(:version).returns(MacOS::Version.new("10.5"))
- Hardware::CPU.stubs(:type).returns(:ppc)
- Hardware::CPU.stubs(:family).returns(:g5)
- MacOS.stubs(:prefer_64_bit?).returns(true)
- assert_equal :leopard_g5_64, Utils::Bottles.tag
- end
-
- def test_tag_leopard_intel_64
- MacOS.stubs(:version).returns(MacOS::Version.new("10.5"))
- Hardware::CPU.stubs(:type).returns(:intel)
- MacOS.stubs(:prefer_64_bit?).returns(true)
- assert_equal :leopard_64, Utils::Bottles.tag
- end
-
- def test_tag_snow_leopard_32
- MacOS.stubs(:version).returns(MacOS::Version.new("10.6"))
- Hardware::CPU.stubs(:is_64_bit?).returns(false)
- assert_equal :snow_leopard_32, Utils::Bottles.tag
- end
-
- def test_tag_snow_leopard_64
- MacOS.stubs(:version).returns(MacOS::Version.new("10.6"))
- Hardware::CPU.stubs(:is_64_bit?).returns(true)
- assert_equal :snow_leopard, Utils::Bottles.tag
- end
-
- def test_tag_lion
- MacOS.stubs(:version).returns(MacOS::Version.new("10.7"))
- assert_equal :lion, Utils::Bottles.tag
- end
-
- def test_tag_mountain_lion
- MacOS.stubs(:version).returns(MacOS::Version.new("10.8"))
- assert_equal :mountain_lion, Utils::Bottles.tag
- end
-end
diff --git a/Library/Homebrew/test/os/mac/dependency_collector_spec.rb b/Library/Homebrew/test/os/mac/dependency_collector_spec.rb
new file mode 100644
index 000000000..21b15cd99
--- /dev/null
+++ b/Library/Homebrew/test/os/mac/dependency_collector_spec.rb
@@ -0,0 +1,50 @@
+require "dependency_collector"
+
+RSpec::Matchers.alias_matcher :need_tar_xz_dependency, :be_tar_needs_xz_dependency
+
+describe DependencyCollector do
+ after(:each) do
+ described_class.clear_cache
+ end
+
+ specify "#tar_needs_xz_dependency?" do
+ allow(MacOS).to receive(:version).and_return(MacOS::Version.new("10.9"))
+ expect(described_class).not_to need_tar_xz_dependency
+ end
+
+ specify "LD64 pre-Leopard dependency" do
+ allow(MacOS).to receive(:version).and_return(MacOS::Version.new("10.4"))
+ expect(subject.build(:ld64)).to eq(LD64Dependency.new)
+ end
+
+ specify "LD64 Leopard or newer dependency" do
+ allow(MacOS).to receive(:version).and_return(MacOS::Version.new("10.5"))
+ expect(subject.build(:ld64)).to be nil
+ end
+
+ specify "ant Mavericks or newer dependency" do
+ allow(MacOS).to receive(:version).and_return(MacOS::Version.new("10.9"))
+ subject.add ant: :build
+ expect(subject.deps.find { |dep| dep.name == "ant" }).to eq(Dependency.new("ant", [:build]))
+ end
+
+ specify "ant pre-Mavericks dependency" do
+ allow(MacOS).to receive(:version).and_return(MacOS::Version.new("10.7"))
+ subject.add ant: :build
+ expect(subject.deps.find { |dep| dep.name == "ant" }).to be nil
+ end
+
+ specify "Resource xz pre-Mavericks dependency" do
+ allow(MacOS).to receive(:version).and_return(MacOS::Version.new("10.8"))
+ resource = Resource.new
+ resource.url("http://example.com/foo.tar.xz")
+ expect(subject.add(resource)).to eq(Dependency.new("xz", [:build]))
+ end
+
+ specify "Resource xz Mavericks or newer dependency" do
+ allow(MacOS).to receive(:version).and_return(MacOS::Version.new("10.9"))
+ resource = Resource.new
+ resource.url("http://example.com/foo.tar.xz")
+ expect(subject.add(resource)).to be nil
+ end
+end
diff --git a/Library/Homebrew/test/os/mac/dependency_collector_test.rb b/Library/Homebrew/test/os/mac/dependency_collector_test.rb
deleted file mode 100644
index 1033df9ab..000000000
--- a/Library/Homebrew/test/os/mac/dependency_collector_test.rb
+++ /dev/null
@@ -1,59 +0,0 @@
-require "testing_env"
-require "dependency_collector"
-
-class OSMacDependencyCollectorTests < Homebrew::TestCase
- def find_dependency(name)
- @d.deps.find { |dep| dep.name == name }
- end
-
- def setup
- super
- @d = DependencyCollector.new
- end
-
- def teardown
- DependencyCollector.clear_cache
- super
- end
-
- def test_tar_needs_xz_dependency
- MacOS.stubs(:version).returns(MacOS::Version.new("10.9"))
- refute DependencyCollector.tar_needs_xz_dependency?
- end
-
- def test_ld64_dep_pre_leopard
- MacOS.stubs(:version).returns(MacOS::Version.new("10.4"))
- assert_equal LD64Dependency.new, @d.build(:ld64)
- end
-
- def test_ld64_dep_leopard_or_newer
- MacOS.stubs(:version).returns(MacOS::Version.new("10.5"))
- assert_nil @d.build(:ld64)
- end
-
- def test_ant_dep_mavericks_or_newer
- MacOS.stubs(:version).returns(MacOS::Version.new("10.9"))
- @d.add ant: :build
- assert_equal find_dependency("ant"), Dependency.new("ant", [:build])
- end
-
- def test_ant_dep_pre_mavericks
- MacOS.stubs(:version).returns(MacOS::Version.new("10.7"))
- @d.add ant: :build
- assert_nil find_dependency("ant")
- end
-
- def test_resource_dep_xz_pre_mavericks
- MacOS.stubs(:version).returns(MacOS::Version.new("10.8"))
- resource = Resource.new
- resource.url("http://example.com/foo.tar.xz")
- assert_equal Dependency.new("xz", [:build]), @d.add(resource)
- end
-
- def test_resource_dep_xz_mavericks_or_newer
- MacOS.stubs(:version).returns(MacOS::Version.new("10.9"))
- resource = Resource.new
- resource.url("http://example.com/foo.tar.xz")
- assert_nil @d.add(resource)
- end
-end
diff --git a/Library/Homebrew/test/os/mac/diagnostic_spec.rb b/Library/Homebrew/test/os/mac/diagnostic_spec.rb
new file mode 100644
index 000000000..d2b38a332
--- /dev/null
+++ b/Library/Homebrew/test/os/mac/diagnostic_spec.rb
@@ -0,0 +1,42 @@
+require "diagnostic"
+
+describe Homebrew::Diagnostic::Checks do
+ specify "#check_for_other_package_managers" do
+ allow(MacOS).to receive(:macports_or_fink).and_return(["fink"])
+ expect(subject.check_for_other_package_managers)
+ .to match("You have MacPorts or Fink installed:")
+ end
+
+ specify "#check_for_unsupported_macos" do
+ ENV.delete("HOMEBREW_DEVELOPER")
+ allow(OS::Mac).to receive(:prerelease?).and_return(true)
+
+ expect(subject.check_for_unsupported_macos)
+ .to match("We do not provide support for this pre-release version.")
+ end
+
+ specify "#check_for_unsupported_curl_vars" do
+ allow(MacOS).to receive(:version).and_return(OS::Mac::Version.new("10.10"))
+ ENV["SSL_CERT_DIR"] = "/some/path"
+
+ expect(subject.check_for_unsupported_curl_vars)
+ .to match("SSL_CERT_DIR support was removed from Apple's curl.")
+ end
+
+ specify "#check_for_beta_xquartz" do
+ allow(MacOS::XQuartz).to receive(:version).and_return("2.7.10_beta2")
+
+ expect(subject.check_for_beta_xquartz)
+ .to match("The following beta release of XQuartz is installed: 2.7.10_beta2")
+ end
+
+ specify "#check_xcode_8_without_clt_on_el_capitan" do
+ allow(MacOS).to receive(:version).and_return(OS::Mac::Version.new("10.11"))
+ allow(MacOS::Xcode).to receive(:installed?).and_return(true)
+ allow(MacOS::Xcode).to receive(:version).and_return("8.0")
+ allow(MacOS::Xcode).to receive(:without_clt?).and_return(true)
+
+ expect(subject.check_xcode_8_without_clt_on_el_capitan)
+ .to match("You have Xcode 8 installed without the CLT")
+ end
+end
diff --git a/Library/Homebrew/test/os/mac/diagnostic_test.rb b/Library/Homebrew/test/os/mac/diagnostic_test.rb
deleted file mode 100644
index 704235b01..000000000
--- a/Library/Homebrew/test/os/mac/diagnostic_test.rb
+++ /dev/null
@@ -1,45 +0,0 @@
-require "testing_env"
-require "fileutils"
-require "pathname"
-require "diagnostic"
-
-class OSMacDiagnosticChecksTest < Homebrew::TestCase
- def setup
- super
- @checks = Homebrew::Diagnostic::Checks.new
- end
-
- def test_check_for_other_package_managers
- MacOS.stubs(:macports_or_fink).returns ["fink"]
- assert_match "You have MacPorts or Fink installed:",
- @checks.check_for_other_package_managers
- end
-
- def test_check_for_unsupported_macos
- ENV.delete("HOMEBREW_DEVELOPER")
- OS::Mac.stubs(:prerelease?).returns true
- assert_match "We do not provide support for this pre-release version.",
- @checks.check_for_unsupported_macos
- end
-
- def test_check_for_unsupported_curl_vars
- MacOS.stubs(:version).returns OS::Mac::Version.new("10.10")
- ENV["SSL_CERT_DIR"] = "/some/path"
-
- assert_match "SSL_CERT_DIR support was removed from Apple's curl.",
- @checks.check_for_unsupported_curl_vars
- end
-
- def test_check_for_beta_xquartz
- MacOS::XQuartz.stubs(:version).returns("2.7.10_beta2")
- assert_match "The following beta release of XQuartz is installed: 2.7.10_beta2", @checks.check_for_beta_xquartz
- end
-
- def test_check_xcode_8_without_clt_on_el_capitan
- MacOS.stubs(:version).returns OS::Mac::Version.new("10.11")
- MacOS::Xcode.stubs(:installed?).returns true
- MacOS::Xcode.stubs(:version).returns "8.0"
- MacOS::Xcode.stubs(:without_clt?).returns true
- assert_match "You have Xcode 8 installed without the CLT", @checks.check_xcode_8_without_clt_on_el_capitan
- end
-end
diff --git a/Library/Homebrew/test/outdated_test.rb b/Library/Homebrew/test/outdated_test.rb
deleted file mode 100644
index 3e7148ded..000000000
--- a/Library/Homebrew/test/outdated_test.rb
+++ /dev/null
@@ -1,10 +0,0 @@
-require "testing_env"
-
-class IntegrationCommandTestOutdated < IntegrationCommandTestCase
- def test_outdated
- setup_test_formula "testball"
- (HOMEBREW_CELLAR/"testball/0.0.1/foo").mkpath
-
- assert_equal "testball", cmd("outdated")
- end
-end
diff --git a/Library/Homebrew/test/patching_spec.rb b/Library/Homebrew/test/patching_spec.rb
new file mode 100644
index 000000000..dd849ca92
--- /dev/null
+++ b/Library/Homebrew/test/patching_spec.rb
@@ -0,0 +1,289 @@
+require "formula"
+
+describe "patching" do
+ TESTBALL_URL = "file://#{TEST_FIXTURE_DIR}/tarballs/testball-0.1.tbz".freeze
+ TESTBALL_PATCHES_URL = "file://#{TEST_FIXTURE_DIR}/tarballs/testball-0.1-patches.tgz".freeze
+ PATCH_URL_A = "file://#{TEST_FIXTURE_DIR}/patches/noop-a.diff".freeze
+ PATCH_URL_B = "file://#{TEST_FIXTURE_DIR}/patches/noop-b.diff".freeze
+ PATCH_A_CONTENTS = File.read "#{TEST_FIXTURE_DIR}/patches/noop-a.diff"
+ PATCH_B_CONTENTS = File.read "#{TEST_FIXTURE_DIR}/patches/noop-b.diff"
+ APPLY_A = "noop-a.diff".freeze
+ APPLY_B = "noop-b.diff".freeze
+ APPLY_C = "noop-c.diff".freeze
+
+ def formula(name = "formula_name", path: Formulary.core_path(name), spec: :stable, alias_path: nil, &block)
+ Class.new(Formula) {
+ url TESTBALL_URL
+ sha256 TESTBALL_SHA256
+ class_eval(&block)
+ }.new(name, path, spec, alias_path: alias_path)
+ end
+
+ matcher :be_patched do
+ match do |formula|
+ shutup do
+ formula.brew do
+ formula.patch
+ s = File.read("libexec/NOOP")
+ expect(s).not_to include("NOOP"), "libexec/NOOP was not patched as expected"
+ expect(s).to include("ABCD"), "libexec/NOOP was not patched as expected"
+ end
+ end
+ end
+ end
+
+ matcher :be_sequentially_patched do
+ match do |formula|
+ shutup do
+ formula.brew do
+ formula.patch
+ s = File.read("libexec/NOOP")
+ expect(s).not_to include("NOOP"), "libexec/NOOP was not patched as expected"
+ expect(s).not_to include("ABCD"), "libexec/NOOP was not patched as expected"
+ expect(s).to include("1234"), "libexec/NOOP was not patched as expected"
+ end
+ end
+ end
+ end
+
+ matcher :miss_apply do
+ match do |formula|
+ expect {
+ shutup do
+ formula.brew do
+ formula.patch
+ end
+ end
+ }.to raise_error(MissingApplyError)
+ end
+ end
+
+ specify "single_patch" do
+ expect(
+ formula do
+ def patches
+ PATCH_URL_A
+ end
+ end,
+ ).to be_patched
+ end
+
+ specify "single_patch_dsl" do
+ expect(
+ formula do
+ patch do
+ url PATCH_URL_A
+ sha256 PATCH_A_SHA256
+ end
+ end,
+ ).to be_patched
+ end
+
+ specify "single_patch_dsl_with_apply" do
+ expect(
+ formula do
+ patch do
+ url TESTBALL_PATCHES_URL
+ sha256 TESTBALL_PATCHES_SHA256
+ apply APPLY_A
+ end
+ end,
+ ).to be_patched
+ end
+
+ specify "single_patch_dsl_with_sequential_apply" do
+ expect(
+ formula do
+ patch do
+ url TESTBALL_PATCHES_URL
+ sha256 TESTBALL_PATCHES_SHA256
+ apply APPLY_A, APPLY_C
+ end
+ end,
+ ).to be_sequentially_patched
+ end
+
+ specify "single_patch_dsl_with_strip" do
+ expect(
+ formula do
+ patch :p1 do
+ url PATCH_URL_A
+ sha256 PATCH_A_SHA256
+ end
+ end,
+ ).to be_patched
+ end
+
+ specify "single_patch_dsl_with_strip_with_apply" do
+ expect(
+ formula do
+ patch :p1 do
+ url TESTBALL_PATCHES_URL
+ sha256 TESTBALL_PATCHES_SHA256
+ apply APPLY_A
+ end
+ end,
+ ).to be_patched
+ end
+
+ specify "single_patch_dsl_with_incorrect_strip" do
+ expect {
+ shutup do
+ f = formula do
+ patch :p0 do
+ url PATCH_URL_A
+ sha256 PATCH_A_SHA256
+ end
+ end
+
+ f.brew { |formula, _staging| formula.patch }
+ end
+ }.to raise_error(ErrorDuringExecution)
+ end
+
+ specify "single_patch_dsl_with_incorrect_strip_with_apply" do
+ expect {
+ shutup do
+ f = formula do
+ patch :p0 do
+ url TESTBALL_PATCHES_URL
+ sha256 TESTBALL_PATCHES_SHA256
+ apply APPLY_A
+ end
+ end
+
+ f.brew { |formula, _staging| formula.patch }
+ end
+ }.to raise_error(ErrorDuringExecution)
+ end
+
+ specify "patch_p0_dsl" do
+ expect(
+ formula do
+ patch :p0 do
+ url PATCH_URL_B
+ sha256 PATCH_B_SHA256
+ end
+ end,
+ ).to be_patched
+ end
+
+ specify "patch_p0_dsl_with_apply" do
+ expect(
+ formula do
+ patch :p0 do
+ url TESTBALL_PATCHES_URL
+ sha256 TESTBALL_PATCHES_SHA256
+ apply APPLY_B
+ end
+ end,
+ ).to be_patched
+ end
+
+ specify "patch_p0" do
+ expect(
+ formula do
+ def patches
+ { p0: PATCH_URL_B }
+ end
+ end,
+ ).to be_patched
+ end
+
+ specify "patch_array" do
+ expect(
+ formula do
+ def patches
+ [PATCH_URL_A]
+ end
+ end,
+ ).to be_patched
+ end
+
+ specify "patch_hash" do
+ expect(
+ formula do
+ def patches
+ { p1: PATCH_URL_A }
+ end
+ end,
+ ).to be_patched
+ end
+
+ specify "patch_hash_array" do
+ expect(
+ formula do
+ def patches
+ { p1: [PATCH_URL_A] }
+ end
+ end,
+ ).to be_patched
+ end
+
+ specify "patch_string" do
+ expect(formula { patch PATCH_A_CONTENTS }).to be_patched
+ end
+
+ specify "patch_string_with_strip" do
+ expect(formula { patch :p0, PATCH_B_CONTENTS }).to be_patched
+ end
+
+ specify "patch_data_constant" do
+ expect(
+ formula("test", path: Pathname.new(__FILE__).expand_path) do
+ def patches
+ :DATA
+ end
+ end,
+ ).to be_patched
+ end
+
+ specify "single_patch_missing_apply_fail" do
+ expect(
+ formula do
+ def patches
+ TESTBALL_PATCHES_URL
+ end
+ end,
+ ).to miss_apply
+ end
+
+ specify "single_patch_dsl_missing_apply_fail" do
+ expect(
+ formula do
+ patch do
+ url TESTBALL_PATCHES_URL
+ sha256 TESTBALL_PATCHES_SHA256
+ end
+ end,
+ ).to miss_apply
+ end
+
+ specify "single_patch_dsl_with_apply_enoent_fail" do
+ expect {
+ shutup do
+ f = formula do
+ patch do
+ url TESTBALL_PATCHES_URL
+ sha256 TESTBALL_PATCHES_SHA256
+ apply "patches/#{APPLY_A}"
+ end
+ end
+
+ f.brew { |formula, _staging| formula.patch }
+ end
+ }.to raise_error(ErrorDuringExecution)
+ end
+end
+
+__END__
+diff --git a/libexec/NOOP b/libexec/NOOP
+index bfdda4c..e08d8f4 100755
+--- a/libexec/NOOP
++++ b/libexec/NOOP
+@@ -1,2 +1,2 @@
+ #!/bin/bash
+-echo NOOP
+\ No newline at end of file
++echo ABCD
+\ No newline at end of file
diff --git a/Library/Homebrew/test/patching_test.rb b/Library/Homebrew/test/patching_test.rb
deleted file mode 100644
index 3dacc0818..000000000
--- a/Library/Homebrew/test/patching_test.rb
+++ /dev/null
@@ -1,248 +0,0 @@
-require "testing_env"
-require "formula"
-
-class PatchingTests < Homebrew::TestCase
- TESTBALL_URL = "file://#{TEST_FIXTURE_DIR}/tarballs/testball-0.1.tbz".freeze
- TESTBALL_PATCHES_URL = "file://#{TEST_FIXTURE_DIR}/tarballs/testball-0.1-patches.tgz".freeze
- PATCH_URL_A = "file://#{TEST_FIXTURE_DIR}/patches/noop-a.diff".freeze
- PATCH_URL_B = "file://#{TEST_FIXTURE_DIR}/patches/noop-b.diff".freeze
- PATCH_A_CONTENTS = File.read "#{TEST_FIXTURE_DIR}/patches/noop-a.diff"
- PATCH_B_CONTENTS = File.read "#{TEST_FIXTURE_DIR}/patches/noop-b.diff"
- APPLY_A = "noop-a.diff".freeze
- APPLY_B = "noop-b.diff".freeze
- APPLY_C = "noop-c.diff".freeze
-
- def formula(*args, &block)
- super do
- url TESTBALL_URL
- sha256 TESTBALL_SHA256
- class_eval(&block)
- end
- end
-
- def assert_patched(formula)
- shutup do
- formula.brew do
- formula.patch
- s = File.read("libexec/NOOP")
- refute_includes s, "NOOP", "libexec/NOOP was not patched as expected"
- assert_includes s, "ABCD", "libexec/NOOP was not patched as expected"
- end
- end
- end
-
- def assert_sequentially_patched(formula)
- shutup do
- formula.brew do
- formula.patch
- s = File.read("libexec/NOOP")
- refute_includes s, "NOOP", "libexec/NOOP was not patched as expected"
- refute_includes s, "ABCD", "libexec/NOOP was not patched as expected"
- assert_includes s, "1234", "libexec/NOOP was not patched as expected"
- end
- end
- end
-
- def assert_missing_apply_fail(formula)
- assert_raises(MissingApplyError) do
- shutup do
- formula.brew do
- formula.patch
- end
- end
- end
- end
-
- def test_single_patch
- assert_patched formula {
- def patches
- PATCH_URL_A
- end
- }
- end
-
- def test_single_patch_dsl
- assert_patched formula {
- patch do
- url PATCH_URL_A
- sha256 PATCH_A_SHA256
- end
- }
- end
-
- def test_single_patch_dsl_with_apply
- assert_patched formula {
- patch do
- url TESTBALL_PATCHES_URL
- sha256 TESTBALL_PATCHES_SHA256
- apply APPLY_A
- end
- }
- end
-
- def test_single_patch_dsl_with_sequential_apply
- assert_sequentially_patched formula {
- patch do
- url TESTBALL_PATCHES_URL
- sha256 TESTBALL_PATCHES_SHA256
- apply APPLY_A, APPLY_C
- end
- }
- end
-
- def test_single_patch_dsl_with_strip
- assert_patched formula {
- patch :p1 do
- url PATCH_URL_A
- sha256 PATCH_A_SHA256
- end
- }
- end
-
- def test_single_patch_dsl_with_strip_with_apply
- assert_patched formula {
- patch :p1 do
- url TESTBALL_PATCHES_URL
- sha256 TESTBALL_PATCHES_SHA256
- apply APPLY_A
- end
- }
- end
-
- def test_single_patch_dsl_with_incorrect_strip
- assert_raises(ErrorDuringExecution) do
- shutup do
- formula do
- patch :p0 do
- url PATCH_URL_A
- sha256 PATCH_A_SHA256
- end
- end.brew { |f, _staging| f.patch }
- end
- end
- end
-
- def test_single_patch_dsl_with_incorrect_strip_with_apply
- assert_raises(ErrorDuringExecution) do
- shutup do
- formula do
- patch :p0 do
- url TESTBALL_PATCHES_URL
- sha256 TESTBALL_PATCHES_SHA256
- apply APPLY_A
- end
- end.brew { |f, _staging| f.patch }
- end
- end
- end
-
- def test_patch_p0_dsl
- assert_patched formula {
- patch :p0 do
- url PATCH_URL_B
- sha256 PATCH_B_SHA256
- end
- }
- end
-
- def test_patch_p0_dsl_with_apply
- assert_patched formula {
- patch :p0 do
- url TESTBALL_PATCHES_URL
- sha256 TESTBALL_PATCHES_SHA256
- apply APPLY_B
- end
- }
- end
-
- def test_patch_p0
- assert_patched formula {
- def patches
- { p0: PATCH_URL_B }
- end
- }
- end
-
- def test_patch_array
- assert_patched formula {
- def patches
- [PATCH_URL_A]
- end
- }
- end
-
- def test_patch_hash
- assert_patched formula {
- def patches
- { p1: PATCH_URL_A }
- end
- }
- end
-
- def test_patch_hash_array
- assert_patched formula {
- def patches
- { p1: [PATCH_URL_A] }
- end
- }
- end
-
- def test_patch_string
- assert_patched formula { patch PATCH_A_CONTENTS }
- end
-
- def test_patch_string_with_strip
- assert_patched formula { patch :p0, PATCH_B_CONTENTS }
- end
-
- def test_patch_data_constant
- assert_patched formula("test", Pathname.new(__FILE__).expand_path) {
- def patches
- :DATA
- end
- }
- end
-
- def test_single_patch_missing_apply_fail
- assert_missing_apply_fail formula {
- def patches
- TESTBALL_PATCHES_URL
- end
- }
- end
-
- def test_single_patch_dsl_missing_apply_fail
- assert_missing_apply_fail formula {
- patch do
- url TESTBALL_PATCHES_URL
- sha256 TESTBALL_PATCHES_SHA256
- end
- }
- end
-
- def test_single_patch_dsl_with_apply_enoent_fail
- assert_raises(ErrorDuringExecution) do
- shutup do
- formula do
- patch do
- url TESTBALL_PATCHES_URL
- sha256 TESTBALL_PATCHES_SHA256
- apply "patches/#{APPLY_A}"
- end
- end.brew { |f, _staging| f.patch }
- end
- end
- end
-end
-
-__END__
-diff --git a/libexec/NOOP b/libexec/NOOP
-index bfdda4c..e08d8f4 100755
---- a/libexec/NOOP
-+++ b/libexec/NOOP
-@@ -1,2 +1,2 @@
- #!/bin/bash
--echo NOOP
-\ No newline at end of file
-+echo ABCD
-\ No newline at end of file
diff --git a/Library/Homebrew/test/pathname_spec.rb b/Library/Homebrew/test/pathname_spec.rb
new file mode 100644
index 000000000..21e14479f
--- /dev/null
+++ b/Library/Homebrew/test/pathname_spec.rb
@@ -0,0 +1,307 @@
+require "tmpdir"
+require "extend/pathname"
+require "install_renamed"
+
+describe Pathname do
+ include FileUtils
+
+ let(:src) { Pathname.new(Dir.mktmpdir) }
+ let(:dst) { Pathname.new(Dir.mktmpdir) }
+ let(:file) { src/"foo" }
+ let(:dir) { src/"bar" }
+
+ after(:each) { rm_rf [src, dst] }
+
+ describe DiskUsageExtension do
+ before(:each) do
+ mkdir_p dir/"a-directory"
+ touch [dir/".DS_Store", dir/"a-file"]
+ File.truncate(dir/"a-file", 1_048_576)
+ ln_s dir/"a-file", dir/"a-symlink"
+ ln dir/"a-file", dir/"a-hardlink"
+ end
+
+ describe "#file_count" do
+ it "returns the number of files in a directory" do
+ expect(dir.file_count).to eq(3)
+ end
+ end
+
+ describe "#abv" do
+ context "when called on a directory" do
+ it "returns a string with the file count and disk usage" do
+ expect(dir.abv).to eq("3 files, 1MB")
+ end
+ end
+
+ context "when called on a file" do
+ it "returns the disk usage" do
+ expect((dir/"a-file").abv).to eq("1MB")
+ end
+ end
+ end
+ end
+
+ describe "#rmdir_if_possible" do
+ before(:each) { mkdir_p dir }
+
+ it "returns true and removes a directory if it doesn't contain files" do
+ expect(dir.rmdir_if_possible).to be true
+ expect(dir).not_to exist
+ end
+
+ it "returns false and doesn't delete a directory if it contains files" do
+ touch dir/"foo"
+ expect(dir.rmdir_if_possible).to be false
+ expect(dir).to be_a_directory
+ end
+
+ it "ignores .DS_Store files" do
+ touch dir/".DS_Store"
+ expect(dir.rmdir_if_possible).to be true
+ expect(dir).not_to exist
+ end
+ end
+
+ describe "#write" do
+ it "creates a file and writes to it" do
+ expect(file).not_to exist
+ file.write("CONTENT")
+ expect(File.read(file)).to eq("CONTENT")
+ end
+
+ it "raises an error if the file already exists" do
+ touch file
+ expect { file.write("CONTENT") }.to raise_error(RuntimeError)
+ end
+ end
+
+ describe "#append_lines" do
+ it "appends lines to a file" do
+ touch file
+
+ file.append_lines("CONTENT")
+ expect(File.read(file)).to eq <<-EOS.undent
+ CONTENT
+ EOS
+
+ file.append_lines("CONTENTS")
+ expect(File.read(file)).to eq <<-EOS.undent
+ CONTENT
+ CONTENTS
+ EOS
+ end
+
+ it "raises an error if the file does not exist" do
+ expect(file).not_to exist
+ expect { file.append_lines("CONTENT") }.to raise_error(RuntimeError)
+ end
+ end
+
+ describe "#atomic_write" do
+ it "atomically replaces a file" do
+ touch file
+ file.atomic_write("CONTENT")
+ expect(File.read(file)).to eq("CONTENT")
+ end
+
+ it "preserves permissions" do
+ File.open(file, "w", 0100777).close
+ file.atomic_write("CONTENT")
+ expect(file.stat.mode).to eq(0100777 & ~File.umask)
+ end
+
+ it "preserves default permissions" do
+ file.atomic_write("CONTENT")
+ sentinel = file.parent.join("sentinel")
+ touch sentinel
+ expect(file.stat.mode).to eq(sentinel.stat.mode)
+ end
+ end
+
+ describe "#ensure_writable" do
+ it "makes a file writable and restores permissions afterwards" do
+ touch file
+ chmod 0555, file
+ expect(file).not_to be_writable
+ file.ensure_writable do
+ expect(file).to be_writable
+ end
+ expect(file).not_to be_writable
+ end
+ end
+
+ describe "#extname" do
+ it "supports common multi-level archives" do
+ expect(Pathname.new("foo-0.1.tar.gz").extname).to eq(".tar.gz")
+ expect(Pathname.new("foo-0.1.cpio.gz").extname).to eq(".cpio.gz")
+ end
+ end
+
+ describe "#stem" do
+ it "returns the basename without double extensions" do
+ expect(Pathname("foo-0.1.tar.gz").stem).to eq("foo-0.1")
+ expect(Pathname("foo-0.1.cpio.gz").stem).to eq("foo-0.1")
+ end
+ end
+
+ describe "#install" do
+ before(:each) do
+ (src/"a.txt").write "This is sample file a."
+ (src/"b.txt").write "This is sample file b."
+ end
+
+ it "raises an error if the file doesn't exist" do
+ expect { dst.install "non_existent_file" }.to raise_error(Errno::ENOENT)
+ end
+
+ it "installs a file to a directory with its basename" do
+ touch file
+ dst.install(file)
+ expect(dst/file.basename).to exist
+ expect(file).not_to exist
+ end
+
+ it "creates intermediate directories" do
+ touch file
+ expect(dir).not_to be_a_directory
+ dir.install(file)
+ expect(dir).to be_a_directory
+ end
+
+ it "can install a file" do
+ dst.install src/"a.txt"
+ expect(dst/"a.txt").to exist, "a.txt was not installed"
+ expect(dst/"b.txt").not_to exist, "b.txt was installed."
+ end
+
+ it "can install an array of files" do
+ dst.install [src/"a.txt", src/"b.txt"]
+
+ expect(dst/"a.txt").to exist, "a.txt was not installed"
+ expect(dst/"b.txt").to exist, "b.txt was not installed"
+ end
+
+ it "can install a directory" do
+ bin = src/"bin"
+ bin.mkpath
+ mv Dir[src/"*.txt"], bin
+ dst.install bin
+
+ expect(dst/"bin/a.txt").to exist, "a.txt was not installed"
+ expect(dst/"bin/b.txt").to exist, "b.txt was not installed"
+ end
+
+ it "supports renaming files" do
+ dst.install src/"a.txt" => "c.txt"
+
+ expect(dst/"c.txt").to exist, "c.txt was not installed"
+ expect(dst/"a.txt").not_to exist, "a.txt was installed but not renamed"
+ expect(dst/"b.txt").not_to exist, "b.txt was installed"
+ end
+
+ it "supports renaming multiple files" do
+ dst.install(src/"a.txt" => "c.txt", src/"b.txt" => "d.txt")
+
+ expect(dst/"c.txt").to exist, "c.txt was not installed"
+ expect(dst/"d.txt").to exist, "d.txt was not installed"
+ expect(dst/"a.txt").not_to exist, "a.txt was installed but not renamed"
+ expect(dst/"b.txt").not_to exist, "b.txt was installed but not renamed"
+ end
+
+ it "supports renaming directories" do
+ bin = src/"bin"
+ bin.mkpath
+ mv Dir[src/"*.txt"], bin
+ dst.install bin => "libexec"
+
+ expect(dst/"bin").not_to exist, "bin was installed but not renamed"
+ expect(dst/"libexec/a.txt").to exist, "a.txt was not installed"
+ expect(dst/"libexec/b.txt").to exist, "b.txt was not installed"
+ end
+
+ it "can install directories as relative symlinks" do
+ bin = src/"bin"
+ bin.mkpath
+ mv Dir[src/"*.txt"], bin
+ dst.install_symlink bin
+
+ expect(dst/"bin").to be_a_symlink
+ expect(dst/"bin").to be_a_directory
+ expect(dst/"bin/a.txt").to exist
+ expect(dst/"bin/b.txt").to exist
+ expect((dst/"bin").readlink).to be_relative
+ end
+
+ it "can install relative paths as symlinks" do
+ dst.install_symlink "foo" => "bar"
+ expect((dst/"bar").readlink).to eq(Pathname.new("foo"))
+ end
+ end
+
+ describe InstallRenamed do
+ before(:each) do
+ dst.extend(InstallRenamed)
+ end
+
+ it "renames the installed file if it already exists" do
+ file.write "a"
+ dst.install file
+
+ file.write "b"
+ dst.install file
+
+ expect(File.read(dst/file.basename)).to eq("a")
+ expect(File.read(dst/"#{file.basename}.default")).to eq("b")
+ end
+
+ it "renames the installed directory" do
+ file.write "a"
+ dst.install src
+ expect(File.read(dst/src.basename/file.basename)).to eq("a")
+ end
+
+ it "recursively renames directories" do
+ (dst/dir.basename).mkpath
+ (dst/dir.basename/"another_file").write "a"
+ dir.mkpath
+ (dir/"another_file").write "b"
+ dst.install dir
+ expect(File.read(dst/dir.basename/"another_file.default")).to eq("b")
+ end
+ end
+
+ describe "#cp_path_sub" do
+ it "copies a file and replaces the given pattern" do
+ file.write "a"
+ file.cp_path_sub src, dst
+ expect(File.read(dst/file.basename)).to eq("a")
+ end
+
+ it "copies a directory and replaces the given pattern" do
+ dir.mkpath
+ dir.cp_path_sub src, dst
+ expect(dst/dir.basename).to be_a_directory
+ end
+ end
+
+ describe "#ds_store?" do
+ it "returns whether a file is .DS_Store or not" do
+ expect(file).not_to be_ds_store
+ expect(file/".DS_Store").to be_ds_store
+ end
+ end
+end
+
+describe FileUtils do
+ let(:dst) { Pathname.new(Dir.mktmpdir) }
+
+ describe "#mkdir" do
+ it "creates indermediate directories" do
+ described_class.mkdir dst/"foo/bar/baz" do
+ expect(dst/"foo/bar/baz").to exist, "foo/bar/baz was not created"
+ expect(dst/"foo/bar/baz").to be_a_directory, "foo/bar/baz was not a directory structure"
+ end
+ end
+ end
+end
diff --git a/Library/Homebrew/test/pathname_test.rb b/Library/Homebrew/test/pathname_test.rb
deleted file mode 100644
index 0107c8675..000000000
--- a/Library/Homebrew/test/pathname_test.rb
+++ /dev/null
@@ -1,268 +0,0 @@
-require "testing_env"
-require "tmpdir"
-require "extend/pathname"
-require "install_renamed"
-
-module PathnameTestExtension
- include FileUtils
-
- def setup
- super
- @src = Pathname.new(mktmpdir)
- @dst = Pathname.new(mktmpdir)
- @file = @src/"foo"
- @dir = @src/"bar"
- end
-end
-
-class PathnameTests < Homebrew::TestCase
- include PathnameTestExtension
-
- def test_disk_usage_extension
- mkdir_p @dir/"a-directory"
- touch @dir/".DS_Store"
- touch @dir/"a-file"
- File.truncate(@dir/"a-file", 1_048_576)
- ln_s @dir/"a-file", @dir/"a-symlink"
- ln @dir/"a-file", @dir/"a-hardlink"
- assert_equal 3, @dir.file_count
- assert_equal "3 files, 1M", @dir.abv
- assert_equal "1M", (@dir/"a-file").abv
- end
-
- def test_rmdir_if_possible
- mkdir_p @dir
- touch @dir/"foo"
-
- assert !@dir.rmdir_if_possible
- assert_predicate @dir, :directory?
-
- rm_f @dir/"foo"
- assert @dir.rmdir_if_possible
- refute_predicate @dir, :exist?
- end
-
- def test_rmdir_if_possible_ignore_ds_store
- mkdir_p @dir
- touch @dir/".DS_Store"
- assert @dir.rmdir_if_possible
- refute_predicate @dir, :exist?
- end
-
- def test_write
- @file.write("CONTENT")
- assert_equal "CONTENT", File.read(@file)
- end
-
- def test_write_does_not_overwrite
- touch @file
- assert_raises(RuntimeError) { @file.write("CONTENT") }
- end
-
- def test_append_lines
- touch @file
- @file.append_lines("CONTENT")
- assert_equal "CONTENT\n", File.read(@file)
- @file.append_lines("CONTENTS")
- assert_equal "CONTENT\nCONTENTS\n", File.read(@file)
- end
-
- def test_append_lines_does_not_create
- assert_raises(RuntimeError) { @file.append_lines("CONTENT") }
- end
-
- def test_atomic_write
- touch @file
- @file.atomic_write("CONTENT")
- assert_equal "CONTENT", File.read(@file)
- end
-
- def test_atomic_write_preserves_permissions
- File.open(@file, "w", 0100777) {}
- @file.atomic_write("CONTENT")
- assert_equal 0100777 & ~File.umask, @file.stat.mode
- end
-
- def test_atomic_write_preserves_default_permissions
- @file.atomic_write("CONTENT")
- sentinel = @file.parent.join("sentinel")
- touch sentinel
- assert_equal sentinel.stat.mode, @file.stat.mode
- end
-
- def test_ensure_writable
- touch @file
- chmod 0555, @file
- @file.ensure_writable { assert_predicate @file, :writable? }
- refute_predicate @file, :writable?
- end
-
- def test_extname
- assert_equal ".tar.gz", Pathname("foo-0.1.tar.gz").extname
- assert_equal ".cpio.gz", Pathname("foo-0.1.cpio.gz").extname
- end
-
- def test_stem
- assert_equal "foo-0.1", Pathname("foo-0.1.tar.gz").stem
- assert_equal "foo-0.1", Pathname("foo-0.1.cpio.gz").stem
- end
-
- def test_install_missing_file
- assert_raises(Errno::ENOENT) { @dst.install "non_existent_file" }
- end
-
- def test_install_removes_original
- touch @file
- @dst.install(@file)
-
- assert_predicate @dst/@file.basename, :exist?
- refute_predicate @file, :exist?
- end
-
- def test_install_creates_intermediate_directories
- touch @file
- refute_predicate @dir, :directory?
- @dir.install(@file)
- assert_predicate @dir, :directory?
- end
-
- def test_install_renamed
- @dst.extend(InstallRenamed)
-
- @file.write "a"
- @dst.install @file
- @file.write "b"
- @dst.install @file
-
- assert_equal "a", File.read(@dst/@file.basename)
- assert_equal "b", File.read(@dst/"#{@file.basename}.default")
- end
-
- def test_install_renamed_directory
- @dst.extend(InstallRenamed)
- @file.write "a"
- @dst.install @src
- assert_equal "a", File.read(@dst/@src.basename/@file.basename)
- end
-
- def test_install_renamed_directory_recursive
- @dst.extend(InstallRenamed)
- (@dst/@dir.basename).mkpath
- (@dst/@dir.basename/"another_file").write "a"
- @dir.mkpath
- (@dir/"another_file").write "b"
- @dst.install @dir
- assert_equal "b", File.read(@dst/@dir.basename/"another_file.default")
- end
-
- def test_cp_path_sub_file
- @file.write "a"
- @file.cp_path_sub @src, @dst
- assert_equal "a", File.read(@dst/"foo")
- end
-
- def test_cp_path_sub_directory
- @dir.mkpath
- @dir.cp_path_sub @src, @dst
- assert_predicate @dst/@dir.basename, :directory?
- end
-
- def test_ds_store
- refute_predicate @file, :ds_store?
- assert_predicate @src/".DS_Store", :ds_store?
- end
-end
-
-class PathnameInstallTests < Homebrew::TestCase
- include PathnameTestExtension
-
- def setup
- super
- (@src/"a.txt").write "This is sample file a."
- (@src/"b.txt").write "This is sample file b."
- end
-
- def test_install
- @dst.install @src/"a.txt"
-
- assert_predicate @dst/"a.txt", :exist?, "a.txt was not installed"
- refute_predicate @dst/"b.txt", :exist?, "b.txt was installed."
- end
-
- def test_install_list
- @dst.install [@src/"a.txt", @src/"b.txt"]
-
- assert_predicate @dst/"a.txt", :exist?, "a.txt was not installed"
- assert_predicate @dst/"b.txt", :exist?, "b.txt was not installed"
- end
-
- def test_install_glob
- @dst.install Dir[@src/"*.txt"]
-
- assert_predicate @dst/"a.txt", :exist?, "a.txt was not installed"
- assert_predicate @dst/"b.txt", :exist?, "b.txt was not installed"
- end
-
- def test_install_directory
- bin = @src/"bin"
- bin.mkpath
- mv Dir[@src/"*.txt"], bin
- @dst.install bin
-
- assert_predicate @dst/"bin/a.txt", :exist?, "a.txt was not installed"
- assert_predicate @dst/"bin/b.txt", :exist?, "b.txt was not installed"
- end
-
- def test_install_rename
- @dst.install @src/"a.txt" => "c.txt"
-
- assert_predicate @dst/"c.txt", :exist?, "c.txt was not installed"
- refute_predicate @dst/"a.txt", :exist?, "a.txt was installed but not renamed"
- refute_predicate @dst/"b.txt", :exist?, "b.txt was installed"
- end
-
- def test_install_rename_more
- @dst.install(@src/"a.txt" => "c.txt", @src/"b.txt" => "d.txt")
-
- assert_predicate @dst/"c.txt", :exist?, "c.txt was not installed"
- assert_predicate @dst/"d.txt", :exist?, "d.txt was not installed"
- refute_predicate @dst/"a.txt", :exist?, "a.txt was installed but not renamed"
- refute_predicate @dst/"b.txt", :exist?, "b.txt was installed but not renamed"
- end
-
- def test_install_rename_directory
- bin = @src/"bin"
- bin.mkpath
- mv Dir[@src/"*.txt"], bin
- @dst.install bin => "libexec"
-
- refute_predicate @dst/"bin", :exist?, "bin was installed but not renamed"
- assert_predicate @dst/"libexec/a.txt", :exist?, "a.txt was not installed"
- assert_predicate @dst/"libexec/b.txt", :exist?, "b.txt was not installed"
- end
-
- def test_install_symlink
- bin = @src/"bin"
- bin.mkpath
- mv Dir[@src/"*.txt"], bin
- @dst.install_symlink bin
-
- assert_predicate @dst/"bin", :symlink?
- assert_predicate @dst/"bin", :directory?
- assert_predicate @dst/"bin/a.txt", :exist?
- assert_predicate @dst/"bin/b.txt", :exist?
- assert_predicate((@dst/"bin").readlink, :relative?)
- end
-
- def test_install_relative_symlink
- @dst.install_symlink "foo" => "bar"
- assert_equal Pathname.new("foo"), (@dst/"bar").readlink
- end
-
- def test_mkdir_creates_intermediate_directories
- mkdir @dst/"foo/bar/baz" do
- assert_predicate @dst/"foo/bar/baz", :exist?, "foo/bar/baz was not created"
- assert_predicate @dst/"foo/bar/baz", :directory?, "foo/bar/baz was not a directory structure"
- end
- end
-end
diff --git a/Library/Homebrew/test/pin_unpin_test.rb b/Library/Homebrew/test/pin_unpin_test.rb
deleted file mode 100644
index 65fb9e4da..000000000
--- a/Library/Homebrew/test/pin_unpin_test.rb
+++ /dev/null
@@ -1,18 +0,0 @@
-require "testing_env"
-
-class IntegrationCommandTestPinUnpin < IntegrationCommandTestCase
- def test_pin_unpin
- setup_test_formula "testball"
- (HOMEBREW_CELLAR/"testball/0.0.1/foo").mkpath
-
- cmd("pin", "testball")
- cmd("upgrade")
- refute((HOMEBREW_CELLAR/"testball/0.1").directory?,
- "The latest version directory should NOT be created")
-
- cmd("unpin", "testball")
- cmd("upgrade")
- assert((HOMEBREW_CELLAR/"testball/0.1").directory?,
- "The latest version directory should be created")
- end
-end
diff --git a/Library/Homebrew/test/prefix_formula_test.rb b/Library/Homebrew/test/prefix_formula_test.rb
deleted file mode 100644
index eb5970d3e..000000000
--- a/Library/Homebrew/test/prefix_formula_test.rb
+++ /dev/null
@@ -1,8 +0,0 @@
-require "testing_env"
-
-class IntegrationCommandTestPrefixFormula < IntegrationCommandTestCase
- def test_prefix_formula
- assert_match "#{HOMEBREW_CELLAR}/testball",
- cmd("--prefix", testball)
- end
-end
diff --git a/Library/Homebrew/test/prefix_test.rb b/Library/Homebrew/test/prefix_test.rb
deleted file mode 100644
index a3ae75542..000000000
--- a/Library/Homebrew/test/prefix_test.rb
+++ /dev/null
@@ -1,8 +0,0 @@
-require "testing_env"
-
-class IntegrationCommandTestPrefix < IntegrationCommandTestCase
- def test_prefix
- assert_equal HOMEBREW_PREFIX.to_s,
- cmd("--prefix")
- end
-end
diff --git a/Library/Homebrew/test/prune_test.rb b/Library/Homebrew/test/prune_test.rb
deleted file mode 100644
index 8fa5df7b7..000000000
--- a/Library/Homebrew/test/prune_test.rb
+++ /dev/null
@@ -1,21 +0,0 @@
-require "testing_env"
-
-class IntegrationCommandTestPrune < IntegrationCommandTestCase
- def test_prune
- 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"
-
- assert_match %r{Would remove \(empty directory\): .*/pruneable/directory/here},
- cmd("prune", "--dry-run")
- assert_match "Pruned 1 symbolic links and 3 directories",
- cmd("prune")
- refute((share/"pruneable").directory?)
- assert((share/"notpruneable").directory?)
- refute((share/"pruneable_symlink").symlink?)
-
- assert_match "Nothing pruned", cmd("prune", "--verbose")
- end
-end
diff --git a/Library/Homebrew/test/pull_offline_test.rb b/Library/Homebrew/test/pull_offline_test.rb
deleted file mode 100644
index c9d46cd74..000000000
--- a/Library/Homebrew/test/pull_offline_test.rb
+++ /dev/null
@@ -1,10 +0,0 @@
-require "testing_env"
-
-class IntegrationCommandTestPullOffline < IntegrationCommandTestCase
- def test_pull_offline
- assert_match "You meant `git pull --rebase`.", cmd_fail("pull", "--rebase")
- assert_match "This command requires at least one argument", cmd_fail("pull")
- assert_match "Not a GitHub pull request or commit",
- cmd_fail("pull", "0")
- end
-end
diff --git a/Library/Homebrew/test/pull_test.rb b/Library/Homebrew/test/pull_test.rb
deleted file mode 100644
index 445d73cb1..000000000
--- a/Library/Homebrew/test/pull_test.rb
+++ /dev/null
@@ -1,27 +0,0 @@
-require "testing_env"
-
-class IntegrationCommandTestPull < IntegrationCommandTestCase
- def test_pull
- skip "Requires network connection" if ENV["HOMEBREW_NO_GITHUB_API"]
-
- core_tap = CoreTap.new
- core_tap.path.cd do
- shutup do
- system "git", "init"
- system "git", "checkout", "-b", "new-branch"
- end
- end
-
- assert_match "Testing URLs require `--bottle`!",
- cmd_fail("pull", "https://bot.brew.sh/job/Homebrew\%20Testing/1028/")
- assert_match "Current branch is new-branch",
- cmd_fail("pull", "1")
- assert_match "No changed formulae found to bump",
- cmd_fail("pull", "--bump", "8")
- assert_match "Can only bump one changed formula",
- cmd_fail("pull", "--bump",
- "https://api.github.com/repos/Homebrew/homebrew-core/pulls/122")
- assert_match "Patch failed to apply",
- cmd_fail("pull", "https://github.com/Homebrew/homebrew-core/pull/1")
- end
-end
diff --git a/Library/Homebrew/test/readall_test.rb b/Library/Homebrew/test/readall_test.rb
deleted file mode 100644
index 3eec79dd8..000000000
--- a/Library/Homebrew/test/readall_test.rb
+++ /dev/null
@@ -1,12 +0,0 @@
-require "testing_env"
-
-class IntegrationCommandTestReadall < IntegrationCommandTestCase
- def test_readall
- formula_file = setup_test_formula "testball"
- alias_file = CoreTap.new.alias_dir/"foobar"
- alias_file.parent.mkpath
- FileUtils.ln_s formula_file, alias_file
- cmd("readall", "--aliases", "--syntax")
- cmd("readall", "homebrew/core")
- end
-end
diff --git a/Library/Homebrew/test/reinstall_pinned_test.rb b/Library/Homebrew/test/reinstall_pinned_test.rb
deleted file mode 100644
index 80f5518ea..000000000
--- a/Library/Homebrew/test/reinstall_pinned_test.rb
+++ /dev/null
@@ -1,15 +0,0 @@
-require "testing_env"
-
-class IntegrationCommandTestReinstallPinned < IntegrationCommandTestCase
- def test_reinstall_pinned
- setup_test_formula "testball"
-
- HOMEBREW_CELLAR.join("testball/0.1").mkpath
- HOMEBREW_PINNED_KEGS.mkpath
- FileUtils.ln_s HOMEBREW_CELLAR.join("testball/0.1"), HOMEBREW_PINNED_KEGS/"testball"
-
- assert_match "testball is pinned. You must unpin it to reinstall.", cmd("reinstall", "testball")
-
- HOMEBREW_PINNED_KEGS.rmtree
- end
-end
diff --git a/Library/Homebrew/test/reinstall_test.rb b/Library/Homebrew/test/reinstall_test.rb
deleted file mode 100644
index 2906983c3..000000000
--- a/Library/Homebrew/test/reinstall_test.rb
+++ /dev/null
@@ -1,24 +0,0 @@
-require "testing_env"
-
-class IntegrationCommandTestReinstall < IntegrationCommandTestCase
- def test_reinstall
- setup_test_formula "testball"
-
- cmd("install", "testball", "--with-foo")
- foo_dir = HOMEBREW_CELLAR/"testball/0.1/foo"
- assert foo_dir.exist?
- foo_dir.rmtree
- assert_match "Reinstalling testball --with-foo",
- cmd("reinstall", "testball")
- assert foo_dir.exist?
- end
-
- def test_reinstall_with_invalid_option
- setup_test_formula "testball"
-
- cmd("install", "testball", "--with-foo")
-
- assert_match "testball: this formula has no --with-fo option so it will be ignored!",
- cmd("reinstall", "testball", "--with-fo")
- end
-end
diff --git a/Library/Homebrew/test/repository_test.rb b/Library/Homebrew/test/repository_test.rb
deleted file mode 100644
index 77967a58d..000000000
--- a/Library/Homebrew/test/repository_test.rb
+++ /dev/null
@@ -1,10 +0,0 @@
-require "testing_env"
-
-class IntegrationCommandTestRepository < IntegrationCommandTestCase
- def test_repository
- assert_match HOMEBREW_REPOSITORY.to_s,
- cmd("--repository")
- assert_match "#{HOMEBREW_LIBRARY}/Taps/foo/homebrew-bar",
- cmd("--repository", "foo/bar")
- end
-end
diff --git a/Library/Homebrew/test/resource_spec.rb b/Library/Homebrew/test/resource_spec.rb
new file mode 100644
index 000000000..6a0419538
--- /dev/null
+++ b/Library/Homebrew/test/resource_spec.rb
@@ -0,0 +1,147 @@
+require "resource"
+
+describe Resource do
+ subject { described_class.new("test") }
+
+ describe "#url" do
+ it "sets the URL" do
+ subject.url("foo")
+ expect(subject.url).to eq("foo")
+ end
+
+ it "can set the URL with specifications" do
+ subject.url("foo", branch: "master")
+ expect(subject.url).to eq("foo")
+ expect(subject.specs).to eq(branch: "master")
+ end
+
+ it "can set the URL with a custom download strategy class" do
+ strategy = Class.new(AbstractDownloadStrategy)
+ subject.url("foo", using: strategy)
+ expect(subject.url).to eq("foo")
+ expect(subject.download_strategy).to eq(strategy)
+ end
+
+ it "can set the URL with specifications and a custom download strategy class" do
+ strategy = Class.new(AbstractDownloadStrategy)
+ subject.url("foo", using: strategy, branch: "master")
+ expect(subject.url).to eq("foo")
+ expect(subject.specs).to eq(branch: "master")
+ expect(subject.download_strategy).to eq(strategy)
+ end
+
+ it "can set the URL with a custom download strategy symbol" do
+ subject.url("foo", using: :git)
+ expect(subject.url).to eq("foo")
+ expect(subject.download_strategy).to eq(GitDownloadStrategy)
+ end
+
+ it "raises an error if the download strategy class is unkown" do
+ expect { subject.url("foo", using: Class.new) }.to raise_error(TypeError)
+ end
+
+ it "does not mutate the specifications hash" do
+ specs = { using: :git, branch: "master" }
+ subject.url("foo", specs)
+ expect(subject.specs).to eq(branch: "master")
+ expect(subject.using).to eq(:git)
+ expect(specs).to eq(using: :git, branch: "master")
+ end
+ end
+
+ describe "#version" do
+ it "sets the version" do
+ subject.version("1.0")
+ expect(subject.version).to eq(Version.parse("1.0"))
+ expect(subject.version).not_to be_detected_from_url
+ end
+
+ it "can detect the version from a URL" do
+ subject.url("http://example.com/foo-1.0.tar.gz")
+ expect(subject.version).to eq(Version.parse("1.0"))
+ expect(subject.version).to be_detected_from_url
+ end
+
+ it "can set the version with a scheme" do
+ klass = Class.new(Version)
+ subject.version klass.new("1.0")
+ expect(subject.version).to eq(Version.parse("1.0"))
+ expect(subject.version).to be_a(klass)
+ end
+
+ it "can set the version from a tag" do
+ subject.url("http://example.com/foo-1.0.tar.gz", tag: "v1.0.2")
+ expect(subject.version).to eq(Version.parse("1.0.2"))
+ expect(subject.version).to be_detected_from_url
+ end
+
+ it "rejects non-string versions" do
+ expect { subject.version(1) }.to raise_error(TypeError)
+ expect { subject.version(2.0) }.to raise_error(TypeError)
+ expect { subject.version(Object.new) }.to raise_error(TypeError)
+ end
+
+ it "returns nil if unset" do
+ expect(subject.version).to be nil
+ end
+ end
+
+ describe "#mirrors" do
+ it "is empty by defaults" do
+ expect(subject.mirrors).to be_empty
+ end
+
+ it "returns an array of mirrors added with #mirror" do
+ subject.mirror("foo")
+ subject.mirror("bar")
+ expect(subject.mirrors).to eq(%w[foo bar])
+ end
+ end
+
+ describe "#checksum" do
+ it "returns nil if unset" do
+ expect(subject.checksum).to be nil
+ end
+
+ it "returns the checksum set with #sha256" do
+ subject.sha256(TEST_SHA256)
+ expect(subject.checksum).to eq(Checksum.new(:sha256, TEST_SHA256))
+ end
+ end
+
+ describe "#download_strategy" do
+ it "returns the download strategy" do
+ strategy = Object.new
+ expect(DownloadStrategyDetector)
+ .to receive(:detect).with("foo", nil).and_return(strategy)
+ subject.url("foo")
+ expect(subject.download_strategy).to eq(strategy)
+ end
+ end
+
+ specify "#verify_download_integrity_missing" do
+ fn = Pathname.new("test")
+
+ allow(fn).to receive(:file?).and_return(true)
+ expect(fn).to receive(:verify_checksum).and_raise(ChecksumMissingError)
+ expect(fn).to receive(:sha256)
+
+ shutup do
+ subject.verify_download_integrity(fn)
+ end
+ end
+
+ specify "#verify_download_integrity_mismatch" do
+ fn = double(file?: true)
+ checksum = subject.sha256(TEST_SHA256)
+
+ expect(fn).to receive(:verify_checksum).with(checksum)
+ .and_raise(ChecksumMismatchError.new(fn, checksum, Object.new))
+
+ shutup do
+ expect {
+ subject.verify_download_integrity(fn)
+ }.to raise_error(ChecksumMismatchError)
+ end
+ end
+end
diff --git a/Library/Homebrew/test/resource_test.rb b/Library/Homebrew/test/resource_test.rb
deleted file mode 100644
index d982a7c33..000000000
--- a/Library/Homebrew/test/resource_test.rb
+++ /dev/null
@@ -1,133 +0,0 @@
-require "testing_env"
-require "resource"
-
-class ResourceTests < Homebrew::TestCase
- def setup
- super
- @resource = Resource.new("test")
- end
-
- def test_url
- @resource.url("foo")
- assert_equal "foo", @resource.url
- end
-
- def test_url_with_specs
- @resource.url("foo", branch: "master")
- assert_equal "foo", @resource.url
- assert_equal({ branch: "master" }, @resource.specs)
- end
-
- def test_url_with_custom_download_strategy_class
- strategy = Class.new(AbstractDownloadStrategy)
- @resource.url("foo", using: strategy)
- assert_equal "foo", @resource.url
- assert_equal strategy, @resource.download_strategy
- end
-
- def test_url_with_specs_and_download_strategy
- strategy = Class.new(AbstractDownloadStrategy)
- @resource.url("foo", using: strategy, branch: "master")
- assert_equal "foo", @resource.url
- assert_equal({ branch: "master" }, @resource.specs)
- assert_equal strategy, @resource.download_strategy
- end
-
- def test_url_with_custom_download_strategy_symbol
- @resource.url("foo", using: :git)
- assert_equal "foo", @resource.url
- assert_equal GitDownloadStrategy, @resource.download_strategy
- end
-
- def test_raises_for_unknown_download_strategy_class
- assert_raises(TypeError) { @resource.url("foo", using: Class.new) }
- end
-
- def test_does_not_mutate_specs_hash
- specs = { using: :git, branch: "master" }
- @resource.url("foo", specs)
- assert_equal({ branch: "master" }, @resource.specs)
- assert_equal(:git, @resource.using)
- assert_equal({ using: :git, branch: "master" }, specs)
- end
-
- def test_version
- @resource.version("1.0")
- assert_version_equal "1.0", @resource.version
- refute_predicate @resource.version, :detected_from_url?
- end
-
- def test_version_from_url
- @resource.url("http://example.com/foo-1.0.tar.gz")
- assert_version_equal "1.0", @resource.version
- assert_predicate @resource.version, :detected_from_url?
- end
-
- def test_version_with_scheme
- klass = Class.new(Version)
- @resource.version klass.new("1.0")
- assert_version_equal "1.0", @resource.version
- assert_instance_of klass, @resource.version
- end
-
- def test_version_from_tag
- @resource.url("http://example.com/foo-1.0.tar.gz", tag: "v1.0.2")
- assert_version_equal "1.0.2", @resource.version
- assert_predicate @resource.version, :detected_from_url?
- end
-
- def test_rejects_non_string_versions
- assert_raises(TypeError) { @resource.version(1) }
- assert_raises(TypeError) { @resource.version(2.0) }
- assert_raises(TypeError) { @resource.version(Object.new) }
- end
-
- def test_version_when_url_is_not_set
- assert_nil @resource.version
- end
-
- def test_mirrors
- assert_empty @resource.mirrors
- @resource.mirror("foo")
- @resource.mirror("bar")
- assert_equal %w[foo bar], @resource.mirrors
- end
-
- def test_checksum_setters
- assert_nil @resource.checksum
- @resource.sha256(TEST_SHA256)
- assert_equal Checksum.new(:sha256, TEST_SHA256), @resource.checksum
- end
-
- def test_download_strategy
- strategy = Object.new
- DownloadStrategyDetector
- .expects(:detect).with("foo", nil).returns(strategy)
- @resource.url("foo")
- assert_equal strategy, @resource.download_strategy
- end
-
- def test_verify_download_integrity_missing
- fn = Pathname.new("test")
-
- fn.stubs(file?: true)
- fn.expects(:verify_checksum).raises(ChecksumMissingError)
- fn.expects(:sha256)
-
- shutup { @resource.verify_download_integrity(fn) }
- end
-
- def test_verify_download_integrity_mismatch
- fn = stub(file?: true)
- checksum = @resource.sha256(TEST_SHA256)
-
- fn.expects(:verify_checksum).with(checksum)
- .raises(ChecksumMismatchError.new(fn, checksum, Object.new))
-
- shutup do
- assert_raises(ChecksumMismatchError) do
- @resource.verify_download_integrity(fn)
- end
- end
- end
-end
diff --git a/Library/Homebrew/test/search_test.rb b/Library/Homebrew/test/search_test.rb
deleted file mode 100644
index 70b6f01fb..000000000
--- a/Library/Homebrew/test/search_test.rb
+++ /dev/null
@@ -1,30 +0,0 @@
-require "testing_env"
-
-class IntegrationCommandTestSearch < IntegrationCommandTestCase
- def test_search
- setup_test_formula "testball"
- desc_cache = HOMEBREW_CACHE/"desc_cache.json"
- refute_predicate desc_cache, :exist?, "Cached file should not exist"
-
- assert_match "testball", cmd("search")
- assert_match "testball", cmd("search", "testball")
- assert_match "testball", cmd("search", "homebrew/homebrew-core/testball")
- assert_match "testball", cmd("search", "--desc", "Some test")
-
- flags = {
- "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",
- }
-
- flags.each do |flag, url|
- assert_equal url, cmd("search", "--#{flag}",
- "testball", "HOMEBREW_BROWSER" => "echo")
- end
-
- assert_predicate desc_cache, :exist?, "Cached file should exist"
- end
-end
diff --git a/Library/Homebrew/test/services_test.rb b/Library/Homebrew/test/services_test.rb
deleted file mode 100644
index 280aeb9f4..000000000
--- a/Library/Homebrew/test/services_test.rb
+++ /dev/null
@@ -1,11 +0,0 @@
-require "testing_env"
-
-class IntegrationCommandTestServices < IntegrationCommandTestCase
- def test_services
- needs_test_cmd_taps
- needs_macos
- setup_remote_tap("homebrew/services")
- assert_equal "Warning: No services available to control with `brew services`",
- cmd("services", "list")
- end
-end
diff --git a/Library/Homebrew/test/sh_test.rb b/Library/Homebrew/test/sh_test.rb
deleted file mode 100644
index 48fcdc54a..000000000
--- a/Library/Homebrew/test/sh_test.rb
+++ /dev/null
@@ -1,8 +0,0 @@
-require "testing_env"
-
-class IntegrationCommandTestSh < IntegrationCommandTestCase
- def test_sh
- assert_match "Your shell has been configured",
- cmd("sh", "SHELL" => which("true"))
- end
-end
diff --git a/Library/Homebrew/test/spec_helper.rb b/Library/Homebrew/test/spec_helper.rb
index 547ec3f7b..9a4dbe026 100644
--- a/Library/Homebrew/test/spec_helper.rb
+++ b/Library/Homebrew/test/spec_helper.rb
@@ -16,6 +16,7 @@ require "tap"
require "test/support/helper/shutup"
require "test/support/helper/fixtures"
+require "test/support/helper/formula"
require "test/support/helper/spec/shared_context/integration_test"
TEST_DIRECTORIES = [
@@ -32,9 +33,14 @@ RSpec.configure do |config|
config.order = :random
config.include(Test::Helper::Shutup)
config.include(Test::Helper::Fixtures)
+ config.include(Test::Helper::Formula)
config.before(:each) do |example|
if example.metadata[:needs_macos]
- skip "not on macOS" unless OS.mac?
+ skip "Not on macOS." unless OS.mac?
+ end
+
+ if example.metadata[:needs_official_cmd_taps]
+ skip "Needs official command Taps." unless ENV["HOMEBREW_TEST_OFFICIAL_CMD_TAPS"]
end
if example.metadata[:needs_python]
diff --git a/Library/Homebrew/test/support/helper/formula.rb b/Library/Homebrew/test/support/helper/formula.rb
new file mode 100644
index 000000000..7f55f4b66
--- /dev/null
+++ b/Library/Homebrew/test/support/helper/formula.rb
@@ -0,0 +1,19 @@
+require "formulary"
+
+module Test
+ module Helper
+ module Formula
+ def formula(name = "formula_name", path: Formulary.core_path(name), spec: :stable, alias_path: nil, &block)
+ Class.new(::Formula, &block).new(name, path, spec, alias_path: alias_path)
+ end
+
+ # Use a stubbed {Formulary::FormulaLoader} to make a given formula be found
+ # when loading from {Formulary} with `ref`.
+ def stub_formula_loader(formula, ref = formula.full_name)
+ loader = double(get_formula: formula)
+ allow(Formulary).to receive(:loader_for).with(ref, from: :keg).and_return(loader)
+ allow(Formulary).to receive(:loader_for).with(ref, from: nil).and_return(loader)
+ end
+ end
+ end
+end
diff --git a/Library/Homebrew/test/support/helper/spec/shared_context/integration_test.rb b/Library/Homebrew/test/support/helper/spec/shared_context/integration_test.rb
index dd2271a3a..2eb98826a 100644
--- a/Library/Homebrew/test/support/helper/spec/shared_context/integration_test.rb
+++ b/Library/Homebrew/test/support/helper/spec/shared_context/integration_test.rb
@@ -63,7 +63,15 @@ RSpec.shared_context "integration test" do
def brew(*args)
env = args.last.is_a?(Hash) ? args.pop : {}
+ # Avoid warnings when HOMEBREW_PREFIX/bin is not in PATH.
+ path = [
+ env["PATH"],
+ (HOMEBREW_PREFIX/"bin").realpath.to_s,
+ ENV["PATH"],
+ ].compact.join(File::PATH_SEPARATOR)
+
env.merge!(
+ "PATH" => path,
"HOMEBREW_BREW_FILE" => HOMEBREW_PREFIX/"bin/brew",
"HOMEBREW_INTEGRATION_TEST" => command_id_from_args(args),
"HOMEBREW_TEST_TMPDIR" => TEST_TMPDIR,
@@ -87,6 +95,80 @@ RSpec.shared_context "integration test" do
status
end
end
+
+ def setup_test_formula(name, content = nil)
+ case name
+ when /^testball/
+ content = <<-EOS.undent
+ desc "Some test"
+ homepage "https://example.com/#{name}"
+ url "file://#{TEST_FIXTURE_DIR}/tarballs/testball-0.1.tbz"
+ sha256 "#{TESTBALL_SHA256}"
+
+ option "with-foo", "Build with foo"
+
+ def install
+ (prefix/"foo"/"test").write("test") if build.with? "foo"
+ prefix.install Dir["*"]
+ (buildpath/"test.c").write \
+ "#include <stdio.h>\\nint main(){return printf(\\"test\\");}"
+ bin.mkpath
+ system ENV.cc, "test.c", "-o", bin/"test"
+ end
+
+ #{content}
+
+ # something here
+ EOS
+ when "foo"
+ content = <<-EOS.undent
+ url "https://example.com/#{name}-1.0"
+ EOS
+ when "bar"
+ content = <<-EOS.undent
+ url "https://example.com/#{name}-1.0"
+ depends_on "foo"
+ EOS
+ end
+
+ Formulary.core_path(name).tap do |formula_path|
+ formula_path.write <<-EOS.undent
+ class #{Formulary.class_s(name)} < Formula
+ #{content}
+ end
+ EOS
+ end
+ end
+
+ def setup_remote_tap(name)
+ Tap.fetch(name).tap do |tap|
+ tap.install(full_clone: false, quiet: true) unless tap.installed?
+ end
+ end
+
+ def install_and_rename_coretap_formula(old_name, new_name)
+ shutup do
+ CoreTap.instance.path.cd do |tap_path|
+ system "git", "init"
+ system "git", "add", "--all"
+ system "git", "commit", "-m",
+ "#{old_name.capitalize} has not yet been renamed"
+
+ brew "install", old_name
+
+ (tap_path/"Formula/#{old_name}.rb").unlink
+ (tap_path/"formula_renames.json").write JSON.generate(old_name => new_name)
+
+ system "git", "add", "--all"
+ system "git", "commit", "-m",
+ "#{old_name.capitalize} has been renamed to #{new_name.capitalize}"
+ end
+ end
+ end
+
+ def testball
+ "#{TEST_FIXTURE_DIR}/testball.rb"
+ end
end
RSpec.configure do |config|
diff --git a/Library/Homebrew/test/switch_test.rb b/Library/Homebrew/test/switch_test.rb
deleted file mode 100644
index af1926c39..000000000
--- a/Library/Homebrew/test/switch_test.rb
+++ /dev/null
@@ -1,20 +0,0 @@
-require "testing_env"
-
-class IntegrationCommandTestSwitch < IntegrationCommandTestCase
- def test_switch
- assert_match "Usage: brew switch <name> <version>", cmd_fail("switch")
- assert_match "testball not found", cmd_fail("switch", "testball", "0.1")
-
- setup_test_formula "testball", <<-EOS.undent
- keg_only "just because"
- EOS
-
- cmd("install", "testball")
- testball_rack = HOMEBREW_CELLAR/"testball"
- FileUtils.cp_r testball_rack/"0.1", testball_rack/"0.2"
-
- cmd("switch", "testball", "0.2")
- assert_match "testball does not have a version \"0.3\"",
- cmd_fail("switch", "testball", "0.3")
- end
-end
diff --git a/Library/Homebrew/test/tab_spec.rb b/Library/Homebrew/test/tab_spec.rb
new file mode 100644
index 000000000..01dbeb67c
--- /dev/null
+++ b/Library/Homebrew/test/tab_spec.rb
@@ -0,0 +1,341 @@
+require "tab"
+require "formula"
+
+RSpec::Matchers.alias_matcher :be_built_with, :be_with
+
+describe Tab do
+ matcher :be_poured_from_bottle do
+ match do |actual|
+ actual.poured_from_bottle == true
+ end
+ end
+
+ matcher :be_built_as_bottle do
+ match do |actual|
+ actual.built_as_bottle == true
+ end
+ end
+
+ subject {
+ described_class.new(
+ "homebrew_version" => HOMEBREW_VERSION,
+ "used_options" => used_options.as_flags,
+ "unused_options" => unused_options.as_flags,
+ "built_as_bottle" => false,
+ "poured_from_bottle" => true,
+ "changed_files" => [],
+ "time" => time,
+ "source_modified_time" => 0,
+ "HEAD" => TEST_SHA1,
+ "compiler" => "clang",
+ "stdlib" => "libcxx",
+ "runtime_dependencies" => [],
+ "source" => {
+ "tap" => CoreTap.instance.to_s,
+ "path" => CoreTap.instance.path.to_s,
+ "spec" => "stable",
+ "versions" => {
+ "stable" => "0.10",
+ "devel" => "0.14",
+ "head" => "HEAD-1111111",
+ },
+ },
+ )
+ }
+ let(:time) { Time.now.to_i }
+ let(:unused_options) { Options.create(%w[--with-baz --without-qux]) }
+ let(:used_options) { Options.create(%w[--with-foo --without-bar]) }
+
+ let(:f) { formula { url "foo-1.0" } }
+ let(:f_tab_path) { f.prefix/"INSTALL_RECEIPT.json" }
+ let(:f_tab_content) { (TEST_FIXTURE_DIR/"receipt.json").read }
+
+ specify "defaults" do
+ tab = described_class.empty
+
+ expect(tab.homebrew_version).to eq(HOMEBREW_VERSION)
+ expect(tab.unused_options).to be_empty
+ expect(tab.used_options).to be_empty
+ expect(tab.changed_files).to be nil
+ expect(tab).not_to be_built_as_bottle
+ expect(tab).not_to be_poured_from_bottle
+ expect(tab).to be_stable
+ expect(tab).not_to be_devel
+ expect(tab).not_to be_head
+ expect(tab.tap).to be nil
+ expect(tab.time).to be nil
+ expect(tab.HEAD).to be nil
+ expect(tab.runtime_dependencies).to be_empty
+ expect(tab.stable_version).to be nil
+ expect(tab.devel_version).to be nil
+ expect(tab.head_version).to be nil
+ expect(tab.cxxstdlib.compiler).to eq(DevelopmentTools.default_compiler)
+ expect(tab.cxxstdlib.type).to be nil
+ expect(tab.source["path"]).to be nil
+ end
+
+ specify "#include?" do
+ expect(subject).to include("with-foo")
+ expect(subject).to include("without-bar")
+ end
+
+ specify "#with?" do
+ expect(subject).to be_built_with("foo")
+ expect(subject).to be_built_with("qux")
+ expect(subject).not_to be_built_with("bar")
+ expect(subject).not_to be_built_with("baz")
+ end
+
+ specify "#universal?" do
+ tab = described_class.new(used_options: %w[--universal])
+ expect(tab).to be_universal
+ end
+
+ specify "#parsed_homebrew_version" do
+ tab = described_class.new
+ expect(tab.parsed_homebrew_version).to be Version::NULL
+
+ tab = described_class.new(homebrew_version: "1.2.3")
+ expect(tab.parsed_homebrew_version).to eq("1.2.3")
+ expect(tab.parsed_homebrew_version).to be < "1.2.3-1-g12789abdf"
+ expect(tab.parsed_homebrew_version).to be_kind_of(Version)
+
+ tab.homebrew_version = "1.2.4-567-g12789abdf"
+ expect(tab.parsed_homebrew_version).to be > "1.2.4"
+ expect(tab.parsed_homebrew_version).to be > "1.2.4-566-g21789abdf"
+ expect(tab.parsed_homebrew_version).to be < "1.2.4-568-g01789abdf"
+
+ tab = described_class.new(homebrew_version: "2.0.0-134-gabcdefabc-dirty")
+ expect(tab.parsed_homebrew_version).to be > "2.0.0"
+ expect(tab.parsed_homebrew_version).to be > "2.0.0-133-g21789abdf"
+ expect(tab.parsed_homebrew_version).to be < "2.0.0-135-g01789abdf"
+ end
+
+ specify "#runtime_dependencies" do
+ tab = described_class.new
+ expect(tab.runtime_dependencies).to be nil
+
+ tab.homebrew_version = "1.1.6"
+ expect(tab.runtime_dependencies).to be nil
+
+ tab.runtime_dependencies = []
+ expect(tab.runtime_dependencies).not_to be nil
+
+ tab.homebrew_version = "1.1.5"
+ expect(tab.runtime_dependencies).to be nil
+
+ tab.homebrew_version = "1.1.7"
+ expect(tab.runtime_dependencies).not_to be nil
+
+ tab.homebrew_version = "1.1.10"
+ expect(tab.runtime_dependencies).not_to be nil
+
+ tab.runtime_dependencies = [{ "full_name" => "foo", "version" => "1.0" }]
+ expect(tab.runtime_dependencies).not_to be nil
+ end
+
+ specify "#cxxstdlib" do
+ expect(subject.cxxstdlib.compiler).to eq(:clang)
+ expect(subject.cxxstdlib.type).to eq(:libcxx)
+ end
+
+ specify "other attributes" do
+ expect(subject.HEAD).to eq(TEST_SHA1)
+ expect(subject.tap.name).to eq("homebrew/core")
+ expect(subject.time).to eq(time)
+ expect(subject).not_to be_built_as_bottle
+ expect(subject).to be_poured_from_bottle
+ end
+
+ describe "::from_file" do
+ it "parses a Tab from a file" do
+ path = Pathname.new("#{TEST_FIXTURE_DIR}/receipt.json")
+ tab = described_class.from_file(path)
+ source_path = "/usr/local/Library/Taps/homebrew/homebrew-core/Formula/foo.rb"
+ runtime_dependencies = [{ "full_name" => "foo", "version" => "1.0" }]
+ changed_files = %w[INSTALL_RECEIPT.json bin/foo]
+
+ expect(tab.used_options.sort).to eq(used_options.sort)
+ expect(tab.unused_options.sort).to eq(unused_options.sort)
+ expect(tab.changed_files).to eq(changed_files)
+ expect(tab).not_to be_built_as_bottle
+ expect(tab).to be_poured_from_bottle
+ expect(tab).to be_stable
+ expect(tab).not_to be_devel
+ expect(tab).not_to be_head
+ expect(tab.tap.name).to eq("homebrew/core")
+ expect(tab.spec).to eq(:stable)
+ expect(tab.time).to eq(Time.at(1_403_827_774).to_i)
+ expect(tab.HEAD).to eq(TEST_SHA1)
+ expect(tab.cxxstdlib.compiler).to eq(:clang)
+ expect(tab.cxxstdlib.type).to eq(:libcxx)
+ expect(tab.runtime_dependencies).to eq(runtime_dependencies)
+ expect(tab.stable_version.to_s).to eq("2.14")
+ expect(tab.devel_version.to_s).to eq("2.15")
+ expect(tab.head_version.to_s).to eq("HEAD-0000000")
+ expect(tab.source["path"]).to eq(source_path)
+ end
+
+ it "can parse an old Tab file" do
+ path = Pathname.new("#{TEST_FIXTURE_DIR}/receipt_old.json")
+ tab = described_class.from_file(path)
+
+ expect(tab.used_options.sort).to eq(used_options.sort)
+ expect(tab.unused_options.sort).to eq(unused_options.sort)
+ expect(tab).not_to be_built_as_bottle
+ expect(tab).to be_poured_from_bottle
+ expect(tab).to be_stable
+ expect(tab).not_to be_devel
+ expect(tab).not_to be_head
+ expect(tab.tap.name).to eq("homebrew/core")
+ expect(tab.spec).to eq(:stable)
+ expect(tab.time).to eq(Time.at(1_403_827_774).to_i)
+ expect(tab.HEAD).to eq(TEST_SHA1)
+ expect(tab.cxxstdlib.compiler).to eq(:clang)
+ expect(tab.cxxstdlib.type).to eq(:libcxx)
+ expect(tab.runtime_dependencies).to be nil
+ end
+ end
+
+ describe "::create" do
+ it "creates a Tab" do
+ f = formula do
+ url "foo-1.0"
+ depends_on "bar"
+ depends_on "user/repo/from_tap"
+ depends_on "baz" => :build
+ end
+
+ tap = Tap.new("user", "repo")
+ from_tap = formula("from_tap", path: tap.path/"Formula/from_tap.rb") do
+ url "from_tap-1.0"
+ end
+ stub_formula_loader from_tap
+
+ stub_formula_loader formula("bar") { url "bar-2.0" }
+ stub_formula_loader formula("baz") { url "baz-3.0" }
+
+ compiler = DevelopmentTools.default_compiler
+ stdlib = :libcxx
+ tab = described_class.create(f, compiler, stdlib)
+
+ runtime_dependencies = [
+ { "full_name" => "bar", "version" => "2.0" },
+ { "full_name" => "user/repo/from_tap", "version" => "1.0" },
+ ]
+
+ expect(tab.runtime_dependencies).to eq(runtime_dependencies)
+ expect(tab.source["path"]).to eq(f.path.to_s)
+ end
+
+ it "can create a Tab from an alias" do
+ alias_path = CoreTap.instance.alias_dir/"bar"
+ f = formula(alias_path: alias_path) { url "foo-1.0" }
+ compiler = DevelopmentTools.default_compiler
+ stdlib = :libcxx
+ tab = described_class.create(f, compiler, stdlib)
+
+ expect(tab.source["path"]).to eq(f.alias_path.to_s)
+ end
+ end
+
+ describe "::for_keg" do
+ subject { described_class.for_keg(f.prefix) }
+
+ it "creates a Tab for a given Keg" do
+ f.prefix.mkpath
+ f_tab_path.write f_tab_content
+
+ expect(subject.tabfile).to eq(f_tab_path)
+ end
+
+ it "can create a Tab for a non-existant Keg" do
+ f.prefix.mkpath
+
+ expect(subject.tabfile).to be nil
+ end
+ end
+
+ describe "::for_formula" do
+ it "creates a Tab for a given Formula" do
+ tab = described_class.for_formula(f)
+ expect(tab.source["path"]).to eq(f.path.to_s)
+ end
+
+ it "can create a Tab for for a Formula from an alias" do
+ alias_path = CoreTap.instance.alias_dir/"bar"
+ f = formula(alias_path: alias_path) { url "foo-1.0" }
+
+ tab = described_class.for_formula(f)
+ expect(tab.source["path"]).to eq(alias_path.to_s)
+ end
+
+ it "creates a Tab for a given Formula" do
+ f.prefix.mkpath
+ f_tab_path.write f_tab_content
+
+ tab = described_class.for_formula(f)
+ expect(tab.tabfile).to eq(f_tab_path)
+ end
+
+ it "can create a Tab for a non-existant Formula" do
+ f.prefix.mkpath
+
+ tab = described_class.for_formula(f)
+ expect(tab.tabfile).to be nil
+ end
+
+ it "can create a Tab for a Formula with multiple Kegs" do
+ f.prefix.mkpath
+ f_tab_path.write f_tab_content
+
+ f2 = formula { url "foo-2.0" }
+ f2.prefix.mkpath
+
+ expect(f2.rack).to eq(f.rack)
+ expect(f.installed_prefixes.length).to eq(2)
+
+ tab = described_class.for_formula(f)
+ expect(tab.tabfile).to eq(f_tab_path)
+ end
+
+ it "can create a Tab for a Formula with an outdated Kegs" do
+ f_tab_path.write f_tab_content
+
+ f2 = formula { url "foo-2.0" }
+
+ expect(f2.rack).to eq(f.rack)
+ expect(f.installed_prefixes.length).to eq(1)
+
+ tab = described_class.for_formula(f)
+ expect(tab.tabfile).to eq(f_tab_path)
+ end
+ end
+
+ specify "#to_json" do
+ tab = described_class.new(JSON.parse(subject.to_json))
+ expect(tab.used_options.sort).to eq(subject.used_options.sort)
+ expect(tab.unused_options.sort).to eq(subject.unused_options.sort)
+ expect(tab.built_as_bottle).to eq(subject.built_as_bottle)
+ expect(tab.poured_from_bottle).to eq(subject.poured_from_bottle)
+ expect(tab.changed_files).to eq(subject.changed_files)
+ expect(tab.tap).to eq(subject.tap)
+ expect(tab.spec).to eq(subject.spec)
+ expect(tab.time).to eq(subject.time)
+ expect(tab.HEAD).to eq(subject.HEAD)
+ expect(tab.compiler).to eq(subject.compiler)
+ expect(tab.stdlib).to eq(subject.stdlib)
+ expect(tab.runtime_dependencies).to eq(subject.runtime_dependencies)
+ expect(tab.stable_version).to eq(subject.stable_version)
+ expect(tab.devel_version).to eq(subject.devel_version)
+ expect(tab.head_version).to eq(subject.head_version)
+ expect(tab.source["path"]).to eq(subject.source["path"])
+ end
+
+ specify "::remap_deprecated_options" do
+ deprecated_options = [DeprecatedOption.new("with-foo", "with-foo-new")]
+ remapped_options = described_class.remap_deprecated_options(deprecated_options, subject.used_options)
+ expect(remapped_options).to include(Option.new("without-bar"))
+ expect(remapped_options).to include(Option.new("with-foo-new"))
+ end
+end
diff --git a/Library/Homebrew/test/tab_test.rb b/Library/Homebrew/test/tab_test.rb
deleted file mode 100644
index 08d45ee90..000000000
--- a/Library/Homebrew/test/tab_test.rb
+++ /dev/null
@@ -1,318 +0,0 @@
-require "testing_env"
-require "tab"
-require "formula"
-
-class TabTests < Homebrew::TestCase
- def setup
- super
-
- @time = Time.now.to_i
- @used = Options.create(%w[--with-foo --without-bar])
- @unused = Options.create(%w[--with-baz --without-qux])
-
- @tab = Tab.new(
- "homebrew_version" => HOMEBREW_VERSION,
- "used_options" => @used.as_flags,
- "unused_options" => @unused.as_flags,
- "built_as_bottle" => false,
- "poured_from_bottle" => true,
- "changed_files" => [],
- "time" => @time,
- "source_modified_time" => 0,
- "HEAD" => TEST_SHA1,
- "compiler" => "clang",
- "stdlib" => "libcxx",
- "runtime_dependencies" => [],
- "source" => {
- "tap" => CoreTap.instance.to_s,
- "path" => CoreTap.instance.path.to_s,
- "spec" => "stable",
- "versions" => {
- "stable" => "0.10",
- "devel" => "0.14",
- "head" => "HEAD-1111111",
- },
- },
- )
- end
-
- def test_defaults
- tab = Tab.empty
-
- assert_equal HOMEBREW_VERSION, tab.homebrew_version
- assert_empty tab.unused_options
- assert_empty tab.used_options
- assert_nil tab.changed_files
- refute_predicate tab, :built_as_bottle
- refute_predicate tab, :poured_from_bottle
- assert_predicate tab, :stable?
- refute_predicate tab, :devel?
- refute_predicate tab, :head?
- assert_nil tab.tap
- assert_nil tab.time
- assert_nil tab.HEAD
- assert_empty tab.runtime_dependencies
- assert_nil tab.stable_version
- assert_nil tab.devel_version
- assert_nil tab.head_version
- assert_equal DevelopmentTools.default_compiler, tab.cxxstdlib.compiler
- assert_nil tab.cxxstdlib.type
- assert_nil tab.source["path"]
- end
-
- def test_include?
- assert_includes @tab, "with-foo"
- assert_includes @tab, "without-bar"
- end
-
- def test_with?
- assert @tab.with?("foo")
- assert @tab.with?("qux")
- refute @tab.with?("bar")
- refute @tab.with?("baz")
- end
-
- def test_universal?
- tab = Tab.new(used_options: %w[--universal])
- assert_predicate tab, :universal?
- end
-
- def test_parsed_homebrew_version
- tab = Tab.new
- assert_same Version::NULL, tab.parsed_homebrew_version
-
- tab = Tab.new(homebrew_version: "1.2.3")
- assert_equal "1.2.3", tab.parsed_homebrew_version
- assert tab.parsed_homebrew_version < "1.2.3-1-g12789abdf"
- assert_kind_of Version, tab.parsed_homebrew_version
-
- tab.homebrew_version = "1.2.4-567-g12789abdf"
- assert tab.parsed_homebrew_version > "1.2.4"
- assert tab.parsed_homebrew_version > "1.2.4-566-g21789abdf"
- assert tab.parsed_homebrew_version < "1.2.4-568-g01789abdf"
-
- tab = Tab.new(homebrew_version: "2.0.0-134-gabcdefabc-dirty")
- assert tab.parsed_homebrew_version > "2.0.0"
- assert tab.parsed_homebrew_version > "2.0.0-133-g21789abdf"
- assert tab.parsed_homebrew_version < "2.0.0-135-g01789abdf"
- end
-
- def test_runtime_dependencies
- tab = Tab.new
- assert_nil tab.runtime_dependencies
-
- tab.homebrew_version = "1.1.6"
- assert_nil tab.runtime_dependencies
-
- tab.runtime_dependencies = []
- refute_nil tab.runtime_dependencies
-
- tab.homebrew_version = "1.1.5"
- assert_nil tab.runtime_dependencies
-
- tab.homebrew_version = "1.1.7"
- refute_nil tab.runtime_dependencies
-
- tab.homebrew_version = "1.1.10"
- refute_nil tab.runtime_dependencies
-
- tab.runtime_dependencies = [{ "full_name" => "foo", "version" => "1.0" }]
- refute_nil tab.runtime_dependencies
- end
-
- def test_cxxstdlib
- assert_equal :clang, @tab.cxxstdlib.compiler
- assert_equal :libcxx, @tab.cxxstdlib.type
- end
-
- def test_other_attributes
- assert_equal TEST_SHA1, @tab.HEAD
- assert_equal "homebrew/core", @tab.tap.name
- assert_equal @time, @tab.time
- refute_predicate @tab, :built_as_bottle
- assert_predicate @tab, :poured_from_bottle
- end
-
- def test_from_old_version_file
- path = Pathname.new("#{TEST_FIXTURE_DIR}/receipt_old.json")
- tab = Tab.from_file(path)
-
- assert_equal @used.sort, tab.used_options.sort
- assert_equal @unused.sort, tab.unused_options.sort
- refute_predicate tab, :built_as_bottle
- assert_predicate tab, :poured_from_bottle
- assert_predicate tab, :stable?
- refute_predicate tab, :devel?
- refute_predicate tab, :head?
- assert_equal "homebrew/core", tab.tap.name
- assert_equal :stable, tab.spec
- refute_nil tab.time
- assert_equal TEST_SHA1, tab.HEAD
- assert_equal :clang, tab.cxxstdlib.compiler
- assert_equal :libcxx, tab.cxxstdlib.type
- assert_nil tab.runtime_dependencies
- end
-
- def test_from_file
- path = Pathname.new("#{TEST_FIXTURE_DIR}/receipt.json")
- tab = Tab.from_file(path)
- source_path = "/usr/local/Library/Taps/homebrew/homebrew-core/Formula/foo.rb"
- runtime_dependencies = [{ "full_name" => "foo", "version" => "1.0" }]
- changed_files = %w[INSTALL_RECEIPT.json bin/foo]
-
- assert_equal @used.sort, tab.used_options.sort
- assert_equal @unused.sort, tab.unused_options.sort
- assert_equal changed_files, tab.changed_files
- refute_predicate tab, :built_as_bottle
- assert_predicate tab, :poured_from_bottle
- assert_predicate tab, :stable?
- refute_predicate tab, :devel?
- refute_predicate tab, :head?
- assert_equal "homebrew/core", tab.tap.name
- assert_equal :stable, tab.spec
- refute_nil tab.time
- assert_equal TEST_SHA1, tab.HEAD
- assert_equal :clang, tab.cxxstdlib.compiler
- assert_equal :libcxx, tab.cxxstdlib.type
- assert_equal runtime_dependencies, tab.runtime_dependencies
- assert_equal "2.14", tab.stable_version.to_s
- assert_equal "2.15", tab.devel_version.to_s
- assert_equal "HEAD-0000000", tab.head_version.to_s
- assert_equal source_path, tab.source["path"]
- end
-
- def test_create
- f = formula do
- url "foo-1.0"
- depends_on "bar"
- depends_on "user/repo/from_tap"
- depends_on "baz" => :build
- end
-
- tap = Tap.new("user", "repo")
- from_tap = formula("from_tap", tap.path/"Formula/from_tap.rb") do
- url "from_tap-1.0"
- end
- stub_formula_loader from_tap
-
- stub_formula_loader formula("bar") { url "bar-2.0" }
- stub_formula_loader formula("baz") { url "baz-3.0" }
-
- compiler = DevelopmentTools.default_compiler
- stdlib = :libcxx
- tab = Tab.create(f, compiler, stdlib)
-
- runtime_dependencies = [
- { "full_name" => "bar", "version" => "2.0" },
- { "full_name" => "user/repo/from_tap", "version" => "1.0" },
- ]
-
- assert_equal runtime_dependencies, tab.runtime_dependencies
- assert_equal f.path.to_s, tab.source["path"]
- end
-
- def test_create_from_alias
- alias_path = CoreTap.instance.alias_dir/"bar"
- f = formula(alias_path: alias_path) { url "foo-1.0" }
- compiler = DevelopmentTools.default_compiler
- stdlib = :libcxx
- tab = Tab.create(f, compiler, stdlib)
-
- assert_equal f.alias_path.to_s, tab.source["path"]
- end
-
- def test_for_formula
- f = formula { url "foo-1.0" }
- tab = Tab.for_formula(f)
-
- assert_equal f.path.to_s, tab.source["path"]
- end
-
- def test_for_formula_from_alias
- alias_path = CoreTap.instance.alias_dir/"bar"
- f = formula(alias_path: alias_path) { url "foo-1.0" }
- tab = Tab.for_formula(f)
-
- assert_equal alias_path.to_s, tab.source["path"]
- end
-
- def test_to_json
- tab = Tab.new(JSON.parse(@tab.to_json))
- assert_equal @tab.used_options.sort, tab.used_options.sort
- assert_equal @tab.unused_options.sort, tab.unused_options.sort
- assert_equal @tab.built_as_bottle, tab.built_as_bottle
- assert_equal @tab.poured_from_bottle, tab.poured_from_bottle
- assert_equal @tab.changed_files, tab.changed_files
- assert_equal @tab.tap, tab.tap
- assert_equal @tab.spec, tab.spec
- assert_equal @tab.time, tab.time
- assert_equal @tab.HEAD, tab.HEAD
- assert_equal @tab.compiler, tab.compiler
- assert_equal @tab.stdlib, tab.stdlib
- assert_equal @tab.runtime_dependencies, tab.runtime_dependencies
- assert_equal @tab.stable_version, tab.stable_version
- assert_equal @tab.devel_version, tab.devel_version
- assert_equal @tab.head_version, tab.head_version
- assert_equal @tab.source["path"], tab.source["path"]
- end
-
- def test_remap_deprecated_options
- deprecated_options = [DeprecatedOption.new("with-foo", "with-foo-new")]
- remapped_options = Tab.remap_deprecated_options(deprecated_options, @tab.used_options)
- assert_includes remapped_options, Option.new("without-bar")
- assert_includes remapped_options, Option.new("with-foo-new")
- end
-end
-
-class TabLoadingTests < Homebrew::TestCase
- def setup
- super
- @f = formula { url "foo-1.0" }
- @f.prefix.mkpath
- @path = @f.prefix.join(Tab::FILENAME)
- @path.write TEST_FIXTURE_DIR.join("receipt.json").read
- end
-
- def test_for_keg
- tab = Tab.for_keg(@f.prefix)
- assert_equal @path, tab.tabfile
- end
-
- def test_for_keg_nonexistent_path
- @path.unlink
- tab = Tab.for_keg(@f.prefix)
- assert_nil tab.tabfile
- end
-
- def test_for_formula
- tab = Tab.for_formula(@f)
- assert_equal @path, tab.tabfile
- end
-
- def test_for_formula_nonexistent_path
- @path.unlink
- tab = Tab.for_formula(@f)
- assert_nil tab.tabfile
- end
-
- def test_for_formula_multiple_kegs
- f2 = formula { url "foo-2.0" }
- f2.prefix.mkpath
-
- assert_equal @f.rack, f2.rack
- assert_equal 2, @f.installed_prefixes.length
-
- tab = Tab.for_formula(@f)
- assert_equal @path, tab.tabfile
- end
-
- def test_for_formula_outdated_keg
- f2 = formula { url "foo-2.0" }
-
- assert_equal @f.rack, f2.rack
- assert_equal 1, @f.installed_prefixes.length
-
- tab = Tab.for_formula(f2)
- assert_equal @path, tab.tabfile
- end
-end
diff --git a/Library/Homebrew/test/tap_new_test.rb b/Library/Homebrew/test/tap_new_test.rb
deleted file mode 100644
index 261a334f0..000000000
--- a/Library/Homebrew/test/tap_new_test.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-require "testing_env"
-
-class IntegrationCommandTestTapNew < IntegrationCommandTestCase
- def test_tap_readme
- assert_equal "", cmd("tap-new", "homebrew/foo", "--verbose")
- readme = HOMEBREW_LIBRARY/"Taps/homebrew/homebrew-foo/README.md"
- assert readme.exist?, "The README should be created"
- end
-end
diff --git a/Library/Homebrew/test/tap_test.rb b/Library/Homebrew/test/tap_test.rb
index 578326cea..729fc8198 100644
--- a/Library/Homebrew/test/tap_test.rb
+++ b/Library/Homebrew/test/tap_test.rb
@@ -1,34 +1,4 @@
require "testing_env"
-require "testing_env"
-
-class IntegrationCommandTestTap < IntegrationCommandTestCase
- def test_tap
- path = Tap::TAP_DIRECTORY/"homebrew/homebrew-foo"
- path.mkpath
- path.cd do
- shutup do
- system "git", "init"
- system "git", "remote", "add", "origin", "https://github.com/Homebrew/homebrew-foo"
- FileUtils.touch "readme"
- system "git", "add", "--all"
- system "git", "commit", "-m", "init"
- end
- end
-
- assert_match "homebrew/foo", cmd("tap")
- assert_match "homebrew/science", cmd("tap", "--list-official")
- assert_match "2 taps", cmd("tap-info")
- assert_match "https://github.com/Homebrew/homebrew-foo", cmd("tap-info", "homebrew/foo")
- assert_match "https://github.com/Homebrew/homebrew-foo", cmd("tap-info", "--json=v1", "--installed")
- assert_match "Pinned homebrew/foo", cmd("tap-pin", "homebrew/foo")
- assert_match "homebrew/foo", cmd("tap", "--list-pinned")
- assert_match "Unpinned homebrew/foo", cmd("tap-unpin", "homebrew/foo")
- assert_match "Tapped", cmd("tap", "homebrew/bar", path/".git")
- assert_match "Untapped", cmd("untap", "homebrew/bar")
- assert_equal "", cmd("tap", "homebrew/bar", path/".git", "-q", "--full")
- assert_match "Untapped", cmd("untap", "homebrew/bar")
- end
-end
class TapTest < Homebrew::TestCase
include FileUtils
diff --git a/Library/Homebrew/test/test_formula_test.rb b/Library/Homebrew/test/test_formula_test.rb
deleted file mode 100644
index 5ad2db9e9..000000000
--- a/Library/Homebrew/test/test_formula_test.rb
+++ /dev/null
@@ -1,30 +0,0 @@
-require "testing_env"
-
-class IntegrationCommandTestTestFormula < IntegrationCommandTestCase
- def test_test_formula
- assert_match "This command requires a formula argument", cmd_fail("test")
- assert_match "Testing requires the latest version of testball",
- cmd_fail("test", testball)
-
- cmd("install", testball)
- assert_match "testball defines no test", cmd_fail("test", testball)
-
- setup_test_formula "testball_copy", <<-EOS.undent
- head "https://github.com/example/testball2.git"
-
- devel do
- url "file://#{TEST_FIXTURE_DIR}/tarballs/testball-0.1.tbz"
- sha256 "#{TESTBALL_SHA256}"
- end
-
- keg_only "just because"
-
- test do
- end
- EOS
-
- cmd("install", "testball_copy")
- assert_match "Testing testball_copy", cmd("test", "--HEAD", "testball_copy")
- assert_match "Testing testball_copy", cmd("test", "--devel", "testball_copy")
- end
-end
diff --git a/Library/Homebrew/test/uninstall_test.rb b/Library/Homebrew/test/uninstall_test.rb
index 2f8bf4fff..a9230ffac 100644
--- a/Library/Homebrew/test/uninstall_test.rb
+++ b/Library/Homebrew/test/uninstall_test.rb
@@ -60,10 +60,3 @@ class UninstallTests < Homebrew::TestCase
end
end
end
-
-class IntegrationCommandTestUninstall < IntegrationCommandTestCase
- def test_uninstall
- cmd("install", testball)
- assert_match "Uninstalling testball", cmd("uninstall", "--force", testball)
- end
-end
diff --git a/Library/Homebrew/test/unlink_test.rb b/Library/Homebrew/test/unlink_test.rb
deleted file mode 100644
index 6d5cefc67..000000000
--- a/Library/Homebrew/test/unlink_test.rb
+++ /dev/null
@@ -1,10 +0,0 @@
-require "testing_env"
-
-class IntegrationCommandTestUnlink < IntegrationCommandTestCase
- def test_unlink
- setup_test_formula "testball"
-
- cmd("install", "testball")
- assert_match "Would remove", cmd("unlink", "--dry-run", "testball")
- end
-end
diff --git a/Library/Homebrew/test/unlinkapps_test.rb b/Library/Homebrew/test/unlinkapps_test.rb
deleted file mode 100644
index 9d9672199..000000000
--- a/Library/Homebrew/test/unlinkapps_test.rb
+++ /dev/null
@@ -1,19 +0,0 @@
-require "testing_env"
-
-class IntegrationCommandTestUnlinkapps < IntegrationCommandTestCase
- def test_unlinkapps
- home_dir = Pathname.new(mktmpdir)
- apps_dir = home_dir/"Applications"
- 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"
-
- assert_match "Unlinking: #{apps_dir}/TestBall.app",
- cmd("unlinkapps", "--local", "HOME" => home_dir)
- end
-end
diff --git a/Library/Homebrew/test/unpack_test.rb b/Library/Homebrew/test/unpack_test.rb
deleted file mode 100644
index bbff6ad1c..000000000
--- a/Library/Homebrew/test/unpack_test.rb
+++ /dev/null
@@ -1,13 +0,0 @@
-require "testing_env"
-
-class IntegrationCommandTestUnpack < IntegrationCommandTestCase
- def test_unpack
- setup_test_formula "testball"
-
- mktmpdir do |path|
- cmd "unpack", "testball", "--destdir=#{path}"
- assert File.directory?("#{path}/testball-0.1"),
- "The tarball should be unpacked"
- end
- end
-end
diff --git a/Library/Homebrew/test/update_report_test.rb b/Library/Homebrew/test/update_report_test.rb
deleted file mode 100644
index 32c3e36d0..000000000
--- a/Library/Homebrew/test/update_report_test.rb
+++ /dev/null
@@ -1,135 +0,0 @@
-require "testing_env"
-require "cmd/update-report"
-require "formula_versions"
-require "yaml"
-
-class ReportTests < Homebrew::TestCase
- class ReporterMock < ::Reporter
- attr_accessor :diff
-
- def initialize(tap)
- @tap = tap
- ENV["HOMEBREW_UPDATE_BEFORE#{repo_var}"] = "12345678"
- ENV["HOMEBREW_UPDATE_AFTER#{repo_var}"] = "abcdef12"
- super(tap)
- end
- end
-
- def fixture(name)
- self.class.fixture_data[name] || ""
- end
-
- def self.fixture_data
- @fixture_data ||= YAML.load_file("#{TEST_FIXTURE_DIR}/updater_fixture.yaml")
- end
-
- def setup
- super
- @tap = CoreTap.new
- @reporter = ReporterMock.new(@tap)
- @hub = ReporterHub.new
- end
-
- def perform_update(fixture_name = "")
- Formulary.stubs(:factory).returns(stub(pkg_version: "1.0"))
- FormulaVersions.stubs(:new).returns(stub(formula_at_revision: "2.0"))
- @reporter.diff = fixture(fixture_name)
- @hub.add(@reporter) if @reporter.updated?
- end
-
- def test_update_report_without_revision_var
- ENV.delete_if { |k, _v| k.start_with? "HOMEBREW_UPDATE" }
- assert_raises(Reporter::ReporterRevisionUnsetError) { Reporter.new(@tap) }
- end
-
- def test_update_homebrew_without_any_changes
- perform_update
- assert_empty @hub
- end
-
- def test_update_homebrew_without_formulae_changes
- perform_update("update_git_diff_output_without_formulae_changes")
- assert_empty @hub.select_formula(:M)
- assert_empty @hub.select_formula(:A)
- assert_empty @hub.select_formula(:D)
- end
-
- def test_update_homebrew_with_formulae_changes
- perform_update("update_git_diff_output_with_formulae_changes")
- assert_equal %w[xar yajl], @hub.select_formula(:M)
- assert_equal %w[antiword bash-completion ddrescue dict lua], @hub.select_formula(:A)
- end
-
- def test_update_homebrew_with_removed_formulae
- perform_update("update_git_diff_output_with_removed_formulae")
- assert_equal %w[libgsasl], @hub.select_formula(:D)
- end
-
- def test_update_homebrew_with_changed_filetype
- perform_update("update_git_diff_output_with_changed_filetype")
- assert_equal %w[elixir], @hub.select_formula(:M)
- assert_equal %w[libbson], @hub.select_formula(:A)
- assert_equal %w[libgsasl], @hub.select_formula(:D)
- end
-
- def test_update_homebrew_with_formula_rename
- @tap.stubs(:formula_renames).returns("cv" => "progress")
- perform_update("update_git_diff_output_with_formula_rename")
- assert_empty @hub.select_formula(:A)
- assert_empty @hub.select_formula(:D)
- assert_equal [["cv", "progress"]], @hub.select_formula(:R)
- end
-
- def test_update_homebrew_with_restructured_tap
- tap = Tap.new("foo", "bar")
- @reporter = ReporterMock.new(tap)
- tap.path.join("Formula").mkpath
-
- perform_update("update_git_diff_output_with_restructured_tap")
- assert_empty @hub.select_formula(:A)
- assert_empty @hub.select_formula(:D)
- assert_empty @hub.select_formula(:R)
- ensure
- tap.path.parent.rmtree
- end
-
- def test_update_homebrew_with_formula_rename_and_restructuring
- tap = Tap.new("foo", "bar")
- @reporter = ReporterMock.new(tap)
- tap.path.join("Formula").mkpath
- tap.stubs(:formula_renames).returns("xchat" => "xchat2")
-
- perform_update("update_git_diff_output_with_formula_rename_and_restructuring")
- assert_empty @hub.select_formula(:A)
- assert_empty @hub.select_formula(:D)
- assert_equal [%w[foo/bar/xchat foo/bar/xchat2]], @hub.select_formula(:R)
- ensure
- tap.path.parent.rmtree
- end
-
- def test_update_homebrew_simulate_homebrew_php_restructuring
- tap = Tap.new("foo", "bar")
- @reporter = ReporterMock.new(tap)
- tap.path.join("Formula").mkpath
-
- perform_update("update_git_diff_simulate_homebrew_php_restructuring")
- assert_empty @hub.select_formula(:A)
- assert_empty @hub.select_formula(:D)
- assert_empty @hub.select_formula(:R)
- ensure
- tap.path.parent.rmtree
- end
-
- def test_update_homebrew_with_tap_formulae_changes
- tap = Tap.new("foo", "bar")
- @reporter = ReporterMock.new(tap)
- tap.path.join("Formula").mkpath
-
- perform_update("update_git_diff_output_with_tap_formulae_changes")
- assert_equal %w[foo/bar/lua], @hub.select_formula(:A)
- assert_equal %w[foo/bar/git], @hub.select_formula(:M)
- assert_empty @hub.select_formula(:D)
- ensure
- tap.path.parent.rmtree
- end
-end
diff --git a/Library/Homebrew/test/upgrade_test.rb b/Library/Homebrew/test/upgrade_test.rb
deleted file mode 100644
index f3f5dccc7..000000000
--- a/Library/Homebrew/test/upgrade_test.rb
+++ /dev/null
@@ -1,12 +0,0 @@
-require "testing_env"
-
-class IntegrationCommandTestUpgrade < IntegrationCommandTestCase
- def test_upgrade
- setup_test_formula "testball"
- (HOMEBREW_CELLAR/"testball/0.0.1/foo").mkpath
-
- cmd("upgrade")
- assert((HOMEBREW_CELLAR/"testball/0.1").directory?,
- "The latest version directory should be created")
- end
-end
diff --git a/Library/Homebrew/test/uses_test.rb b/Library/Homebrew/test/uses_test.rb
deleted file mode 100644
index 1fad0da28..000000000
--- a/Library/Homebrew/test/uses_test.rb
+++ /dev/null
@@ -1,16 +0,0 @@
-require "testing_env"
-
-class IntegrationCommandTestUses < IntegrationCommandTestCase
- def test_uses
- 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
-
- assert_equal "", cmd("uses", "baz")
- assert_equal "baz", cmd("uses", "bar")
- assert_match(/(bar\nbaz|baz\nbar)/, cmd("uses", "--recursive", "foo"))
- end
-end
diff --git a/Library/Homebrew/test/utils/bottles/bottles_spec.rb b/Library/Homebrew/test/utils/bottles/bottles_spec.rb
new file mode 100644
index 000000000..8b54b0b34
--- /dev/null
+++ b/Library/Homebrew/test/utils/bottles/bottles_spec.rb
@@ -0,0 +1,80 @@
+require "utils/bottles"
+
+describe Utils::Bottles do
+ describe "#tag", :needs_macos do
+ it "returns :tiger_foo on Tiger PowerPC" do
+ allow(MacOS).to receive(:version).and_return(MacOS::Version.new("10.4"))
+ allow(Hardware::CPU).to receive(:type).and_return(:ppc)
+ allow(Hardware::CPU).to receive(:family).and_return(:foo)
+ allow(MacOS).to receive(:prefer_64_bit?).and_return(false)
+ expect(described_class.tag).to eq(:tiger_foo)
+ end
+
+ it "returns :tiger on Tiger Intel" do
+ allow(MacOS).to receive(:version).and_return(MacOS::Version.new("10.4"))
+ allow(Hardware::CPU).to receive(:type).and_return(:intel)
+ allow(MacOS).to receive(:prefer_64_bit?).and_return(false)
+ expect(described_class.tag).to eq(:tiger)
+ end
+
+ it "returns :tiger_g5_64 on Tiger PowerPC 64-bit" do
+ allow(MacOS).to receive(:version).and_return(MacOS::Version.new("10.4"))
+ allow(Hardware::CPU).to receive(:type).and_return(:ppc)
+ allow(Hardware::CPU).to receive(:family).and_return(:g5)
+ allow(MacOS).to receive(:prefer_64_bit?).and_return(true)
+ expect(described_class.tag).to eq(:tiger_g5_64)
+ end
+
+ # Note that this will probably never be used
+ it "returns :tiger_64 on Tiger Intel 64-bit" do
+ allow(MacOS).to receive(:version).and_return(MacOS::Version.new("10.4"))
+ allow(Hardware::CPU).to receive(:type).and_return(:intel)
+ allow(MacOS).to receive(:prefer_64_bit?).and_return(true)
+ expect(described_class.tag).to eq(:tiger_64)
+ end
+
+ it "returns :leopard on Leopard Intel" do
+ allow(MacOS).to receive(:version).and_return(MacOS::Version.new("10.5"))
+ allow(Hardware::CPU).to receive(:type).and_return(:intel)
+ allow(MacOS).to receive(:prefer_64_bit?).and_return(false)
+ expect(described_class.tag).to eq(:leopard)
+ end
+
+ it "returns :leopard_g5_64 on Leopard PowerPC 64-bit" do
+ allow(MacOS).to receive(:version).and_return(MacOS::Version.new("10.5"))
+ allow(Hardware::CPU).to receive(:type).and_return(:ppc)
+ allow(Hardware::CPU).to receive(:family).and_return(:g5)
+ allow(MacOS).to receive(:prefer_64_bit?).and_return(true)
+ expect(described_class.tag).to eq(:leopard_g5_64)
+ end
+
+ it "returns :leopard_64 on Leopard Intel 64-bit" do
+ allow(MacOS).to receive(:version).and_return(MacOS::Version.new("10.5"))
+ allow(Hardware::CPU).to receive(:type).and_return(:intel)
+ allow(MacOS).to receive(:prefer_64_bit?).and_return(true)
+ expect(described_class.tag).to eq(:leopard_64)
+ end
+
+ it "returns :snow_leopard_32 on Snow Leopard 32-bit" do
+ allow(MacOS).to receive(:version).and_return(MacOS::Version.new("10.6"))
+ allow(Hardware::CPU).to receive(:is_64_bit?).and_return(false)
+ expect(described_class.tag).to eq(:snow_leopard_32)
+ end
+
+ it "returns :snow_leopard on Snow Leopard 64-bit" do
+ allow(MacOS).to receive(:version).and_return(MacOS::Version.new("10.6"))
+ allow(Hardware::CPU).to receive(:is_64_bit?).and_return(true)
+ expect(described_class.tag).to eq(:snow_leopard)
+ end
+
+ it "returns :lion on Lion" do
+ allow(MacOS).to receive(:version).and_return(MacOS::Version.new("10.7"))
+ expect(described_class.tag).to eq(:lion)
+ end
+
+ it "returns :mountain_lion on Mountain Lion" do
+ allow(MacOS).to receive(:version).and_return(MacOS::Version.new("10.8"))
+ expect(described_class.tag).to eq(:mountain_lion)
+ end
+ end
+end
diff --git a/Library/Homebrew/test/utils_spec.rb b/Library/Homebrew/test/utils_spec.rb
index 040ad630b..b3fdedcb9 100644
--- a/Library/Homebrew/test/utils_spec.rb
+++ b/Library/Homebrew/test/utils_spec.rb
@@ -232,10 +232,10 @@ describe "globally-scoped helper methods" do
specify "#disk_usage_readable" do
expect(disk_usage_readable(1)).to eq("1B")
expect(disk_usage_readable(1000)).to eq("1000B")
- expect(disk_usage_readable(1024)).to eq("1K")
- expect(disk_usage_readable(1025)).to eq("1K")
- expect(disk_usage_readable(4_404_020)).to eq("4.2M")
- expect(disk_usage_readable(4_509_715_660)).to eq("4.2G")
+ expect(disk_usage_readable(1024)).to eq("1KB")
+ expect(disk_usage_readable(1025)).to eq("1KB")
+ expect(disk_usage_readable(4_404_020)).to eq("4.2MB")
+ expect(disk_usage_readable(4_509_715_660)).to eq("4.2GB")
end
describe "#number_readable" do
diff --git a/Library/Homebrew/test/version_test.rb b/Library/Homebrew/test/version_test.rb
deleted file mode 100644
index e7ffbc4f6..000000000
--- a/Library/Homebrew/test/version_test.rb
+++ /dev/null
@@ -1,8 +0,0 @@
-require "testing_env"
-
-class IntegrationCommandTestVersion < IntegrationCommandTestCase
- def test_version
- assert_match HOMEBREW_VERSION.to_s,
- cmd("--version")
- end
-end
diff --git a/Library/Homebrew/utils.rb b/Library/Homebrew/utils.rb
index 70d2787d9..56ddfd611 100644
--- a/Library/Homebrew/utils.rb
+++ b/Library/Homebrew/utils.rb
@@ -10,6 +10,7 @@ require "utils/github"
require "utils/hash"
require "utils/inreplace"
require "utils/popen"
+require "utils/svn"
require "utils/tty"
require "time"
@@ -421,13 +422,13 @@ end
def disk_usage_readable(size_in_bytes)
if size_in_bytes >= 1_073_741_824
size = size_in_bytes.to_f / 1_073_741_824
- unit = "G"
+ unit = "GB"
elsif size_in_bytes >= 1_048_576
size = size_in_bytes.to_f / 1_048_576
- unit = "M"
+ unit = "MB"
elsif size_in_bytes >= 1_024
size = size_in_bytes.to_f / 1_024
- unit = "K"
+ unit = "KB"
else
size = size_in_bytes
unit = "B"
diff --git a/Library/Homebrew/utils/git.rb b/Library/Homebrew/utils/git.rb
index dfe47f890..1b4d24894 100644
--- a/Library/Homebrew/utils/git.rb
+++ b/Library/Homebrew/utils/git.rb
@@ -40,4 +40,9 @@ module Utils
@git_path = nil
@git_version = nil
end
+
+ def self.git_remote_exists(url)
+ return true unless git_available?
+ quiet_system "git", "ls-remote", url
+ end
end
diff --git a/Library/Homebrew/utils/svn.rb b/Library/Homebrew/utils/svn.rb
new file mode 100644
index 000000000..fb49ac2e9
--- /dev/null
+++ b/Library/Homebrew/utils/svn.rb
@@ -0,0 +1,11 @@
+module Utils
+ def self.svn_available?
+ return @svn if instance_variable_defined?(:@svn)
+ @svn = quiet_system HOMEBREW_SHIMS_PATH/"scm/svn", "--version"
+ end
+
+ def self.svn_remote_exists(url)
+ return true unless svn_available?
+ quiet_system "svn", "ls", url, "--depth", "empty"
+ end
+end
diff --git a/README.md b/README.md
index 4b8b18de4..1175c65f0 100644
--- a/README.md
+++ b/README.md
@@ -40,7 +40,7 @@ This is our PGP key which is valid until May 24, 2017.
## Who Are You?
Homebrew's lead maintainer is [Mike McQuaid](https://github.com/mikemcquaid).
-Homebrew's current maintainers are [Misty De Meo](https://github.com/mistydemeo), [Andrew Janke](https://github.com/apjanke), [Tomasz Pajor](https://github.com/nijikon), [Josh Hagins](https://github.com/jawshooah), [Baptiste Fontaine](https://github.com/bfontaine), [Markus Reiter](https://github.com/reitermarkus), [ilovezfs](https://github.com/ilovezfs), [Tom Schoonjans](https://github.com/tschoonj), [Uladzislau Shablinski](https://github.com/vladshablinsky), [Tim Smith](https://github.com/tdsmith) and [Alex Dunn](https://github.com/dunn).
+Homebrew's current maintainers are [Alyssa Ross](https://github.com/alyssais), [Andrew Janke](https://github.com/apjanke), [Baptiste Fontaine](https://github.com/bfontaine), [Alex Dunn](https://github.com/dunn), [FX Coudert](https://github.com/fxcoudert), [ilovezfs](https://github.com/ilovezfs), [Josh Hagins](https://github.com/jawshooah), [JCount](https://github.com/jcount), [Misty De Meo](https://github.com/mistydemeo), [Tomasz Pajor](https://github.com/nijikon), [Markus Reiter](https://github.com/reitermarkus), [Tim Smith](https://github.com/tdsmith), [Tom Schoonjans](https://github.com/tschoonj), [Uladzislau Shablinski](https://github.com/vladshablinsky) and [William Woodruff](https://github.com/woodruffw).
Former maintainers with significant contributions include [Xu Cheng](https://github.com/xu-cheng), [Martin Afanasjew](https://github.com/UniqMartin), [Dominyk Tiller](https://github.com/DomT4), [Brett Koonce](https://github.com/asparagui), [Jack Nagel](https://github.com/jacknagel), [Adam Vandenberg](https://github.com/adamv) and Homebrew's creator: [Max Howell](https://github.com/mxcl).
@@ -73,6 +73,10 @@ Our bottles (binary packages) are hosted by [Bintray](https://bintray.com/homebr
[![Downloads by Bintray](https://bintray.com/docs/images/downloads_by_bintray_96.png)](https://bintray.com/homebrew)
+[Our website](https://brew.sh) is hosted by [Netlify](https://www.netlify.com).
+
+[![Deploys by Netlify](https://www.netlify.com/img/global/badges/netlify-color-accent.svg)](https://www.netlify.com)
+
Secure password storage and syncing provided by [1Password for Teams](https://1password.com/teams/) by [AgileBits](https://agilebits.com)
[![AgileBits](https://da36klfizjv29.cloudfront.net/assets/branding/agilebits-fcca96e9b8e815c5c48c6b3e98156cb5.png)](https://agilebits.com)
diff --git a/docs/Acceptable-Formulae.md b/docs/Acceptable-Formulae.md
index 9f4fb45db..24dd7a7c4 100644
--- a/docs/Acceptable-Formulae.md
+++ b/docs/Acceptable-Formulae.md
@@ -38,7 +38,7 @@ There are exceptions:
| emacs, vim | [Too popular to move to dupes](https://github.com/Homebrew/homebrew/pull/21594#issuecomment-21968819) |
| subversion | Originally added for 10.5, but people want the latest version |
| libcurl | Some formulae require a newer version than macOS provides |
-| openssl | macOS's openssl is deprecated & outdated. |
+| openssl | macOS's openssl is deprecated & outdated |
| libxml2 | Historically, macOS's libxml2 has been buggy |
We also maintain [a tap](https://github.com/Homebrew/homebrew-dupes) that
@@ -74,7 +74,7 @@ due to upstream changes and we can’t provide [bottles](Bottles.md) for them.
### Bindings
First check that there is not already a binding available via
[`gem`](https://rubygems.org/) or [`pip`](http://www.pip-installer.org/)
-etc..
+etc.
If not, then put bindings in the formula they bind to. This is more
useful to people. Just install the stuff! Having to faff around with
diff --git a/docs/Brew-Test-Bot-For-Core-Contributors.md b/docs/Brew-Test-Bot-For-Core-Contributors.md
index f4c9a0ec6..3ed86c706 100644
--- a/docs/Brew-Test-Bot-For-Core-Contributors.md
+++ b/docs/Brew-Test-Bot-For-Core-Contributors.md
@@ -4,13 +4,13 @@ If a build has run and passed on `brew test-bot` then it can be used to quickly
There are two types of Jenkins jobs you will interact with:
-## [Homebrew Pull Requests](https://bot.brew.sh/job/Homebrew%20Core%20Pull%20Requests/)
+## [Homebrew Core Pull Requests](https://bot.brew.sh/job/Homebrew%20Core/)
This job automatically builds any pull requests submitted to Homebrew/homebrew-core. On success or failure it updates the pull request status (see more details on the [main Brew Test Bot documentation page](Brew-Test-Bot.md)). On a successful build it automatically uploads bottles.
## [Homebrew Testing](https://bot.brew.sh/job/Homebrew%20Testing/)
-This job is manually triggered to run [`brew test-bot`](https://github.com/Homebrew/brew/blob/master/Library/Homebrew/dev-cmd/test-bot.rb) with user-specified parameters. On a successful build it automatically uploads bottles.
+This job is manually triggered to run [`brew test-bot`](https://github.com/Homebrew/homebrew-test-bot/blob/master/cmd/brew-test-bot.rb) with user-specified parameters. On a successful build it automatically uploads bottles.
-You can manually start this job with parameters to run [`brew test-bot`](https://github.com/Homebrew/brew/blob/master/Library/Homebrew/dev-cmd/test-bot.rb) with the same parameters. It's often useful to pass a pull request URL, a commit URL, a commit SHA-1 and/or formula names to have `brew-test-bot` test them, report the results and produce bottles.
+You can manually start this job with parameters to run [`brew test-bot`](https://github.com/Homebrew/homebrew-test-bot/blob/master/cmd/brew-test-bot.rb) with the same parameters. It's often useful to pass a pull request URL, a commit URL, a commit SHA-1 and/or formula names to have `brew-test-bot` test them, report the results and produce bottles.
## Bottling
To pull and bottle a pull request with `brew pull`:
diff --git a/docs/Brew-Test-Bot.md b/docs/Brew-Test-Bot.md
index db39327fa..484fa3275 100644
--- a/docs/Brew-Test-Bot.md
+++ b/docs/Brew-Test-Bot.md
@@ -3,9 +3,9 @@
`brew test-bot` is the name for the automated review and testing system funded
by [our Kickstarter in 2013](https://www.kickstarter.com/projects/homebrew/brew-test-bot).
-It comprises of four Mac Minis running in a data centre in England which host
+It comprises four Mac Minis running in a data centre in England which host
[a Jenkins instance at https://bot.brew.sh](https://bot.brew.sh) and run the
-[`brew test-bot.rb`](https://github.com/Homebrew/brew/blob/master/Library/Homebrew/dev-cmd/test-bot.rb)
+[`brew test-bot.rb`](https://github.com/Homebrew/homebrew-test-bot/blob/master/cmd/brew-test-bot.rb)
Ruby script to perform automated testing of commits to the master branch, pull
requests and custom builds requested by maintainers.
@@ -15,7 +15,7 @@ The bot automatically builds pull requests and updates their status depending
on the result of the job.
For example, a job which has been queued but not yet started will have a
-section in the pull-request that looks like this:
+section in the pull request that looks like this:
![Triggered Pull Request](images/brew-test-bot-triggered-pr.png)
diff --git a/docs/Common-Issues.md b/docs/Common-Issues.md
index 8da622ab4..e8b48751d 100644
--- a/docs/Common-Issues.md
+++ b/docs/Common-Issues.md
@@ -7,8 +7,7 @@ You need to have the Xcode Command Line Utilities installed (and updated): run `
(In OS X prior to 10.9, the "Command Line Tools" package can alternatively be installed from within Xcode. `⌘,` will get you to preferences. Visit the "Downloads" tab and hit the install button next to "Command Line Tools".)
### Ruby `bad interpreter: /usr/bin/ruby^M: no such file or directory`
-You cloned with git, and your git configuration is set to use Windows line endings. See this page: https://help.github.com/articles/dealing-with-line-endings
-
+You cloned with git, and your git configuration is set to use Windows line endings. See this page: <https://help.github.com/articles/dealing-with-line-endings>
### Ruby `bad interpreter: /usr/bin/ruby`
You don't have a `/usr/bin/ruby` or it is not executable. It's not recommended to let this persist, you'd be surprised how many .apps, tools and scripts expect your macOS provided files and directories to be *unmodified* since macOS was installed.
diff --git a/docs/External-Commands.md b/docs/External-Commands.md
index 59622bd3a..e2dafdce8 100644
--- a/docs/External-Commands.md
+++ b/docs/External-Commands.md
@@ -47,15 +47,15 @@ brew tap youtux/livecheck
```
### brew-gem
-Install any gem package into a self-contained Homebrew cellar location: [https://github.com/sportngin/brew-gem](https://github.com/sportngin/brew-gem).
+Install any gem package into a self-contained Homebrew cellar location: <https://github.com/sportngin/brew-gem>
Note this can also be installed with `brew install brew-gem`.
### brew-growl
-Get Growl notifications for Homebrew https://github.com/secondplanet/brew-growl
+Get Growl notifications for Homebrew: <https://github.com/secondplanet/homebrew-growl>
### brew-services
-Simple support to start formulae using launchctl, has out of the box support for any formula which defines `startup_plist` (e.g. mysql, postgres, redis u.v.m.): [https://github.com/Homebrew/homebrew-services](https://github.com/Homebrew/homebrew-services)
+Simple support to start formulae using launchctl, has out of the box support for any formula which defines `startup_plist` (e.g. mysql, postgres, redis u.v.m.): <https://github.com/Homebrew/homebrew-services>
Install using:
```sh
diff --git a/docs/FAQ.md b/docs/FAQ.md
index 7a32cf926..7527289dc 100644
--- a/docs/FAQ.md
+++ b/docs/FAQ.md
@@ -81,13 +81,12 @@ including how to set this across reboots. If you’re pre-Mountain Lion,
alternative](https://developer.apple.com/legacy/library/qa/qa1067/_index.html).
## How do I contribute to Homebrew?
-Read [CONTRIBUTING.md](/CONTRIBUTING.md).
+Read [CONTRIBUTING.md](https://github.com/Homebrew/brew/blob/master/CONTRIBUTING.md).
## Why do you compile everything?
Homebrew provides pre-compiled versions for many formulae. These
pre-compiled versions are referred to as **bottles** and are available
-at:
-[https://bintray.com/homebrew/bottles](https://bintray.com/homebrew/bottles).
+at <https://bintray.com/homebrew/bottles>.
If available, bottled binaries will be used by default except under the
following conditions:
diff --git a/docs/Formula-Cookbook.md b/docs/Formula-Cookbook.md
index c87424c7e..6b4678f90 100644
--- a/docs/Formula-Cookbook.md
+++ b/docs/Formula-Cookbook.md
@@ -288,13 +288,13 @@ Name the formula like the project markets the product. So it’s `pkg-config`, n
The only exception is stuff like “Apache Ant”. Apache sticks “Apache” in front of everything, but we use the formula name `ant`. We only include the prefix in cases like *GNUplot* (because it’s part of the name) and *GNU Go* (because everyone calls it “GNU go”—nobody just calls it “Go”). The word “Go” is too common and there are too many implementations of it.
-If you’re not sure about the name check the homepage, and check the Wikipedia page and [what Debian call it](https://www.debian.org/distrib/packages).
+If you’re not sure about the name check the homepage, and check the Wikipedia page and [what Debian calls it](https://www.debian.org/distrib/packages).
-Where Homebrew already has a formula called `foo` we typically do not accept requests to replace that formula with something else also named `foo`. This is to avoid both confusing and surprising users’ expectation.
+Where Homebrew already has a formula called `foo` we typically do not accept requests to replace that formula with something else also named `foo`. This is to avoid both confusing and surprising users’ expectations.
When two formulae share an upstream name, e.g. [`AESCrypt`](https://github.com/Homebrew/homebrew-core/blob/master/Formula/aescrypt.rb) and [`AESCrypt`](https://github.com/Homebrew/homebrew-core/blob/master/Formula/aescrypt-packetizer.rb) the newer formula must typically adapt the name to avoid conflict with the current formula.
-If you’re *still* not sure, just commit. We’ll apply some arbitrary rule and make a decision :wink:.
+If you’re *still* not sure, just commit. We’ll apply some arbitrary rule and make a decision 😉.
When importing classes, Homebrew will require the formula and then create an instance of the class. It does this by assuming the formula name can be directly converted to the class name using a `regexp`. The rules are simple:
diff --git a/docs/Gems,-Eggs-and-Perl-Modules.md b/docs/Gems,-Eggs-and-Perl-Modules.md
index 770d770f6..f86124f66 100644
--- a/docs/Gems,-Eggs-and-Perl-Modules.md
+++ b/docs/Gems,-Eggs-and-Perl-Modules.md
@@ -81,7 +81,7 @@ or use this:
**However all versions of RubyGems before 1.3.6 are buggy** and ignore
the above setting. Sadly a fresh install of Snow Leopard comes with
-1.3.5. Currently the only known way to get round this is to upgrade
+1.3.5. Currently the only known way to get around this is to upgrade
rubygems as root:
`sudo gem update --system`
diff --git a/docs/Homebrew-and-Python.md b/docs/Homebrew-and-Python.md
index e2f59c322..2e9e643b5 100644
--- a/docs/Homebrew-and-Python.md
+++ b/docs/Homebrew-and-Python.md
@@ -58,7 +58,7 @@ Homebrew builds bindings against the first `python` (and `python-config`) in you
**Warning!** Python may crash (see [Common Issues](Common-Issues.md)) if you `import <module>` from a brewed Python if you ran `brew install <formula_with_python_bindings>` against the system Python. If you decide to switch to the brewed Python, then reinstall all formulae with python bindings (e.g. `pyside`, `wxwidgets`, `pygtk`, `pygobject`, `opencv`, `vtk` and `boost-python`).
## Policy for non-brewed Python bindings
-These should be installed via `pip install <x>`. To discover, you can use `pip search` or <https://pypi.python.org/pypi>. (**Note:** System Python does not provide `pip`. Follow the instructions at https://pip.readthedocs.org/en/stable/installing/#install-pip to install it for your system Python if you would like it.)
+These should be installed via `pip install <x>`. To discover, you can use `pip search` or <https://pypi.python.org/pypi>. (**Note:** System Python does not provide `pip`. Follow the instructions at <https://pip.readthedocs.io/en/stable/installing/#install-pip> to install it for your system Python if you would like it.)
## Brewed Python modules
diff --git a/docs/How-To-Open-a-Homebrew-Pull-Request.md b/docs/How-To-Open-a-Homebrew-Pull-Request.md
index ef6091e2c..104fc2829 100644
--- a/docs/How-To-Open-a-Homebrew-Pull-Request.md
+++ b/docs/How-To-Open-a-Homebrew-Pull-Request.md
@@ -25,7 +25,7 @@ Depending on the change you want to make, you need to send the pull request to t
3. Add your pushable forked repository with `git remote add <YOUR_USERNAME> https://github.com/<YOUR_USERNAME>/homebrew-core.git`
* `<YOUR_USERNAME>` is your GitHub username, not your local machine username.
-For formulae in central taps other than `homebrew/core`, such as `homebrew/science` or `homebrew/games`, substitute that tap's name for `homebrew/core` in each step, and alter the GitHub repository URLs as necessary.
+For formulae in central taps other than `homebrew/core`, such as `homebrew/science` or `homebrew/nginx`, substitute that tap's name for `homebrew/core` in each step, and alter the GitHub repository URLs as necessary.
## Create your pull request from a new branch
@@ -43,7 +43,7 @@ To make a new branch and submit it for review, create a GitHub pull request with
4. `brew audit --strict <CHANGED_FORMULA>`
6. Make a separate commit for each changed formula with `git add` and `git commit`.
7. Upload your new commits to the branch on your fork with `git push --set-upstream <YOUR_USERNAME> <YOUR_BRANCH_NAME>`.
-8. Go to the relevant repository (e.g. https://github.com/Homebrew/brew, https://github.com/Homebrew/homebrew-core, etc.) and create a pull request to request review and merging of the commits in your pushed branch. Explain why the change is needed and, if fixing a bug, how to reproduce the bug. Make sure you have done each step in the checklist that appears in your new PR.
+8. Go to the relevant repository (e.g. <https://github.com/Homebrew/brew>, <https://github.com/Homebrew/homebrew-core>, etc.) and create a pull request to request review and merging of the commits in your pushed branch. Explain why the change is needed and, if fixing a bug, how to reproduce the bug. Make sure you have done each step in the checklist that appears in your new PR.
* Please note that our preferred commit message format for simple version updates is "`<FORMULA_NAME> <NEW_VERSION>`", e.g. "`source-highlight 3.1.8`". `devel` version updates should have the commit message suffixed with `(devel)`, e.g. "`nginx 1.9.1 (devel)`". If updating both stable and `devel`, the format should be a concatenation of these two forms, e.g. "`x264 r2699, r2705 (devel)`".
9. Await feedback or a merge from Homebrew's maintainers. We typically respond to all PRs within a couple days, but it may take up to a week, depending on the maintainers' workload.
10. Thank you!
diff --git a/docs/Interesting-Taps-&-Forks.md b/docs/Interesting-Taps-&-Forks.md
index a5c609441..de9b8809e 100644
--- a/docs/Interesting-Taps-&-Forks.md
+++ b/docs/Interesting-Taps-&-Forks.md
@@ -1,7 +1,7 @@
# Interesting Taps & Forks
A Tap is homebrew-speak for a git repository containing extra formulae.
-Homebrew has the capability to add (and remove) multiple taps to your local installation with the `brew tap` and `brew untap` command. Type `man brew` in your Terminal. The main repository https://github.com/Homebrew/homebrew-core, often called `homebrew/core`, is always built-in.
+Homebrew has the capability to add (and remove) multiple taps to your local installation with the `brew tap` and `brew untap` command. Type `man brew` in your Terminal. The main repository <https://github.com/Homebrew/homebrew-core>, often called `homebrew/core`, is always built-in.
## Main Taps
diff --git a/docs/Node-for-Formula-Authors.md b/docs/Node-for-Formula-Authors.md
index c78668a58..83516da93 100644
--- a/docs/Node-for-Formula-Authors.md
+++ b/docs/Node-for-Formula-Authors.md
@@ -14,9 +14,9 @@ where `libexec` is the destination prefix (usually the `libexec` variable).
# Download URL
-If the Node module is also available on the npm registry, we prefer npm hosted release tarballs over GitHub (or elsewhere) hosted source tarballs. The advantages of these tarballs are that they doesn't include the files from the `.npmignore` (such as tests) resulting in a smaller download size and that a possibly transpilation step is already done (e.g. no need to compile CoffeeScript files as a build step).
+If the Node module is also available on the npm registry, we prefer npm hosted release tarballs over GitHub (or elsewhere) hosted source tarballs. The advantages of these tarballs are that they don't include the files from the `.npmignore` (such as tests) resulting in a smaller download size and that any possible transpilation step is already done (e.g. no need to compile CoffeeScript files as a build step).
-The npm registry URLs have usually the format of:
+The npm registry URLs usually have the format of:
```
https://registry.npmjs.org/<name>/-/<name>-<version>.tgz
@@ -26,33 +26,33 @@ Alternatively you could curl the JSON at `https://registry.npmjs.org/<name>` and
# Dependencies
-Node modules, which are compatible with the latest Node version should declare a dependencies on the `node` formula.
+Node modules which are compatible with the latest Node version should declare a dependency on the `node` formula.
```ruby
depends_on "node"
```
-If your formula requires to be executed with an older Node version you must vendor this older Node version as done in the [`kibana` formula](https://github.com/Homebrew/homebrew-core/blob/c6202f91a129e2f994d904f299a308cc6fbd58e5/Formula/kibana.rb).
+If your formula requires being executed with an older Node version you must vendor this older Node version as done in the [`kibana` formula](https://github.com/Homebrew/homebrew-core/blob/c6202f91a129e2f994d904f299a308cc6fbd58e5/Formula/kibana.rb).
### Special requirements for native addons
-If your node module is a native addon or has a native addon somewhere in it's dependency tree you have to declare an additional dependency. Since the compilation of the native addon results in a invocation of `node-gyp` we need an additional build time dependency on `:python` (because gyp depends on Python 2.7).
+If your node module is a native addon or has a native addon somewhere in its dependency tree you have to declare an additional dependency. Since the compilation of the native addon results in a invocation of `node-gyp` we need an additional build time dependency on `:python` (because gyp depends on Python 2.7).
```ruby
depends_on :python => :build
```
-Please also note, that such a formula would only be compatible with the same Node major version it originally was compiled with. This means that we need to revision every formula with a Node native addon with every major version bump of the `node` formula. To make sure we don't overlook your formula on a Node major version bump, write a meaningful test which would fail in such a case (invoked with an ABI incompatible Node version).
+Please also note that such a formula would only be compatible with the same Node major version it originally was compiled with. This means that we need to revision every formula with a Node native addon with every major version bump of the `node` formula. To make sure we don't overlook your formula on a Node major version bump, write a meaningful test which would fail in such a case (invoked with an ABI incompatible Node version).
# Installation
Node modules should be installed to `libexec`. This prevents the Node modules from contaminating the global `node_modules`, which is important so that npm doesn't try to manage Homebrew-installed Node modules.
-In the following we distinguish between 2 type of Node module using formulae:
+In the following we distinguish between two types of Node modules using formulae:
* formulae for standard Node modules compatible with npm's global module format which should use [`std_npm_install_args`](#installing-global-style-modules-with-std_npm_install_args-to-libexec) (like [`azure-cli`](https://github.com/Homebrew/homebrew-core/blob/d93fe9ba3bcc9071b699c8da4e7d733518d3337e/Formula/azure-cli.rb) or [`autocode`](https://github.com/Homebrew/homebrew-core/blob/1a670a6269e1e07f86683c2d164977c9bd8a3fb6/Formula/autocode.rb)) and
-* formulae were the `npm install` step is only one of multiple not exclusively Node related install steps (not compatible with npm's global module format) which have to use [`local_npm_install_args`](#installing-module-dependencies-locally-with-local_npm_install_args) (like [`elixirscript`](https://github.com/Homebrew/homebrew-core/blob/ec1e40d37e81af63122a354f0101c377f6a4e66d/Formula/elixirscript.rb) or [`kibana`](https://github.com/Homebrew/homebrew-core/blob/c6202f91a129e2f994d904f299a308cc6fbd58e5/Formula/kibana.rb))
+* formulae where the `npm install` step is only one of multiple not exclusively Node related install steps (not compatible with npm's global module format) which have to use [`local_npm_install_args`](#installing-module-dependencies-locally-with-local_npm_install_args) (like [`elixirscript`](https://github.com/Homebrew/homebrew-core/blob/ec1e40d37e81af63122a354f0101c377f6a4e66d/Formula/elixirscript.rb) or [`kibana`](https://github.com/Homebrew/homebrew-core/blob/c6202f91a129e2f994d904f299a308cc6fbd58e5/Formula/kibana.rb))
-Both methods have in common, that they are setting the correct environment for using npm inside Homebrew up and returning the arguments for invoking `npm install` for their specific use cases. This includes fixing an important edge case with the npm cache (Caused by Homebrew's redirection of `$HOME` during the build and test process) by using our own custom `npm_cache` inside `HOMEBREW_CACHE`, which would otherwise result in very long build times and high disk space usage.
+Both methods have in common that they are setting the correct environment for using npm inside Homebrew and are returning the arguments for invoking `npm install` for their specific use cases. This includes fixing an important edge case with the npm cache (caused by Homebrew's redirection of `$HOME` during the build and test process) by using our own custom `npm_cache` inside `HOMEBREW_CACHE`, which would otherwise result in very long build times and high disk space usage.
To use them you have to require the Node language module at the beginning of your formula file with:
@@ -62,13 +62,13 @@ require "language/node"
### Installing global style modules with `std_npm_install_args` to libexec
-In your formula's `install` method, simply cd to the top level of your Node module if necessary and than use `system` to invoke `npm install` with `Language::Node.std_npm_install_args` like:
+In your formula's `install` method, simply cd to the top level of your Node module if necessary and then use `system` to invoke `npm install` with `Language::Node.std_npm_install_args` like:
```ruby
system "npm", "install", *Language::Node.std_npm_install_args(libexec)
```
-This will install your Node module in npm's global module style with a custom prefix to `libexec`. All your modules executable will be automatically resolved by npm into `libexec/"bin"` for you, which is not symlinked into Homebrew's prefix. We need to make sure these are installed. Do this with we need to symlink all executables to `bin` with:
+This will install your Node module in npm's global module style with a custom prefix to `libexec`. All your modules' executables will be automatically resolved by npm into `libexec/"bin"` for you, which is not symlinked into Homebrew's prefix. We need to make sure these are installed. To do this we need to symlink all executables to `bin` with:
```ruby
bin.install_symlink Dir["#{libexec}/bin/*"]
@@ -76,13 +76,13 @@ bin.install_symlink Dir["#{libexec}/bin/*"]
### Installing module dependencies locally with `local_npm_install_args`
-In your formula's `install` method, do any installation steps which need to be done before the `npm install` step and than cd to the top level of the included Node module. Then, use `system` with `Language::Node.local_npm_install_args` to invoke `npm install` like:
+In your formula's `install` method, do any installation steps which need to be done before the `npm install` step and then cd to the top level of the included Node module. Then, use `system` with `Language::Node.local_npm_install_args` to invoke `npm install` like:
```ruby
system "npm", "install", *Language::Node.local_npm_install_args
```
-This will install all of your Node modules dependencies to your local build path. You can now continue with your build steps and take care of the installation into the Homebrew `prefix` by your own, following the [general Homebrew formula instructions](https://github.com/Homebrew/brew/blob/master/docs/Formula-Cookbook.md).
+This will install all of your Node modules dependencies to your local build path. You can now continue with your build steps and take care of the installation into the Homebrew `prefix` on your own, following the [general Homebrew formula instructions](https://github.com/Homebrew/brew/blob/master/docs/Formula-Cookbook.md).
# Example
diff --git a/docs/Prose-Style-Guidelines.md b/docs/Prose-Style-Guidelines.md
index 1d8e2b0fc..7da21d355 100644
--- a/docs/Prose-Style-Guidelines.md
+++ b/docs/Prose-Style-Guidelines.md
@@ -44,8 +44,8 @@ We prefer:
* More generally, parallel list item structure
* Capitalize all list items if you want, even if they're not complete sentences; just be consistent within each list, and preferably, throughout the whole page
* Use a subordinate list item instead of dropping a multi-sentence paragraph-long item into a list of sentence fragments
-* Prefer Markdown over other markup formats unless their specific features are needed.
-* GitHub flavored Markdown. GitHub's implementation is the standard, period.
+* Prefer Markdown over other markup formats unless their specific features are needed
+ * GitHub Flavored Markdown. GitHub's implementation is the standard, period.
### Typographical conventions
diff --git a/docs/Python-for-Formula-Authors.md b/docs/Python-for-Formula-Authors.md
index 93830a6c7..0867e8dd8 100644
--- a/docs/Python-for-Formula-Authors.md
+++ b/docs/Python-for-Formula-Authors.md
@@ -4,7 +4,7 @@ This document explains how to successfully use Python in a Homebrew formula.
Homebrew draws a distinction between Python **applications** and Python **libraries**. The difference is that users generally do not care that applications are written in Python; it is unusual that a user would expect to be able to `import foo` after installing an application. Examples of applications are `ansible` and `jrnl`.
-Python libraries exist to be imported from other Python modules; they are often dependencies of Python applications. They are usually no more than incidentally useful from a Terminal.app command line. Examples of libraries are `py2cairo` and the bindings that are installed by `protobuf --with-python`.
+Python libraries exist to be imported by other Python modules; they are often dependencies of Python applications. They are usually no more than incidentally useful from a Terminal.app command line. Examples of libraries are `py2cairo` and the bindings that are installed by `protobuf --with-python`.
Bindings are a special case of libraries that allow Python code to interact with a library or application implemented in another language.
@@ -22,7 +22,7 @@ where `prefix` is the destination prefix (usually `libexec` or `prefix`).
# Python module dependencies
-In general, applications should unconditionally bundle all of their dependencies and libraries should install any unsatisfied dependencies; these strategies are discussed in depth in the following sections.
+In general, applications should unconditionally bundle all of their dependencies and libraries and should install any unsatisfied dependencies; these strategies are discussed in depth in the following sections.
In the rare instance that this proves impractical, you can specify a Python module as an external dependency using the syntax:
@@ -49,9 +49,9 @@ Applications that are compatible with Python 2 **should** use the Apple-provided
```ruby
depends_on :python if MacOS.version <= :snow_leopard
```
-No explicit Python dependency is needed on recent OS versions since /usr/bin is always in `PATH` for Homebrew formulæ; on Leopard and older, the python in `PATH` is used if it's at least version 2.7, or else Homebrew's python is installed.
+No explicit Python dependency is needed on recent OS versions since /usr/bin is always in `PATH` for Homebrew formulae; on Leopard and older, the python in `PATH` is used if it's at least version 2.7, or else Homebrew's python is installed.
-Formulæ for apps that require Python 3 **should** declare an unconditional dependency on `:python3`, which will cause the formula to use the first python3 discovered in `PATH` at install time (or install Homebrew's if there isn't one). These apps **must** work with the current Homebrew python3 formula.
+Formulae for apps that require Python 3 **should** declare an unconditional dependency on `:python3`, which will cause the formula to use the first python3 discovered in `PATH` at install time (or install Homebrew's if there isn't one). These apps **must** work with the current Homebrew python3 formula.
## Installing
@@ -183,7 +183,7 @@ Sometimes we have to `inreplace` a `Makefile` to use our prefix for the python b
Libraries **should** declare a dependency on `:python` or `:python3` as appropriate, which will respectively cause the formula to use the first python or python3 discovered in `PATH` at install time. If a library supports both Python 2.x and Python 3.x, the `:python` dependency **should** be `:recommended` (i.e. built by default) and the :python3 dependency should be `:optional`. Python 2.x libraries **must** function when they are installed against either the system Python or Homebrew Python.
-Formulæ that declare a dependency on `:python` will always be bottled against Homebrew's python, since we cannot in general build binary packages that can be imported from both Pythons. Users can add `--build-from-source` after `brew install` to compile against whichever python is in `PATH`.
+Formulae that declare a dependency on `:python` will always be bottled against Homebrew's python, since we cannot in general build binary packages that can be imported from both Pythons. Users can add `--build-from-source` after `brew install` to compile against whichever python is in `PATH`.
## Installing
@@ -213,7 +213,7 @@ Distribute (not to be confused with distutils) is an obsolete fork of setuptools
## What is `--single-version-externally-managed`?
-`--single-version-externally-managed` ("SVEM") is a setuptools-only [argument to setup.py install](https://pythonhosted.org/setuptools/setuptools.html#install-run-easy-install-or-old-style-installation). The primary effect of SVEM is to use distutils to perform the install instead of using setuptools' `easy_install`.
+`--single-version-externally-managed` ("SVEM") is a setuptools-only [argument to setup.py install](http://setuptools.readthedocs.io/en/latest/setuptools.html?#install-run-easy-install-or-old-style-installation). The primary effect of SVEM is to use distutils to perform the install instead of using setuptools' `easy_install`.
`easy_install` does a few things that we need to avoid:
diff --git a/docs/Querying-Brew.md b/docs/Querying-Brew.md
index 6d37cb588..c5a2d9aeb 100644
--- a/docs/Querying-Brew.md
+++ b/docs/Querying-Brew.md
@@ -31,9 +31,9 @@ The schema itself is not currently documented outside of the code that generates
## Examples
-_The top-level element of the JSON is always an array, so the `map` operator is used to act on the data._
+_The top-level element of the JSON output is always an array, so the `map` operator is used to act on the data._
-### Prety-print a single formula's info
+### Pretty-print a single formula's info
`brew info --json=v1 tig | jq .`
@@ -63,6 +63,6 @@ To find the names of normal (not keg-only) formulae that are installed, but not
## Concluding remarks
-Using the JSON output, queries can be made against Homebrew with less risk of being broken due to Homebrew code changes, and without needing to understand Homebrew's ruby internals.
+Using the JSON output, queries can be made against Homebrew with less risk of being broken due to Homebrew code changes, and without needing to understand Homebrew's Ruby internals.
-If the JSON does not provide some information that it ought to, please submit request, preferably with a patch to add the desired information.
+If the JSON output does not provide some information that it ought to, please submit a request, preferably with a patch to add the desired information.
diff --git a/docs/Tips-N'-Tricks.md b/docs/Tips-N'-Tricks.md
index 8f67c9ca8..e6e18ca9e 100644
--- a/docs/Tips-N'-Tricks.md
+++ b/docs/Tips-N'-Tricks.md
@@ -5,7 +5,7 @@
The supported method of installing specific versions of
some formulae is to see if there is a versions formula like e.g. `gcc@6` available. If the version you’re looking for isn’t available, consider [opening a pull request](How-To-Open-a-Homebrew-Pull-Request.md)!
-### Installing directly from pull-requests
+### Installing directly from pull requests
You can [browse pull requests](https://github.com/Homebrew/homebrew-core/pulls)
and install through the direct link. For example Python 3.3.0 pull request [Homebrew/homebrew#15199](https://github.com/Homebrew/homebrew/pull/15199)
diff --git a/docs/Versions.md b/docs/Versions.md
index bd3ef8a5f..6c6438144 100644
--- a/docs/Versions.md
+++ b/docs/Versions.md
@@ -1,6 +1,6 @@
# Versions
-Now that [Homebrew/versions](https://github.com/homebrew/homebrew-versions) has been deprecated [Homebrew/core](https://github.com/homebrew/homebrew-core) supports multiple versions of formulae with a new naming format.
+Now that [Homebrew/versions](https://github.com/homebrew/homebrew-versions) has been deprecated, [Homebrew/core](https://github.com/homebrew/homebrew-core) supports multiple versions of formulae with a new naming format.
In [Homebrew/versions](https://github.com/homebrew/homebrew-versions) the formula for GCC 6 was named `gcc6.rb` and began `class Gcc6 < Formula`. In [Homebrew/core](https://github.com/homebrew/homebrew-core) this same formula is named `gcc@6.rb` and begins `class GccAT6 < Formula`.
diff --git a/docs/brew-tap.md b/docs/brew-tap.md
index 15f8c7936..cfa0870d8 100644
--- a/docs/brew-tap.md
+++ b/docs/brew-tap.md
@@ -73,7 +73,7 @@ If you need a formula to be installed from a particular tap, you can use fully
qualified names to refer to them.
For example, you can create a tap for an alternative `vim` formula. Without
-pinning it, the behavior will be
+pinning it, the behaviour will be
```bash
brew install vim # installs from homebrew/core
diff --git a/docs/brew.1.html b/docs/brew.1.html
index e8b914281..ff2d6105c 100644
--- a/docs/brew.1.html
+++ b/docs/brew.1.html
@@ -25,7 +25,7 @@ didn't include with macOS.</p>
<dt><code>uninstall</code> <var>formula</var></dt><dd><p>Uninstall <var>formula</var>.</p></dd>
<dt class="flush"><code>update</code></dt><dd><p>Fetch the newest version of Homebrew from GitHub using <code>git</code>(1).</p></dd>
<dt class="flush"><code>list</code></dt><dd><p>List all installed formulae.</p></dd>
-<dt><code>search</code> <var>text</var>|<code>/</code><var>text</var><code>/</code></dt><dd><p>Perform a substring search of formula names for <var>text</var>. If <var>text</var> is
+<dt><code>search</code> (<var>text</var>|<code>/</code><var>text</var><code>/</code>)</dt><dd><p>Perform a substring search of formula names for <var>text</var>. If <var>text</var> is
surrounded with slashes, then it is interpreted as a regular expression.
The search for <var>text</var> is extended online to some popular taps.
If no search term is given, all locally available formulae are listed.</p></dd>
@@ -48,7 +48,7 @@ cellar. In addition, old downloads from the Homebrew download-cache are deleted.
<p>If <code>--dry-run</code> or <code>-n</code> is passed, show what would be removed, but do not
actually remove anything.</p>
-<p>If <code>-s</code> is passed, scrubs the cache, removing downloads for even the latest
+<p>If <code>-s</code> 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: <code>rm -rf $(brew --cache)</code></p></dd>
<dt><code>command</code> <var>cmd</var></dt><dd><p>Display the path to the file which is used when invoking <code>brew</code> <var>cmd</var>.</p></dd>
@@ -93,10 +93,9 @@ dependencies of that formula.</p>
<p>The <var>filters</var> placeholder is any combination of options <code>--include-build</code>,
<code>--include-optional</code>, and <code>--skip-recommended</code> as documented above.</p></dd>
<dt><code>desc</code> <var>formula</var></dt><dd><p>Display <var>formula</var>'s name and one-line description.</p></dd>
-<dt><code>desc</code> [<code>-s</code>|<code>-n</code>|<code>-d</code>] <var>pattern</var></dt><dd><p>Search both name and description (<code>-s</code>), just the names (<code>-n</code>), or just the
-descriptions (<code>-d</code>) for <code>&lt;pattern></code>. <code>&lt;pattern></code> 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
+<dt><code>desc</code> [<code>-s</code>|<code>-n</code>|<code>-d</code>] (<var>text</var>|<code>/</code><var>text</var><code>/</code>)</dt><dd><p>Search both name and description (<code>-s</code>), just the names (<code>-n</code>), or just the
+descriptions (<code>-d</code>) for <var>text</var>. If <var>text</var> 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.</p></dd>
<dt><code>diy</code> [<code>--name=</code><var>name</var>] [<code>--version=</code><var>version</var>]</dt><dd><p>Automatically determine the installation prefix for non-Homebrew software.</p>
@@ -144,14 +143,14 @@ GitHub repository as well as creating the Gist.</p>
<dt><code>info</code> <var>formula</var></dt><dd><p>Display information about <var>formula</var>.</p></dd>
<dt><code>info</code> <code>--github</code> <var>formula</var></dt><dd><p>Open a browser to the GitHub History page for formula <var>formula</var>.</p>
-<p>To view formula history locally: <code>brew log -p &lt;formula></code>.</p></dd>
+<p>To view formula history locally: <code>brew log -p &lt;formula></code></p></dd>
<dt><code>info</code> <code>--json=</code><var>version</var> (<code>--all</code>|<code>--installed</code>|<var>formulae</var>)</dt><dd><p>Print a JSON representation of <var>formulae</var>. Currently the only accepted value
for <var>version</var> is <code>v1</code>.</p>
<p>Pass <code>--all</code> to get information on all formulae, or <code>--installed</code> to get
information on all installed formulae.</p>
-<p>See the docs for examples of using the JSON:
+<p>See the docs for examples of using the JSON output:
<a href="http://docs.brew.sh/Querying-Brew.html" data-bare-link="true">http://docs.brew.sh/Querying-Brew.html</a></p></dd>
<dt><code>install</code> [<code>--debug</code>] [<code>--env=</code><var>std</var>|<var>super</var>] [<code>--ignore-dependencies</code>] [<code>--only-dependencies</code>] [<code>--cc=</code><var>compiler</var>] [<code>--build-from-source</code>] [<code>--devel</code>|<code>--HEAD</code>] [<code>--keep-tmp</code>] <var>formula</var></dt><dd><p>Install <var>formula</var>.</p>
@@ -265,7 +264,7 @@ spaces.</p>
<p>If <code>--all</code> is passed, show options for all formulae.</p>
<p>If <code>--installed</code> is passed, show options for all installed formulae.</p></dd>
-<dt><code>outdated</code> [<code>--quiet</code>|<code>--verbose</code>|<code>--json=v1</code>] [<code>--fetch-HEAD</code>]</dt><dd><p>Show formulae that have an updated version available.</p>
+<dt><code>outdated</code> [<code>--quiet</code>|<code>--verbose</code>|<code>--json=</code><var>version</var>] [<code>--fetch-HEAD</code>]</dt><dd><p>Show formulae that have an updated version available.</p>
<p>By default, version information is displayed in interactive shells, and
suppressed otherwise.</p>
@@ -295,7 +294,7 @@ actually remove anything.</p></dd>
<dt><code>reinstall</code> <var>formula</var></dt><dd><p>Uninstall and then install <var>formula</var>.</p></dd>
<dt><code>search</code>, <code>-S</code></dt><dd><p>Display all locally available formulae for brewing (including tapped ones).
No online search is performed if called without arguments.</p></dd>
-<dt><code>search</code> [<code>--desc</code>] <var>text</var>|<code>/</code><var>text</var><code>/</code></dt><dd><p>Perform a substring search of formula names for <var>text</var>. If <var>text</var> is
+<dt><code>search</code> [<code>--desc</code>] (<var>text</var>|<code>/</code><var>text</var><code>/</code>)</dt><dd><p>Perform a substring search of formula names for <var>text</var>. If <var>text</var> is
surrounded with slashes, then it is interpreted as a regular expression.
The search for <var>text</var> is extended online to some popular taps.</p>
@@ -353,7 +352,7 @@ for <var>version</var> is <code>v1</code>.</p>
<p>Pass <code>--installed</code> to get information on installed taps.</p>
-<p>See the docs for examples of using the JSON:
+<p>See the docs for examples of using the JSON output:
<a href="http://docs.brew.sh/Querying-Brew.html" data-bare-link="true">http://docs.brew.sh/Querying-Brew.html</a></p></dd>
<dt><code>tap-pin</code> <var>tap</var></dt><dd><p>Pin <var>tap</var>, prioritizing its formulae over core when formula names are supplied
by the user. See also <code>tap-unpin</code>.</p></dd>
@@ -367,7 +366,7 @@ installed, delete all installed versions.</p>
formulae depending on <var>formula</var> would still be installed.</p></dd>
<dt><code>unlink</code> [<code>--dry-run</code>] <var>formula</var></dt><dd><p>Remove symlinks for <var>formula</var> from the Homebrew prefix. This can be useful
for temporarily disabling a formula:
-<code>brew unlink foo &amp;&amp; commands &amp;&amp; brew link foo</code>.</p>
+<code>brew unlink &lt;formula> &amp;&amp; &lt;commands> &amp;&amp; brew link &lt;formula></code></p>
<p>If <code>--dry-run</code> or <code>-n</code> is passed, Homebrew will list all files which would
be unlinked, but will not actually unlink or delete any files.</p></dd>
@@ -387,7 +386,7 @@ directory instead of the system directory.</p>
would be removed, but will not actually delete any files.</p></dd>
<dt><code>unpack</code> [<code>--git</code>|<code>--patch</code>] [<code>--destdir=</code><var>path</var>] <var>formulae</var></dt><dd><p>Unpack the source files for <var>formulae</var> into subdirectories of the current
working directory. If <code>--destdir=</code><var>path</var> is given, the subdirectories will
-be created in the directory named by <code>&lt;path></code> instead.</p>
+be created in the directory named by <var>path</var> instead.</p>
<p>If <code>--patch</code> is passed, patches for <var>formulae</var> will be applied to the
unpacked source.</p>
@@ -431,8 +430,8 @@ or recommended dependency. To include the <code>:build</code> type dependencies,
<code>--include-build</code>. Similarly, pass <code>--include-optional</code> to include <code>:optional</code>
dependencies. To skip <code>:recommended</code> type dependencies, pass <code>--skip-recommended</code>.</p>
-<p>By default, <code>uses</code> shows usages of <code>formula</code> by stable builds. To find
-cases where <code>formula</code> is used by development or HEAD build, pass
+<p>By default, <code>uses</code> shows usages of <var>formulae</var> by stable builds. To find
+cases where <var>formulae</var> is used by development or HEAD build, pass
<code>--devel</code> or <code>--HEAD</code>.</p></dd>
<dt class="flush"><code>--cache</code></dt><dd><p>Display Homebrew's download cache. See also <code>HOMEBREW_CACHE</code>.</p></dd>
<dt><code>--cache</code> <var>formula</var></dt><dd><p>Display the file or directory used to cache <var>formula</var>.</p></dd>
@@ -479,15 +478,12 @@ name of the file or formula being audited, to make the output easy to grep.</p>
<p><code>audit</code> exits with a non-zero status if any errors are found. This is useful,
for instance, for implementing pre-commit hooks.</p></dd>
-<dt><code>bottle</code> [<code>--verbose</code>] [<code>--no-rebuild</code>] [<code>--keep-old</code>] [<code>--skip-relocation</code>] [<code>--root-url=&lt;root_url></code>] [<code>--force-core-tap</code>]:</dt><dd><p></p></dd>
-<dt><code>bottle</code> <code>--merge</code> [<code>--no-commit</code>] [<code>--keep-old</code>] [<code>--write</code>]:</dt><dd><p></p>
-
-<p>Generate a bottle (binary package) from a formula installed with
+<dt><code>bottle</code> [<code>--verbose</code>] [<code>--no-rebuild</code>] [<code>--keep-old</code>] [<code>--skip-relocation</code>] [<code>--root-url=</code><var>URL</var>] [<code>--force-core-tap</code>]:</dt><dd><p></p></dd>
+<dt><code>bottle</code> <code>--merge</code> [<code>--no-commit</code>] [<code>--keep-old</code>] [<code>--write</code>]</dt><dd><p>Generate a bottle (binary package) from a formula installed with
<code>--build-bottle</code>.</p></dd>
-<dt><code>bump-formula-pr</code> [<code>--devel</code>] [<code>--dry-run</code>] [<code>--audit</code>|<code>--strict</code>] [<code>--message=</code><var>message</var>] <code>--url=</code><var>url</var> <code>--sha256=</code><var>sha-256</var> <var>formula</var>:</dt><dd><p></p></dd>
-<dt><code>bump-formula-pr</code> [<code>--devel</code>] [<code>--dry-run</code>] [<code>--audit</code>|<code>--strict</code>] [<code>--message=</code><var>message</var>] <code>--tag=</code><var>tag</var> <code>--revision=</code><var>revision</var> <var>formula</var></dt><dd><p>Creates a pull request to update the formula with a new url or a new tag.</p>
+<dt><code>bump-formula-pr</code> [<code>--devel</code>] [<code>--dry-run</code> [<code>--write</code>]] [<code>--audit</code>|<code>--strict</code>] [<code>--mirror=</code><var>URL</var>] [<code>--version=</code><var>version</var>] [<code>--message=</code><var>message</var>] (<code>--url=</code><var>URL</var> <code>--sha256=</code><var>sha-256</var>|<code>--tag=</code><var>tag</var> <code>--revision=</code><var>revision</var>) <var>formula</var></dt><dd><p>Creates a pull request to update the formula with a new URL or a new tag.</p>
-<p>If a <var>url</var> is specified, the <var>sha-256</var> checksum of the new download must
+<p>If a <var>URL</var> is specified, the <var>sha-256</var> checksum of the new download must
also be specified. A best effort to determine the <var>sha-256</var> and <var>formula</var>
name will be made if either or both values are not supplied by the user.</p>
@@ -506,25 +502,24 @@ making the expected file modifications but not taking any git actions.</p>
<p>If <code>--strict</code> is passed, run <code>brew audit --strict</code> before opening the PR.</p>
-<p>If <code>--mirror=</code><var>url</var> is passed, use the value as a mirror url.</p>
+<p>If <code>--mirror=</code><var>URL</var> is passed, use the value as a mirror URL.</p>
<p>If <code>--version=</code><var>version</var> is passed, use the value to override the value
-parsed from the url or tag. Note that <code>--version=0</code> can be used to delete
+parsed from the URL or tag. Note that <code>--version=0</code> can be used to delete
an existing <code>version</code> override from a formula if it has become redundant.</p>
<p>If <code>--message=</code><var>message</var> is passed, append <var>message</var> to the default PR
message.</p>
<p>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.</p></dd>
<dt><code>create</code> <var>URL</var> [<code>--autotools</code>|<code>--cmake</code>|<code>--meson</code>] [<code>--no-fetch</code>] [<code>--set-name</code> <var>name</var>] [<code>--set-version</code> <var>version</var>] [<code>--tap</code> <var>user</var><code>/</code><var>repo</var>]</dt><dd><p>Generate a formula for the downloadable file at <var>URL</var> and open it in the editor.
Homebrew will attempt to automatically derive the formula name
and version, but if it fails, you'll have to make your own template. The <code>wget</code>
-formula serves as a simple example. For the complete API have a look at</p>
-
-<p><a href="http://www.rubydoc.info/github/Homebrew/brew/master/Formula" data-bare-link="true">http://www.rubydoc.info/github/Homebrew/brew/master/Formula</a></p>
+formula serves as a simple example. For the complete API have a look at
+<a href="http://www.rubydoc.info/github/Homebrew/brew/master/Formula" data-bare-link="true">http://www.rubydoc.info/github/Homebrew/brew/master/Formula</a>.</p>
<p>If <code>--autotools</code> is passed, create a basic template for an Autotools-style build.
If <code>--cmake</code> is passed, create a basic template for a CMake-style build.
@@ -540,8 +535,8 @@ you to explicitly set the name and version of the package you are creating.</p>
the specified tap.</p></dd>
<dt class="flush"><code>edit</code></dt><dd><p>Open all of Homebrew for editing.</p></dd>
<dt><code>edit</code> <var>formula</var></dt><dd><p>Open <var>formula</var> in the editor.</p></dd>
-<dt><code>formula</code> <var>formula</var></dt><dd><p>Display the path where <var>formula</var> is</p></dd>
-<dt><code>linkage</code> [<code>--test</code>] [<code>--reverse</code>] <var>formula-name</var></dt><dd><p>Checks the library links of an installed formula.</p>
+<dt><code>formula</code> <var>formula</var></dt><dd><p>Display the path where <var>formula</var> is located.</p></dd>
+<dt><code>linkage</code> [<code>--test</code>] [<code>--reverse</code>] <var>formula</var></dt><dd><p>Checks the library links of an installed formula.</p>
<p>Only works on installed formulae. An error is raised if it is run on
uninstalled formulae.</p>
@@ -558,44 +553,47 @@ status code if changes are detected in the manpage outputs.
This can be used for CI to be notified when the manpages are out of date.
Additionally, the date used in new manpages will match those in the existing
manpages (to allow comparison without factoring in the date).</p></dd>
-</dl>
-
+<dt><code>pull</code> [<code>--bottle</code>] [<code>--bump</code>] [<code>--clean</code>] [<code>--ignore-whitespace</code>] [<code>--resolve</code>] [<code>--branch-okay</code>] [<code>--no-pbcopy</code>] [<code>--no-publish</code>] <var>patch-source</var> [<var>patch-source</var>]</dt><dd><p>Gets a patch from a GitHub commit or pull request and applies it to Homebrew.
+Optionally, installs the formulae changed by the patch.</p>
-<p> <code>pull</code> [<code>--bottle</code>] [<code>--bump</code>] [<code>--clean</code>] [<code>--ignore-whitespace</code>] [<code>--resolve</code>] [<code>--branch-okay</code>] [<code>--no-pbcopy</code>] [<code>--no-publish</code>] <var>patch-source</var> [<var>patch-source</var>]</p>
+<p>Each <var>patch-source</var> may be one of:</p>
-<pre><code>Gets a patch from a GitHub commit or pull request and applies it to Homebrew.
-Optionally, installs the formulae changed by the patch.
+<p> ~ The ID number of a PR (pull request) in the homebrew/core GitHub
+ repository</p>
-Each &lt;patch-source> may be one of:
- * 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
+<p> ~ 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
-</code></pre>
+ Homebrew/homebrew-core or any tap.</p>
-<p> If <code>--bottle</code> was passed, handle bottles, pulling the bottle-update
- commit and publishing files on Bintray.
- If <code>--bump</code> was passed, for one-formula PRs, automatically reword
- commit message to our preferred format.
- If <code>--clean</code> was passed, do not rewrite or otherwise modify the
- commits found in the pulled PR.
- If <code>--ignore-whitespace</code> was passed, silently ignore whitespace
- discrepancies when applying diffs.
- If <code>--resolve</code> was passed, when a patch fails to apply, leave in
- progress and allow user to
- resolve, instead of aborting.
- If <code>--branch-okay</code> was passed, do not warn if pulling to a branch
- besides master (useful for testing).
- If <code>--no-pbcopy</code> was passed, do not copy anything to the system
- If <code>--no-publish</code> was passed, do not publish bottles to Bintray.</p>
+<p> ~ The URL of a commit on GitHub</p>
-<dl>
-<dt><code>release-notes</code> [<var>previous_tag</var>] [<var>end_ref</var>]</dt><dd><p>Output the merged pull requests on Homebrew/brew between two Git refs.
-If no <code>previous_tag</code> is provided it defaults to the newest tag.
-If no <code>end_ref</code> is provided it defaults to <code>origin/master</code>.</p>
+<p> ~ A "http://bot.brew.sh/job/..." string specifying a testing job ID</p>
+
+<p>If <code>--bottle</code> is passed, handle bottles, pulling the bottle-update
+commit and publishing files on Bintray.</p>
+
+<p>If <code>--bump</code> is passed, for one-formula PRs, automatically reword
+commit message to our preferred format.</p>
+
+<p>If <code>--clean</code> is passed, do not rewrite or otherwise modify the
+commits found in the pulled PR.</p>
+
+<p>If <code>--ignore-whitespace</code> is passed, silently ignore whitespace
+discrepancies when applying diffs.</p>
+
+<p>If <code>--resolve</code> is passed, when a patch fails to apply, leave in
+progress and allow user to resolve, instead of aborting.</p>
+
+<p>If <code>--branch-okay</code> is passed, do not warn if pulling to a branch
+besides master (useful for testing).</p>
+
+<p>If <code>--no-pbcopy</code> is passed, do not copy anything to the system
+clipboard.</p>
+
+<p>If <code>--no-publish</code> is passed, do not publish bottles to Bintray.</p></dd>
+<dt><code>release-notes</code> [<code>--markdown</code>] [<var>previous_tag</var>] [<var>end_ref</var>]</dt><dd><p>Output the merged pull requests on Homebrew/brew between two Git refs.
+If no <var>previous_tag</var> is provided it defaults to the newest tag.
+If no <var>end_ref</var> is provided it defaults to <code>origin/master</code>.</p>
<p>If <code>--markdown</code> is passed, output as a Markdown list.</p></dd>
<dt><code>tap-new</code> <var>user</var><code>/</code><var>repo</var></dt><dd><p>Generate the template files for a new tap.</p></dd>
@@ -614,17 +612,17 @@ launched with access to IRB or a shell inside the temporary test directory.</p>
not deleted.</p>
<p>Example: <code>brew install jruby &amp;&amp; brew test jruby</code></p></dd>
-<dt><code>tests</code> [<code>-v</code>] [<code>--coverage</code>] [<code>--generic</code>] [<code>--no-compat</code>] [<code>--only=</code>&lt;test_script:test_method>] [<code>--seed</code> <var>seed</var>] [<code>--trace</code>] [<code>--online</code>] [<code>--official-cmd-taps</code>]</dt><dd><p>Run Homebrew's unit and integration tests.</p></dd>
-<dt><code>update-test</code> [<code>--commit=&lt;commit></code>] [<code>--before=&lt;date></code>] [<code>--keep-tmp</code>]</dt><dd><p>Runs a test of <code>brew update</code> with a new repository clone.</p>
+<dt><code>tests</code> [<code>-v</code>] [<code>--coverage</code>] [<code>--generic</code>] [<code>--no-compat</code>] [<code>--only=</code><var>test_script</var><code>:</code><var>test_method</var>] [<code>--seed</code> <var>seed</var>] [<code>--trace</code>] [<code>--online</code>] [<code>--official-cmd-taps</code>]</dt><dd><p>Run Homebrew's unit and integration tests.</p></dd>
+<dt><code>update-test</code> [<code>--commit=</code><var>commit</var>] [<code>--before=</code><var>date</var>] [<code>--keep-tmp</code>]</dt><dd><p>Runs a test of <code>brew update</code> with a new repository clone.</p>
<p>If no arguments are passed, use <code>origin/master</code> as the start commit.</p>
-<p>If <code>--commit=&lt;commit></code> is passed, use <code>&lt;commit></code> as the start commit.</p>
+<p>If <code>--commit=</code><var>commit</var> is passed, use <var>commit</var> as the start commit.</p>
-<p>If <code>--before=&lt;date></code> is passed, use the commit at <code>&lt;date></code> as the
+<p>If <code>--before=</code><var>date</var> is passed, use the commit at <var>date</var> as the
start commit.</p>
-<p>If <code>--to-tag</code> is passed, set HOMEBREW_UPDATE_TO_TAG to test updating
+<p>If <code>--to-tag</code> is passed, set <code>HOMEBREW_UPDATE_TO_TAG</code> to test updating
between tags.</p>
<p>If <code>--keep-tmp</code> is passed, retain the temporary directory containing
@@ -742,7 +740,7 @@ successful build.</p>
to insecure HTTP.</p>
<p>While ensuring your downloads are fully secure, this is likely
-to cause from-source Sourceforge, some GNU &amp; GNOME based
+to cause from-source SourceForge, some GNU &amp; GNOME based
formulae to fail to download.</p></dd>
<dt><code>HOMEBREW_NO_GITHUB_API</code></dt><dd><p>If set, Homebrew will not use the GitHub API for e.g searches or
fetching relevant issues on a failed install.</p></dd>
@@ -791,7 +789,7 @@ your shell profile, or you can use it before a brew command:</p>
<p>Homebrew's lead maintainer is Mike McQuaid.</p>
-<p>Homebrew's current maintainers are Misty De Meo, Andrew Janke, Tomasz Pajor, Josh Hagins, Baptiste Fontaine, Markus Reiter, ilovezfs, Tom Schoonjans, Uladzislau Shablinski, Tim Smith and Alex Dunn.</p>
+<p>Homebrew's current maintainers are Alyssa Ross, Andrew Janke, Baptiste Fontaine, Alex Dunn, FX Coudert, ilovezfs, Josh Hagins, JCount, Misty De Meo, Tomasz Pajor, Markus Reiter, Tim Smith, Tom Schoonjans, Uladzislau Shablinski and William Woodruff.</p>
<p>Former maintainers with significant contributions include Xu Cheng, Martin Afanasjew, Dominyk Tiller, Brett Koonce, Jack Nagel, Adam Vandenberg and Homebrew's creator: Max Howell.</p>
diff --git a/manpages/brew-cask.1 b/manpages/brew-cask.1
index a30c9eb56..d42feb6c0 100644
--- a/manpages/brew-cask.1
+++ b/manpages/brew-cask.1
@@ -34,68 +34,84 @@ The tokens returned by \fBsearch\fR are suitable as arguments for most other com
.
.SH "COMMANDS"
.
-.IP "\(bu" 4
-\fBaudit\fR [ \fItoken\fR \.\.\. ]: Check the given Casks for installability\. If no tokens are given on the command line, all Casks are audited\.
+.TP
+\fBaudit\fR [ \fItoken\fR \.\.\. ]
+Check the given Casks for installability\. If no tokens are given on the command line, all Casks are audited\.
.
-.IP "\(bu" 4
-\fBcat\fR \fItoken\fR [ \fItoken\fR \.\.\. ]: Dump the given Cask definition file to the standard output\.
+.TP
+\fBcat\fR \fItoken\fR [ \fItoken\fR \.\.\. ]
+Dump the given Cask definition file to the standard output\.
.
-.IP "\(bu" 4
-\fBcleanup\fR [\-\-outdated]: Clean up cached downloads and tracker symlinks\. With \fB\-\-outdated\fR, only clean up cached downloads older than 10 days old\.
+.TP
+\fBcleanup\fR [\-\-outdated]
+Clean up cached downloads and tracker symlinks\. With \fB\-\-outdated\fR, only clean up cached downloads older than 10 days old\.
.
-.IP "\(bu" 4
-\fBcreate\fR \fItoken\fR: Generate a Cask definition file for the Cask identified by \fItoken\fR and open a template for it in your favorite editor\.
+.TP
+\fBcreate\fR \fItoken\fR
+Generate a Cask definition file for the Cask identified by \fItoken\fR and open a template for it in your favorite editor\.
.
-.IP "\(bu" 4
-\fBdoctor\fR or \fBdr\fR: Check for configuration issues\. Can be useful to upload as a gist for developers along with a bug report\.
+.TP
+\fBdoctor\fR or \fBdr\fR
+Check for configuration issues\. Can be useful to upload as a gist for developers along with a bug report\.
.
-.IP "\(bu" 4
-\fBedit\fR \fItoken\fR: Open the given Cask definition file for editing\.
+.TP
+\fBedit\fR \fItoken\fR
+Open the given Cask definition file for editing\.
.
-.IP "\(bu" 4
-\fBfetch\fR [\-\-force] \fItoken\fR [ \fItoken\fR \.\.\. ]: Download remote application files for the given Cask to the local cache\. With \fB\-\-force\fR, force re\-download even if the files are already cached\.
+.TP
+\fBfetch\fR [\-\-force] \fItoken\fR [ \fItoken\fR \.\.\. ]
+Download remote application files for the given Cask to the local cache\. With \fB\-\-force\fR, force re\-download even if the files are already cached\.
.
-.IP "\(bu" 4
-\fBhome\fR or \fBhomepage\fR [ \fItoken\fR \.\.\. ]: Display the homepage associated with a given Cask in a browser\.
+.TP
+\fBhome\fR or \fBhomepage\fR [ \fItoken\fR \.\.\. ]
+Display the homepage associated with a given Cask in a browser\.
.
.IP
With no arguments, display the project page \fIhttp://caskroom\.io\fR\.
.
-.IP "\(bu" 4
-\fBinfo\fR or \fBabv\fR \fItoken\fR [ \fItoken\fR \.\.\. ]: Display information about the given Cask\.
+.TP
+\fBinfo\fR or \fBabv\fR \fItoken\fR [ \fItoken\fR \.\.\. ]
+Display information about the given Cask\.
.
-.IP "\(bu" 4
-\fBinstall\fR [\-\-force] [\-\-skip\-cask\-deps] [\-\-require\-sha] \fItoken\fR [ \fItoken\fR \.\.\. ]: Install the given Cask\. With \fB\-\-force\fR, re\-install even if the Cask appears to be already present\. With \fB\-\-skip\-cask\-deps\fR, skip any Cask dependencies\. \fB\-\-require\-sha\fR will abort installation if the Cask does not have a checksum defined\.
+.TP
+\fBinstall\fR [\-\-force] [\-\-skip\-cask\-deps] [\-\-require\-sha] \fItoken\fR [ \fItoken\fR \.\.\. ]
+Install the given Cask\. With \fB\-\-force\fR, re\-install even if the Cask appears to be already present\. With \fB\-\-skip\-cask\-deps\fR, skip any Cask dependencies\. \fB\-\-require\-sha\fR will abort installation if the Cask does not have a checksum defined\.
.
.IP
\fItoken\fR is usually the ID of a Cask as returned by \fBbrew cask search\fR, but see \fIOTHER WAYS TO SPECIFY A CASK\fR for variations\.
.
-.IP "\(bu" 4
-\fBlist\fR or \fBls\fR [\-1] [\-\-versions] [ \fItoken\fR \.\.\. ]: Without any arguments, list all installed Casks\. With \fB\-1\fR, always format the output in a single column\. With \fB\-\-versions\fR, show all installed versions\.
+.TP
+\fBlist\fR or \fBls\fR [\-1] [\-\-versions] [ \fItoken\fR \.\.\. ]
+Without any arguments, list all installed Casks\. With \fB\-1\fR, always format the output in a single column\. With \fB\-\-versions\fR, show all installed versions\.
.
.IP
If \fItoken\fR is given, summarize the staged files associated with the given Cask\.
.
-.IP "\(bu" 4
-\fBreinstall\fR \fItoken\fR [ \fItoken\fR \.\.\.] Reinstall the given Cask\.
+.TP
+\fBreinstall\fR \fItoken\fR [ \fItoken\fR \.\.\. ]
+Reinstall the given Cask\.
.
-.IP "\(bu" 4
-\fBsearch\fR or \fB\-S\fR [\fItext\fR | /\fIregexp\fR/]: Without argument, display all Casks available for install, otherwise perform a substring search of known Cask tokens for \fItext\fR or, if the text is delimited by slashes (/\fIregexp\fR/), it is interpreted as a Ruby regular expression\.
+.TP
+\fBsearch\fR or \fB\-S\fR [\fItext\fR | /\fIregexp\fR/]
+Without an argument, display all Casks available for install; otherwise perform a substring search of known Cask tokens for \fItext\fR or, if the text is delimited by slashes (/\fIregexp\fR/), it is interpreted as a Ruby regular expression\.
.
-.IP "\(bu" 4
-\fBstyle\fR [\-\-fix] [ \fItoken\fR \.\.\. ]: Check the given Casks for correct style using RuboCop Cask \fIhttps://github\.com/caskroom/rubocop\-cask\fR\. If no tokens are given on the command line, all Casks are checked\. With \fB\-\-fix\fR, auto\-correct any style errors if possible\.
+.TP
+\fBstyle\fR [\-\-fix] [ \fItoken\fR \.\.\. ]
+Check the given Casks for correct style using RuboCop Cask \fIhttps://github\.com/caskroom/rubocop\-cask\fR\. If no tokens are given on the command line, all Casks are checked\. With \fB\-\-fix\fR, auto\-correct any style errors if possible\.
.
-.IP "\(bu" 4
-\fBuninstall\fR or \fBrm\fR or \fBremove\fR [\-\-force] \fItoken\fR [ \fItoken\fR \.\.\. ]: Uninstall the given Cask\. With \fB\-\-force\fR, uninstall even if the Cask does not appear to be present\.
+.TP
+\fBuninstall\fR or \fBrm\fR or \fBremove\fR [\-\-force] \fItoken\fR [ \fItoken\fR \.\.\. ]
+Uninstall the given Cask\. With \fB\-\-force\fR, uninstall even if the Cask does not appear to be present\.
.
-.IP "\(bu" 4
-\fBzap\fR \fItoken\fR [ \fItoken\fR \.\.\. ]: Unconditionally remove \fIall\fR files associated with the given Cask\.
+.TP
+\fBzap\fR \fItoken\fR [ \fItoken\fR \.\.\. ]
+Unconditionally remove \fIall\fR files associated with the given Cask\.
.
.IP
Implicitly performs all actions associated with \fBuninstall\fR, even if the Cask does not appear to be currently installed\.
.
.IP
-Removes all staged versions of the Cask distribution found under \fB<Caskroom_path>/<token>\fR\.
+Removes all staged versions of the Cask distribution found under \fB<Caskroom_path>/\fR\fItoken\fR\.
.
.IP
If the Cask definition contains a \fBzap\fR stanza, performs additional \fBzap\fR actions as defined there, such as removing local preference files\. \fBzap\fR actions are variable, depending on the level of detail defined by the Cask author\.
@@ -103,23 +119,21 @@ If the Cask definition contains a \fBzap\fR stanza, performs additional \fBzap\f
.IP
\fB\fBzap\fR may remove files which are shared between applications\.\fR
.
-.IP "" 0
-.
.SH "INTERNAL COMMANDS"
.
.TP
\fB_appcast_checkpoint\fR [\-\-calculate] [ \fItoken\fR \.\.\. | \fIURL\fR \.\.\. ]
-Given a \fBtoken\fR, returns the current appcast checkpoint, or calculates the appcast checkpoint if the \fB\-\-calculate\fR flag is specified\.
+Given a \fItoken\fR, returns the current appcast checkpoint, or calculates the appcast checkpoint if the \fB\-\-calculate\fR flag is specified\.
.
-.br
-Given a \fBURL\fR, calculates the appcast checkpoint for it\.
+.IP
+Given a \fIURL\fR, calculates the appcast checkpoint for it\.
.
.TP
-\fB_stanza\fR \fIstanza_name\fR [ \-\-table | \-\-yaml | \-\-inspect | \-\-quiet ] [ \fIcask_token\fR \.\.\. ]
-Given a \fBstanza_name\fR and a \fBcask_token\fR, returns the current stanza for a given Cask\. If no \fBcask_token\fR is given, then data for all Casks is returned\.
+\fB_stanza\fR \fIstanza_name\fR [ \-\-table | \-\-yaml | \-\-inspect | \-\-quiet ] [ \fItoken\fR \.\.\. ]
+Given a \fIstanza_name\fR and a \fItoken\fR, returns the current stanza for a given Cask\. If no \fItoken\fR is given, then data for all Casks is returned\.
.
.SH "OPTIONS"
-To make these options persistent, see the ENVIRONMENT section, below\.
+To make these options persistent, see the \fIENVIRONMENT\fR section, below\.
.
.P
Some of these (such as \fB\-\-prefpanedir\fR) may be subject to removal in a future version\.
@@ -138,7 +152,7 @@ Abort Cask installation if the Cask does not have a checksum defined\.
.
.TP
\fB\-\-caskroom=<path>\fR
-Location of the Caskroom, where all binaries are stored\. The default value is: \fB$(brew \-\-prefix)/Caskroom\fR\.
+Set location of the Caskroom, where all binaries are stored\. The default value is \fB$(brew \-\-prefix)/Caskroom\fR\.
.
.TP
\fB\-\-verbose\fR
@@ -234,7 +248,7 @@ brew update
Most Homebrew\-Cask commands can accept a Cask token as an argument\. As described above, the argument can take the form of:
.
.IP "\(bu" 4
-A token as returned by \fBbrew cask search\fR, \fIeg\fR \fBgoogle\-chrome\fR
+A token as returned by \fBbrew cask search\fR, e\.g\. \fBgoogle\-chrome\fR
.
.IP "" 0
.
@@ -242,13 +256,13 @@ A token as returned by \fBbrew cask search\fR, \fIeg\fR \fBgoogle\-chrome\fR
Homebrew\-Cask also accepts three other forms in place of plain tokens:
.
.IP "\(bu" 4
-A fully\-qualified token which includes the Tap name, \fIeg\fR \fBcaskroom/fonts/font\-symbola\fR
+A fully\-qualified token which includes the Tap name, e\.g\. \fBcaskroom/fonts/font\-symbola\fR
.
.IP "\(bu" 4
-A fully\-qualified pathname to a Cask file, \fIeg\fR \fB/usr/local/Library/Taps/caskroom/homebrew\-cask/Casks/google\-chrome\.rb\fR
+A fully\-qualified pathname to a Cask file, e\.g\. \fB/usr/local/Library/Taps/caskroom/homebrew\-cask/Casks/google\-chrome\.rb\fR
.
.IP "\(bu" 4
-A \fBcurl\fR\-retrievable URI to a Cask file, \fIeg\fR \fBhttps://raw\.githubusercontent\.com/caskroom/homebrew\-cask/f25b6babcd398abf48e33af3d887b2d00de1d661/Casks/google\-chrome\.rb\fR
+A \fBcurl\fR\-retrievable URI to a Cask file, e\.g\. \fBhttps://raw\.githubusercontent\.com/caskroom/homebrew\-cask/f25b6babcd398abf48e33af3d887b2d00de1d661/Casks/google\-chrome\.rb\fR
.
.IP "" 0
.
@@ -259,14 +273,25 @@ Homebrew\-Cask respects many of the environment variables used by the parent com
Environment variables specific to Homebrew\-Cask:
.
.TP
-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: \fBexport HOMEBREW_CASK_OPTS=\'\-\-appdir=/Applications \-\-caskroom=/etc/Caskroom\'\fR\.
+\fBHOMEBREW_CASK_OPTS\fR
+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:
+.
+.IP "" 4
+.
+.nf
+
+ export HOMEBREW_CASK_OPTS=\'\-\-appdir=/Applications \-\-caskroom=/etc/Caskroom\'
+.
+.fi
+.
+.IP "" 0
+
.
.SH "SEE ALSO"
-The Homebrew\-Cask home page: \fIhttp://caskroom\.io\fR\.
+The Homebrew\-Cask home page: \fIhttp://caskroom\.io\fR
.
.P
-The Homebrew\-Cask GitHub page: \fIhttps://github\.com/caskroom/homebrew\-cask\fR\.
+The Homebrew\-Cask GitHub page: \fIhttps://github\.com/caskroom/homebrew\-cask\fR
.
.P
\fBbrew\fR(1), \fBcurl\fR(1)
@@ -278,7 +303,7 @@ Paul Hinze and Contributors\.
Man page format based on \fBbrew\.1\.md\fR from Homebrew\.
.
.SH "BUGS"
-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 \fIhttps://github\.com/caskroom/homebrew\-cask/issues?state=open\fR\.
+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 \fIhttps://github\.com/caskroom/homebrew\-cask/issues?state=open\fR\.
.
.P
When reporting bugs, remember that Homebrew\-Cask is an independent project from Homebrew\. Do your best to direct bug reports to the appropriate project\. If your command\-line started with \fBbrew cask\fR, bring the bug to us first!
diff --git a/manpages/brew.1 b/manpages/brew.1
index 7591cf4ea..0899007b5 100644
--- a/manpages/brew.1
+++ b/manpages/brew.1
@@ -38,7 +38,7 @@ Fetch the newest version of Homebrew from GitHub using \fBgit\fR(1)\.
List all installed formulae\.
.
.TP
-\fBsearch\fR \fItext\fR|\fB/\fR\fItext\fR\fB/\fR
+\fBsearch\fR (\fItext\fR|\fB/\fR\fItext\fR\fB/\fR)
Perform a substring search of formula names for \fItext\fR\. If \fItext\fR is surrounded with slashes, then it is interpreted as a regular expression\. The search for \fItext\fR is extended online to some popular taps\. If no search term is given, all locally available formulae are listed\.
.
.SH "COMMANDS"
@@ -70,7 +70,7 @@ If \fB\-\-prune=\fR\fIdays\fR is specified, remove all cache files older than \f
If \fB\-\-dry\-run\fR or \fB\-n\fR is passed, show what would be removed, but do not actually remove anything\.
.
.IP
-If \fB\-s\fR is passed, scrubs 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: \fBrm \-rf $(brew \-\-cache)\fR
+If \fB\-s\fR 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: \fBrm \-rf $(brew \-\-cache)\fR
.
.TP
\fBcommand\fR \fIcmd\fR
@@ -131,8 +131,8 @@ The \fIfilters\fR placeholder is any combination of options \fB\-\-include\-buil
Display \fIformula\fR\'s name and one\-line description\.
.
.TP
-\fBdesc\fR [\fB\-s\fR|\fB\-n\fR|\fB\-d\fR] \fIpattern\fR
-Search both name and description (\fB\-s\fR), just the names (\fB\-n\fR), or just the descriptions (\fB\-d\fR) for \fB<pattern>\fR\. \fB<pattern>\fR 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 the first search, making that search slower than subsequent ones\.
+\fBdesc\fR [\fB\-s\fR|\fB\-n\fR|\fB\-d\fR] (\fItext\fR|\fB/\fR\fItext\fR\fB/\fR)
+Search both name and description (\fB\-s\fR), just the names (\fB\-n\fR), or just the descriptions (\fB\-d\fR) for \fItext\fR\. If \fItext\fR 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\.
.
.TP
\fBdiy\fR [\fB\-\-name=\fR\fIname\fR] [\fB\-\-version=\fR\fIversion\fR]
@@ -203,7 +203,7 @@ Display information about \fIformula\fR\.
Open a browser to the GitHub History page for formula \fIformula\fR\.
.
.IP
-To view formula history locally: \fBbrew log \-p <formula>\fR\.
+To view formula history locally: \fBbrew log \-p <formula>\fR
.
.TP
\fBinfo\fR \fB\-\-json=\fR\fIversion\fR (\fB\-\-all\fR|\fB\-\-installed\fR|\fIformulae\fR)
@@ -213,7 +213,7 @@ Print a JSON representation of \fIformulae\fR\. Currently the only accepted valu
Pass \fB\-\-all\fR to get information on all formulae, or \fB\-\-installed\fR to get information on all installed formulae\.
.
.IP
-See the docs for examples of using the JSON: \fIhttp://docs\.brew\.sh/Querying\-Brew\.html\fR
+See the docs for examples of using the JSON output: \fIhttp://docs\.brew\.sh/Querying\-Brew\.html\fR
.
.TP
\fBinstall\fR [\fB\-\-debug\fR] [\fB\-\-env=\fR\fIstd\fR|\fIsuper\fR] [\fB\-\-ignore\-dependencies\fR] [\fB\-\-only\-dependencies\fR] [\fB\-\-cc=\fR\fIcompiler\fR] [\fB\-\-build\-from\-source\fR] [\fB\-\-devel\fR|\fB\-\-HEAD\fR] [\fB\-\-keep\-tmp\fR] \fIformula\fR
@@ -352,7 +352,7 @@ If \fB\-\-all\fR is passed, show options for all formulae\.
If \fB\-\-installed\fR is passed, show options for all installed formulae\.
.
.TP
-\fBoutdated\fR [\fB\-\-quiet\fR|\fB\-\-verbose\fR|\fB\-\-json=v1\fR] [\fB\-\-fetch\-HEAD\fR]
+\fBoutdated\fR [\fB\-\-quiet\fR|\fB\-\-verbose\fR|\fB\-\-json=\fR\fIversion\fR] [\fB\-\-fetch\-HEAD\fR]
Show formulae that have an updated version available\.
.
.IP
@@ -394,7 +394,7 @@ Uninstall and then install \fIformula\fR\.
Display all locally available formulae for brewing (including tapped ones)\. No online search is performed if called without arguments\.
.
.TP
-\fBsearch\fR [\fB\-\-desc\fR] \fItext\fR|\fB/\fR\fItext\fR\fB/\fR
+\fBsearch\fR [\fB\-\-desc\fR] (\fItext\fR|\fB/\fR\fItext\fR\fB/\fR)
Perform a substring search of formula names for \fItext\fR\. If \fItext\fR is surrounded with slashes, then it is interpreted as a regular expression\. The search for \fItext\fR is extended online to some popular taps\.
.
.IP
@@ -479,7 +479,7 @@ Print a JSON representation of \fItaps\fR\. Currently the only accepted value fo
Pass \fB\-\-installed\fR to get information on installed taps\.
.
.IP
-See the docs for examples of using the JSON: \fIhttp://docs\.brew\.sh/Querying\-Brew\.html\fR
+See the docs for examples of using the JSON output: \fIhttp://docs\.brew\.sh/Querying\-Brew\.html\fR
.
.TP
\fBtap\-pin\fR \fItap\fR
@@ -501,7 +501,7 @@ If \fB\-\-ignore\-dependencies\fR is passed, uninstalling won\'t fail, even if f
.
.TP
\fBunlink\fR [\fB\-\-dry\-run\fR] \fIformula\fR
-Remove symlinks for \fIformula\fR from the Homebrew prefix\. This can be useful for temporarily disabling a formula: \fBbrew unlink foo && commands && brew link foo\fR\.
+Remove symlinks for \fIformula\fR from the Homebrew prefix\. This can be useful for temporarily disabling a formula: \fBbrew unlink <formula> && <commands> && brew link <formula>\fR
.
.IP
If \fB\-\-dry\-run\fR or \fB\-n\fR is passed, Homebrew will list all files which would be unlinked, but will not actually unlink or delete any files\.
@@ -524,7 +524,7 @@ If \fB\-\-dry\-run\fR or \fB\-n\fR is passed, Homebrew will list all symlinks wh
.
.TP
\fBunpack\fR [\fB\-\-git\fR|\fB\-\-patch\fR] [\fB\-\-destdir=\fR\fIpath\fR] \fIformulae\fR
-Unpack the source files for \fIformulae\fR into subdirectories of the current working directory\. If \fB\-\-destdir=\fR\fIpath\fR is given, the subdirectories will be created in the directory named by \fB<path>\fR instead\.
+Unpack the source files for \fIformulae\fR into subdirectories of the current working directory\. If \fB\-\-destdir=\fR\fIpath\fR is given, the subdirectories will be created in the directory named by \fIpath\fR instead\.
.
.IP
If \fB\-\-patch\fR is passed, patches for \fIformulae\fR will be applied to the unpacked source\.
@@ -580,7 +580,7 @@ If \fB\-\-installed\fR is passed, only list installed formulae\.
By default, \fBuses\fR shows all formulae that specify \fIformulae\fR as a required or recommended dependency\. To include the \fB:build\fR type dependencies, pass \fB\-\-include\-build\fR\. Similarly, pass \fB\-\-include\-optional\fR to include \fB:optional\fR dependencies\. To skip \fB:recommended\fR type dependencies, pass \fB\-\-skip\-recommended\fR\.
.
.IP
-By default, \fBuses\fR shows usages of \fBformula\fR by stable builds\. To find cases where \fBformula\fR is used by development or HEAD build, pass \fB\-\-devel\fR or \fB\-\-HEAD\fR\.
+By default, \fBuses\fR shows usages of \fIformulae\fR by stable builds\. To find cases where \fIformulae\fR is used by development or HEAD build, pass \fB\-\-devel\fR or \fB\-\-HEAD\fR\.
.
.TP
\fB\-\-cache\fR
@@ -653,25 +653,19 @@ If \fB\-\-display\-filename\fR is passed, every line of output is prefixed with
\fBaudit\fR exits with a non\-zero status if any errors are found\. This is useful, for instance, for implementing pre\-commit hooks\.
.
.TP
-\fBbottle\fR [\fB\-\-verbose\fR] [\fB\-\-no\-rebuild\fR] [\fB\-\-keep\-old\fR] [\fB\-\-skip\-relocation\fR] [\fB\-\-root\-url=<root_url>\fR] [\fB\-\-force\-core\-tap\fR]:
+\fBbottle\fR [\fB\-\-verbose\fR] [\fB\-\-no\-rebuild\fR] [\fB\-\-keep\-old\fR] [\fB\-\-skip\-relocation\fR] [\fB\-\-root\-url=\fR\fIURL\fR] [\fB\-\-force\-core\-tap\fR]:
.
.TP
-\fBbottle\fR \fB\-\-merge\fR [\fB\-\-no\-commit\fR] [\fB\-\-keep\-old\fR] [\fB\-\-write\fR]:
-.
-.IP
+\fBbottle\fR \fB\-\-merge\fR [\fB\-\-no\-commit\fR] [\fB\-\-keep\-old\fR] [\fB\-\-write\fR]
Generate a bottle (binary package) from a formula installed with \fB\-\-build\-bottle\fR\.
.
.TP
-\fBbump\-formula\-pr\fR [\fB\-\-devel\fR] [\fB\-\-dry\-run\fR] [\fB\-\-audit\fR|\fB\-\-strict\fR] [\fB\-\-message=\fR\fImessage\fR] \fB\-\-url=\fR\fIurl\fR \fB\-\-sha256=\fR\fIsha\-256\fR \fIformula\fR:
-
-.
-.TP
-\fBbump\-formula\-pr\fR [\fB\-\-devel\fR] [\fB\-\-dry\-run\fR] [\fB\-\-audit\fR|\fB\-\-strict\fR] [\fB\-\-message=\fR\fImessage\fR] \fB\-\-tag=\fR\fItag\fR \fB\-\-revision=\fR\fIrevision\fR \fIformula\fR
-Creates a pull request to update the formula with a new url or a new tag\.
+\fBbump\-formula\-pr\fR [\fB\-\-devel\fR] [\fB\-\-dry\-run\fR [\fB\-\-write\fR]] [\fB\-\-audit\fR|\fB\-\-strict\fR] [\fB\-\-mirror=\fR\fIURL\fR] [\fB\-\-version=\fR\fIversion\fR] [\fB\-\-message=\fR\fImessage\fR] (\fB\-\-url=\fR\fIURL\fR \fB\-\-sha256=\fR\fIsha\-256\fR|\fB\-\-tag=\fR\fItag\fR \fB\-\-revision=\fR\fIrevision\fR) \fIformula\fR
+Creates a pull request to update the formula with a new URL or a new tag\.
.
.IP
-If a \fIurl\fR is specified, the \fIsha\-256\fR checksum of the new download must also be specified\. A best effort to determine the \fIsha\-256\fR and \fIformula\fR name will be made if either or both values are not supplied by the user\.
+If a \fIURL\fR is specified, the \fIsha\-256\fR checksum of the new download must also be specified\. A best effort to determine the \fIsha\-256\fR and \fIformula\fR name will be made if either or both values are not supplied by the user\.
.
.IP
If a \fItag\fR is specified, the git commit \fIrevision\fR corresponding to that tag must also be specified\.
@@ -692,23 +686,20 @@ If \fB\-\-audit\fR is passed, run \fBbrew audit\fR before opening the PR\.
If \fB\-\-strict\fR is passed, run \fBbrew audit \-\-strict\fR before opening the PR\.
.
.IP
-If \fB\-\-mirror=\fR\fIurl\fR is passed, use the value as a mirror url\.
+If \fB\-\-mirror=\fR\fIURL\fR is passed, use the value as a mirror URL\.
.
.IP
-If \fB\-\-version=\fR\fIversion\fR is passed, use the value to override the value parsed from the url or tag\. Note that \fB\-\-version=0\fR can be used to delete an existing \fBversion\fR override from a formula if it has become redundant\.
+If \fB\-\-version=\fR\fIversion\fR is passed, use the value to override the value parsed from the URL or tag\. Note that \fB\-\-version=0\fR can be used to delete an existing \fBversion\fR override from a formula if it has become redundant\.
.
.IP
If \fB\-\-message=\fR\fImessage\fR is passed, append \fImessage\fR to the default PR message\.
.
.IP
-Note that this command cannot be used to transition a formula from a 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\.
+Note that this command cannot be used to transition a formula from a 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\.
.
.TP
\fBcreate\fR \fIURL\fR [\fB\-\-autotools\fR|\fB\-\-cmake\fR|\fB\-\-meson\fR] [\fB\-\-no\-fetch\fR] [\fB\-\-set\-name\fR \fIname\fR] [\fB\-\-set\-version\fR \fIversion\fR] [\fB\-\-tap\fR \fIuser\fR\fB/\fR\fIrepo\fR]
-Generate a formula for the downloadable file at \fIURL\fR and open it in the editor\. Homebrew will attempt to automatically derive the formula name and version, but if it fails, you\'ll have to make your own template\. The \fBwget\fR formula serves as a simple example\. For the complete API have a look at
-.
-.IP
-\fIhttp://www\.rubydoc\.info/github/Homebrew/brew/master/Formula\fR
+Generate a formula for the downloadable file at \fIURL\fR and open it in the editor\. Homebrew will attempt to automatically derive the formula name and version, but if it fails, you\'ll have to make your own template\. The \fBwget\fR formula serves as a simple example\. For the complete API have a look at \fIhttp://www\.rubydoc\.info/github/Homebrew/brew/master/Formula\fR\.
.
.IP
If \fB\-\-autotools\fR is passed, create a basic template for an Autotools\-style build\. If \fB\-\-cmake\fR is passed, create a basic template for a CMake\-style build\. If \fB\-\-meson\fR is passed, create a basic template for a Meson\-style build\.
@@ -732,10 +723,10 @@ Open \fIformula\fR in the editor\.
.
.TP
\fBformula\fR \fIformula\fR
-Display the path where \fIformula\fR is
+Display the path where \fIformula\fR is located\.
.
.TP
-\fBlinkage\fR [\fB\-\-test\fR] [\fB\-\-reverse\fR] \fIformula\-name\fR
+\fBlinkage\fR [\fB\-\-test\fR] [\fB\-\-reverse\fR] \fIformula\fR
Checks the library links of an installed formula\.
.
.IP
@@ -754,35 +745,52 @@ Generate Homebrew\'s manpages\.
.IP
If \fB\-\-fail\-if\-changed\fR is passed, the command will return a failing status code if changes are detected in the manpage outputs\. This can be used for CI to be notified when the manpages are out of date\. Additionally, the date used in new manpages will match those in the existing manpages (to allow comparison without factoring in the date)\.
.
-.P
+.TP
\fBpull\fR [\fB\-\-bottle\fR] [\fB\-\-bump\fR] [\fB\-\-clean\fR] [\fB\-\-ignore\-whitespace\fR] [\fB\-\-resolve\fR] [\fB\-\-branch\-okay\fR] [\fB\-\-no\-pbcopy\fR] [\fB\-\-no\-publish\fR] \fIpatch\-source\fR [\fIpatch\-source\fR]
+Gets a patch from a GitHub commit or pull request and applies it to Homebrew\. Optionally, installs the formulae changed by the patch\.
.
-.IP "" 4
+.IP
+Each \fIpatch\-source\fR may be one of:
.
-.nf
-
-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
- repository
- * 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
+.IP
+~ The ID number of a PR (pull request) in the homebrew/core GitHub repository
.
-.fi
+.IP
+~ 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\.
.
-.IP "" 0
+.IP
+~ The URL of a commit on GitHub
.
-.P
-If \fB\-\-bottle\fR was passed, handle bottles, pulling the bottle\-update commit and publishing files on Bintray\. If \fB\-\-bump\fR was passed, for one\-formula PRs, automatically reword commit message to our preferred format\. If \fB\-\-clean\fR was passed, do not rewrite or otherwise modify the commits found in the pulled PR\. If \fB\-\-ignore\-whitespace\fR was passed, silently ignore whitespace discrepancies when applying diffs\. If \fB\-\-resolve\fR was passed, when a patch fails to apply, leave in progress and allow user to resolve, instead of aborting\. If \fB\-\-branch\-okay\fR was passed, do not warn if pulling to a branch besides master (useful for testing)\. If \fB\-\-no\-pbcopy\fR was passed, do not copy anything to the system If \fB\-\-no\-publish\fR was passed, do not publish bottles to Bintray\.
+.IP
+~ A "http://bot\.brew\.sh/job/\.\.\." string specifying a testing job ID
+.
+.IP
+If \fB\-\-bottle\fR is passed, handle bottles, pulling the bottle\-update commit and publishing files on Bintray\.
+.
+.IP
+If \fB\-\-bump\fR is passed, for one\-formula PRs, automatically reword commit message to our preferred format\.
+.
+.IP
+If \fB\-\-clean\fR is passed, do not rewrite or otherwise modify the commits found in the pulled PR\.
+.
+.IP
+If \fB\-\-ignore\-whitespace\fR is passed, silently ignore whitespace discrepancies when applying diffs\.
+.
+.IP
+If \fB\-\-resolve\fR is passed, when a patch fails to apply, leave in progress and allow user to resolve, instead of aborting\.
+.
+.IP
+If \fB\-\-branch\-okay\fR is passed, do not warn if pulling to a branch besides master (useful for testing)\.
+.
+.IP
+If \fB\-\-no\-pbcopy\fR is passed, do not copy anything to the system clipboard\.
+.
+.IP
+If \fB\-\-no\-publish\fR is passed, do not publish bottles to Bintray\.
.
.TP
-\fBrelease\-notes\fR [\fIprevious_tag\fR] [\fIend_ref\fR]
-Output the merged pull requests on Homebrew/brew between two Git refs\. If no \fBprevious_tag\fR is provided it defaults to the newest tag\. If no \fBend_ref\fR is provided it defaults to \fBorigin/master\fR\.
+\fBrelease\-notes\fR [\fB\-\-markdown\fR] [\fIprevious_tag\fR] [\fIend_ref\fR]
+Output the merged pull requests on Homebrew/brew between two Git refs\. If no \fIprevious_tag\fR is provided it defaults to the newest tag\. If no \fIend_ref\fR is provided it defaults to \fBorigin/master\fR\.
.
.IP
If \fB\-\-markdown\fR is passed, output as a Markdown list\.
@@ -808,24 +816,24 @@ If \fB\-\-keep\-tmp\fR is passed, the temporary files created for the test are n
Example: \fBbrew install jruby && brew test jruby\fR
.
.TP
-\fBtests\fR [\fB\-v\fR] [\fB\-\-coverage\fR] [\fB\-\-generic\fR] [\fB\-\-no\-compat\fR] [\fB\-\-only=\fR<test_script:test_method>] [\fB\-\-seed\fR \fIseed\fR] [\fB\-\-trace\fR] [\fB\-\-online\fR] [\fB\-\-official\-cmd\-taps\fR]
+\fBtests\fR [\fB\-v\fR] [\fB\-\-coverage\fR] [\fB\-\-generic\fR] [\fB\-\-no\-compat\fR] [\fB\-\-only=\fR\fItest_script\fR\fB:\fR\fItest_method\fR] [\fB\-\-seed\fR \fIseed\fR] [\fB\-\-trace\fR] [\fB\-\-online\fR] [\fB\-\-official\-cmd\-taps\fR]
Run Homebrew\'s unit and integration tests\.
.
.TP
-\fBupdate\-test\fR [\fB\-\-commit=<commit>\fR] [\fB\-\-before=<date>\fR] [\fB\-\-keep\-tmp\fR]
+\fBupdate\-test\fR [\fB\-\-commit=\fR\fIcommit\fR] [\fB\-\-before=\fR\fIdate\fR] [\fB\-\-keep\-tmp\fR]
Runs a test of \fBbrew update\fR with a new repository clone\.
.
.IP
If no arguments are passed, use \fBorigin/master\fR as the start commit\.
.
.IP
-If \fB\-\-commit=<commit>\fR is passed, use \fB<commit>\fR as the start commit\.
+If \fB\-\-commit=\fR\fIcommit\fR is passed, use \fIcommit\fR as the start commit\.
.
.IP
-If \fB\-\-before=<date>\fR is passed, use the commit at \fB<date>\fR as the start commit\.
+If \fB\-\-before=\fR\fIdate\fR is passed, use the commit at \fIdate\fR as the start commit\.
.
.IP
-If \fB\-\-to\-tag\fR is passed, set HOMEBREW_UPDATE_TO_TAG to test updating between tags\.
+If \fB\-\-to\-tag\fR is passed, set \fBHOMEBREW_UPDATE_TO_TAG\fR to test updating between tags\.
.
.IP
If \fB\-\-keep\-tmp\fR is passed, retain the temporary directory containing the new repository clone\.
@@ -985,7 +993,7 @@ If set, Homebrew will not print the \fBHOMEBREW_INSTALL_BADGE\fR on a successful
If set, Homebrew will not permit redirects from secure HTTPS to insecure HTTP\.
.
.IP
-While ensuring your downloads are fully secure, this is likely to cause from\-source Sourceforge, some GNU & GNOME based formulae to fail to download\.
+While ensuring your downloads are fully secure, this is likely to cause from\-source SourceForge, some GNU & GNOME based formulae to fail to download\.
.
.TP
\fBHOMEBREW_NO_GITHUB_API\fR
@@ -1056,7 +1064,7 @@ Homebrew Documentation: \fIhttps://github\.com/Homebrew/brew/blob/master/docs/\f
Homebrew\'s lead maintainer is Mike McQuaid\.
.
.P
-Homebrew\'s current maintainers are Misty De Meo, Andrew Janke, Tomasz Pajor, Josh Hagins, Baptiste Fontaine, Markus Reiter, ilovezfs, Tom Schoonjans, Uladzislau Shablinski, Tim Smith and Alex Dunn\.
+Homebrew\'s current maintainers are Alyssa Ross, Andrew Janke, Baptiste Fontaine, Alex Dunn, FX Coudert, ilovezfs, Josh Hagins, JCount, Misty De Meo, Tomasz Pajor, Markus Reiter, Tim Smith, Tom Schoonjans, Uladzislau Shablinski and William Woodruff\.
.
.P
Former maintainers with significant contributions include Xu Cheng, Martin Afanasjew, Dominyk Tiller, Brett Koonce, Jack Nagel, Adam Vandenberg and Homebrew\'s creator: Max Howell\.